1package.preload["fennel.repl"] = package.preload["fennel.repl"] or function(...)
2  local utils = require("fennel.utils")
3  local parser = require("fennel.parser")
4  local compiler = require("fennel.compiler")
5  local specials = require("fennel.specials")
6  local view = require("fennel.view")
7  local unpack = (table.unpack or _G.unpack)
8  local function default_read_chunk(parser_state)
9    local function _520_()
10      if (0 < parser_state["stack-size"]) then
11        return ".."
12      else
13        return ">> "
14      end
15    end
16    io.write(_520_())
17    io.flush()
18    local input = io.read()
19    return (input and (input .. "\n"))
20  end
21  local function default_on_values(xs)
22    io.write(table.concat(xs, "\9"))
23    return io.write("\n")
24  end
25  local function default_on_error(errtype, err, lua_source)
26    local function _522_()
27      local _521_ = errtype
28      if (_521_ == "Lua Compile") then
29        return ("Bad code generated - likely a bug with the compiler:\n" .. "--- Generated Lua Start ---\n" .. lua_source .. "--- Generated Lua End ---\n")
30      elseif (_521_ == "Runtime") then
31        return (compiler.traceback(tostring(err), 4) .. "\n")
32      elseif true then
33        local _ = _521_
34        return ("%s error: %s\n"):format(errtype, tostring(err))
35      else
36        return nil
37      end
38    end
39    return io.write(_522_())
40  end
41  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")
42  local function splice_save_locals(env, lua_source)
43    local spliced_source = {}
44    local bind = "local %s = ___replLocals___['%s']"
45    for line in lua_source:gmatch("([^\n]+)\n?") do
46      table.insert(spliced_source, line)
47    end
48    for name in pairs(env.___replLocals___) do
49      table.insert(spliced_source, 1, bind:format(name, name))
50    end
51    if ((1 < #spliced_source) and (spliced_source[#spliced_source]):match("^ *return .*$")) then
52      table.insert(spliced_source, #spliced_source, save_source)
53    else
54    end
55    return table.concat(spliced_source, "\n")
56  end
57  local function completer(env, scope, text)
58    local matches = {}
59    local input_fragment = text:gsub(".*[%s)(]+", "")
60    local stop_looking_3f = false
61    local function add_partials(input, tbl, prefix, method_3f)
62      for k in utils.allpairs(tbl) do
63        local k0
64        if ((tbl == env) or (tbl == env.___replLocals___)) then
65          k0 = scope.unmanglings[k]
66        else
67          k0 = k
68        end
69        if ((#matches < 2000) and (type(k0) == "string") and (input == k0:sub(0, #input)) and (not method_3f or ("function" == type(tbl[k0])))) then
70          local function _526_()
71            if method_3f then
72              return (prefix .. ":" .. k0)
73            else
74              return (prefix .. k0)
75            end
76          end
77          table.insert(matches, _526_())
78        else
79        end
80      end
81      return nil
82    end
83    local function descend(input, tbl, prefix, add_matches, method_3f)
84      local splitter
85      if method_3f then
86        splitter = "^([^:]+):(.*)"
87      else
88        splitter = "^([^.]+)%.(.*)"
89      end
90      local head, tail = input:match(splitter)
91      local raw_head = (scope.manglings[head] or head)
92      if (type(tbl[raw_head]) == "table") then
93        stop_looking_3f = true
94        if method_3f then
95          return add_partials(tail, tbl[raw_head], (prefix .. head), true)
96        else
97          return add_matches(tail, tbl[raw_head], (prefix .. head))
98        end
99      else
100        return nil
101      end
102    end
103    local function add_matches(input, tbl, prefix)
104      local prefix0
105      if prefix then
106        prefix0 = (prefix .. ".")
107      else
108        prefix0 = ""
109      end
110      if (not input:find("%.") and input:find(":")) then
111        return descend(input, tbl, prefix0, add_matches, true)
112      elseif not input:find("%.") then
113        return add_partials(input, tbl, prefix0)
114      else
115        return descend(input, tbl, prefix0, add_matches, false)
116      end
117    end
118    for _, source in ipairs({scope.specials, scope.macros, (env.___replLocals___ or {}), env, env._G}) do
119      if stop_looking_3f then break end
120      add_matches(input_fragment, source)
121    end
122    return matches
123  end
124  local commands = {}
125  local function command_3f(input)
126    return input:match("^%s*,")
127  end
128  local function command_docs()
129    local _533_
130    do
131      local tbl_14_auto = {}
132      local i_15_auto = #tbl_14_auto
133      for name, f in pairs(commands) do
134        local val_16_auto = ("  ,%s - %s"):format(name, ((compiler.metadata):get(f, "fnl/docstring") or "undocumented"))
135        if (nil ~= val_16_auto) then
136          i_15_auto = (i_15_auto + 1)
137          do end (tbl_14_auto)[i_15_auto] = val_16_auto
138        else
139        end
140      end
141      _533_ = tbl_14_auto
142    end
143    return table.concat(_533_, "\n")
144  end
145  commands.help = function(_, _0, on_values)
146    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")})
147  end
148  do end (compiler.metadata):set(commands.help, "fnl/docstring", "Show this message.")
149  local function reload(module_name, env, on_values, on_error)
150    local _535_, _536_ = pcall(specials["load-code"]("return require(...)", env), module_name)
151    if ((_535_ == true) and (nil ~= _536_)) then
152      local old = _536_
153      local _
154      package.loaded[module_name] = nil
155      _ = nil
156      local ok, new = pcall(require, module_name)
157      local new0
158      if not ok then
159        on_values({new})
160        new0 = old
161      else
162        new0 = new
163      end
164      if ((type(old) == "table") and (type(new0) == "table")) then
165        for k, v in pairs(new0) do
166          old[k] = v
167        end
168        for k in pairs(old) do
169          if (nil == (new0)[k]) then
170            old[k] = nil
171          else
172          end
173        end
174        package.loaded[module_name] = old
175      else
176      end
177      return on_values({"ok"})
178    elseif ((_535_ == false) and (nil ~= _536_)) then
179      local msg = _536_
180      local function _541_()
181        local _540_ = msg:gsub("\n.*", "")
182        return _540_
183      end
184      return on_error("Runtime", _541_())
185    else
186      return nil
187    end
188  end
189  local function run_command(read, on_error, f)
190    local _543_, _544_, _545_ = pcall(read)
191    if ((_543_ == true) and (_544_ == true) and (nil ~= _545_)) then
192      local val = _545_
193      return f(val)
194    elseif (_543_ == false) then
195      return on_error("Parse", "Couldn't parse input.")
196    else
197      return nil
198    end
199  end
200  commands.reload = function(env, read, on_values, on_error)
201    local function _547_(_241)
202      return reload(tostring(_241), env, on_values, on_error)
203    end
204    return run_command(read, on_error, _547_)
205  end
206  do end (compiler.metadata):set(commands.reload, "fnl/docstring", "Reload the specified module.")
207  commands.reset = function(env, _, on_values)
208    env.___replLocals___ = {}
209    return on_values({"ok"})
210  end
211  do end (compiler.metadata):set(commands.reset, "fnl/docstring", "Erase all repl-local scope.")
212  commands.complete = function(env, read, on_values, on_error, scope, chars)
213    local function _548_()
214      return on_values(completer(env, scope, string.char(unpack(chars)):gsub(",complete +", ""):sub(1, -2)))
215    end
216    return run_command(read, on_error, _548_)
217  end
218  do end (compiler.metadata):set(commands.complete, "fnl/docstring", "Print all possible completions for a given input symbol.")
219  local function apropos_2a(pattern, tbl, prefix, seen, names)
220    for name, subtbl in pairs(tbl) do
221      if (("string" == type(name)) and (package ~= subtbl)) then
222        local _549_ = type(subtbl)
223        if (_549_ == "function") then
224          if ((prefix .. name)):match(pattern) then
225            table.insert(names, (prefix .. name))
226          else
227          end
228        elseif (_549_ == "table") then
229          if not seen[subtbl] then
230            local _552_
231            do
232              local _551_ = seen
233              _551_[subtbl] = true
234              _552_ = _551_
235            end
236            apropos_2a(pattern, subtbl, (prefix .. name:gsub("%.", "/") .. "."), _552_, names)
237          else
238          end
239        else
240        end
241      else
242      end
243    end
244    return names
245  end
246  local function apropos(pattern)
247    local names = apropos_2a(pattern, package.loaded, "", {}, {})
248    local tbl_14_auto = {}
249    local i_15_auto = #tbl_14_auto
250    for _, name in ipairs(names) do
251      local val_16_auto = name:gsub("^_G%.", "")
252      if (nil ~= val_16_auto) then
253        i_15_auto = (i_15_auto + 1)
254        do end (tbl_14_auto)[i_15_auto] = val_16_auto
255      else
256      end
257    end
258    return tbl_14_auto
259  end
260  commands.apropos = function(_env, read, on_values, on_error, _scope)
261    local function _557_(_241)
262      return on_values(apropos(tostring(_241)))
263    end
264    return run_command(read, on_error, _557_)
265  end
266  do end (compiler.metadata):set(commands.apropos, "fnl/docstring", "Print all functions matching a pattern in all loaded modules.")
267  local function apropos_follow_path(path)
268    local paths
269    do
270      local tbl_14_auto = {}
271      local i_15_auto = #tbl_14_auto
272      for p in path:gmatch("[^%.]+") do
273        local val_16_auto = p
274        if (nil ~= val_16_auto) then
275          i_15_auto = (i_15_auto + 1)
276          do end (tbl_14_auto)[i_15_auto] = val_16_auto
277        else
278        end
279      end
280      paths = tbl_14_auto
281    end
282    local tgt = package.loaded
283    for _, path0 in ipairs(paths) do
284      if (nil == tgt) then break end
285      local _560_
286      do
287        local _559_ = path0:gsub("%/", ".")
288        _560_ = _559_
289      end
290      tgt = tgt[_560_]
291    end
292    return tgt
293  end
294  local function apropos_doc(pattern)
295    local names = {}
296    for _, path in ipairs(apropos(".*")) do
297      local tgt = apropos_follow_path(path)
298      if ("function" == type(tgt)) then
299        local _561_ = (compiler.metadata):get(tgt, "fnl/docstring")
300        if (nil ~= _561_) then
301          local docstr = _561_
302          if docstr:match(pattern) then
303            table.insert(names, path)
304          else
305          end
306        else
307        end
308      else
309      end
310    end
311    return names
312  end
313  commands["apropos-doc"] = function(_env, read, on_values, on_error, _scope)
314    local function _565_(_241)
315      return on_values(apropos_doc(tostring(_241)))
316    end
317    return run_command(read, on_error, _565_)
318  end
319  do end (compiler.metadata):set(commands["apropos-doc"], "fnl/docstring", "Print all functions that match the pattern in their docs")
320  local function apropos_show_docs(on_values, pattern)
321    for _, path in ipairs(apropos(pattern)) do
322      local tgt = apropos_follow_path(path)
323      if (("function" == type(tgt)) and (compiler.metadata):get(tgt, "fnl/docstring")) then
324        on_values(specials.doc(tgt, path))
325        on_values()
326      else
327      end
328    end
329    return nil
330  end
331  commands["apropos-show-docs"] = function(_env, read, on_values, on_error)
332    local function _567_(_241)
333      return apropos_show_docs(on_values, tostring(_241))
334    end
335    return run_command(read, on_error, _567_)
336  end
337  do end (compiler.metadata):set(commands["apropos-show-docs"], "fnl/docstring", "Print all documentations matching a pattern in function name")
338  local function resolve(identifier, _568_, scope)
339    local _arg_569_ = _568_
340    local ___replLocals___ = _arg_569_["___replLocals___"]
341    local env = _arg_569_
342    local e
343    local function _570_(_241, _242)
344      return (___replLocals___[_242] or env[_242])
345    end
346    e = setmetatable({}, {__index = _570_})
347    local code = compiler["compile-string"](tostring(identifier), {scope = scope})
348    return specials["load-code"](code, e)()
349  end
350  commands.find = function(env, read, on_values, on_error, scope)
351    local function _571_(_241)
352      local _572_
353      do
354        local _573_ = utils["sym?"](_241)
355        if (nil ~= _573_) then
356          local _574_ = resolve(_573_, env, scope)
357          if (nil ~= _574_) then
358            _572_ = debug.getinfo(_574_)
359          else
360            _572_ = _574_
361          end
362        else
363          _572_ = _573_
364        end
365      end
366      if ((_G.type(_572_) == "table") and (nil ~= (_572_).short_src) and (nil ~= (_572_).source) and (nil ~= (_572_).linedefined) and ((_572_).what == "Lua")) then
367        local src = (_572_).short_src
368        local source = (_572_).source
369        local line = (_572_).linedefined
370        local fnlsrc
371        do
372          local t_577_ = compiler.sourcemap
373          if (nil ~= t_577_) then
374            t_577_ = (t_577_)[source]
375          else
376          end
377          if (nil ~= t_577_) then
378            t_577_ = (t_577_)[line]
379          else
380          end
381          if (nil ~= t_577_) then
382            t_577_ = (t_577_)[2]
383          else
384          end
385          fnlsrc = t_577_
386        end
387        return on_values({string.format("%s:%s", src, (fnlsrc or line))})
388      elseif (_572_ == nil) then
389        return on_error("Repl", "Unknown value")
390      elseif true then
391        local _ = _572_
392        return on_error("Repl", "No source info")
393      else
394        return nil
395      end
396    end
397    return run_command(read, on_error, _571_)
398  end
399  do end (compiler.metadata):set(commands.find, "fnl/docstring", "Print the filename and line number for a given function")
400  commands.doc = function(env, read, on_values, on_error, scope)
401    local function _582_(_241)
402      local name = tostring(_241)
403      local target = (scope.specials[name] or scope.macros[name] or resolve(name, env, scope))
404      return on_values({specials.doc(target, name)})
405    end
406    return run_command(read, on_error, _582_)
407  end
408  do end (compiler.metadata):set(commands.doc, "fnl/docstring", "Print the docstring and arglist for a function, macro, or special form.")
409  local function load_plugin_commands(plugins)
410    for _, plugin in ipairs((plugins or {})) do
411      for name, f in pairs(plugin) do
412        local _583_ = name:match("^repl%-command%-(.*)")
413        if (nil ~= _583_) then
414          local cmd_name = _583_
415          commands[cmd_name] = (commands[cmd_name] or f)
416        else
417        end
418      end
419    end
420    return nil
421  end
422  local function run_command_loop(input, read, loop, env, on_values, on_error, scope, chars)
423    local command_name = input:match(",([^%s/]+)")
424    do
425      local _585_ = commands[command_name]
426      if (nil ~= _585_) then
427        local command = _585_
428        command(env, read, on_values, on_error, scope, chars)
429      elseif true then
430        local _ = _585_
431        if ("exit" ~= command_name) then
432          on_values({"Unknown command", command_name})
433        else
434        end
435      else
436      end
437    end
438    if ("exit" ~= command_name) then
439      return loop()
440    else
441      return nil
442    end
443  end
444  local function repl(options)
445    local old_root_options = utils.root.options
446    local env
447    if options.env then
448      env = specials["wrap-env"](options.env)
449    else
450      env = setmetatable({}, {__index = (rawget(_G, "_ENV") or _G)})
451    end
452    local save_locals_3f = ((options.saveLocals ~= false) and env.debug and env.debug.getlocal)
453    local opts = utils.copy(options)
454    local read_chunk = (opts.readChunk or default_read_chunk)
455    local on_values = (opts.onValues or default_on_values)
456    local on_error = (opts.onError or default_on_error)
457    local pp = (opts.pp or view)
458    local byte_stream, clear_stream = parser.granulate(read_chunk)
459    local chars = {}
460    local read, reset = nil, nil
461    local function _590_(parser_state)
462      local c = byte_stream(parser_state)
463      table.insert(chars, c)
464      return c
465    end
466    read, reset = parser.parser(_590_)
467    opts.env, opts.scope = env, compiler["make-scope"]()
468    opts.useMetadata = (options.useMetadata ~= false)
469    if (opts.allowedGlobals == nil) then
470      opts.allowedGlobals = specials["current-global-names"](opts.env)
471    else
472    end
473    if opts.registerCompleter then
474      local function _594_()
475        local _592_ = env
476        local _593_ = opts.scope
477        local function _595_(...)
478          return completer(_592_, _593_, ...)
479        end
480        return _595_
481      end
482      opts.registerCompleter(_594_())
483    else
484    end
485    load_plugin_commands(opts.plugins)
486    if save_locals_3f then
487      local function newindex(t, k, v)
488        if opts.scope.unmanglings[k] then
489          return rawset(t, k, v)
490        else
491          return nil
492        end
493      end
494      env.___replLocals___ = setmetatable({}, {__newindex = newindex})
495    else
496    end
497    local function print_values(...)
498      local vals = {...}
499      local out = {}
500      env._, env.__ = vals[1], vals
501      for i = 1, select("#", ...) do
502        table.insert(out, pp(vals[i]))
503      end
504      return on_values(out)
505    end
506    local function loop()
507      for k in pairs(chars) do
508        chars[k] = nil
509      end
510      reset()
511      local ok, parse_ok_3f, x = pcall(read)
512      local src_string = string.char(unpack(chars))
513      if not ok then
514        on_error("Parse", parse_ok_3f)
515        clear_stream()
516        return loop()
517      elseif command_3f(src_string) then
518        return run_command_loop(src_string, read, loop, env, on_values, on_error, opts.scope, chars)
519      else
520        if parse_ok_3f then
521          do
522            local _599_, _600_ = nil, nil
523            local function _602_()
524              local _601_ = opts
525              _601_["source"] = src_string
526              return _601_
527            end
528            _599_, _600_ = pcall(compiler.compile, x, _602_())
529            if ((_599_ == false) and (nil ~= _600_)) then
530              local msg = _600_
531              clear_stream()
532              on_error("Compile", msg)
533            elseif ((_599_ == true) and (nil ~= _600_)) then
534              local src = _600_
535              local src0
536              if save_locals_3f then
537                src0 = splice_save_locals(env, src, opts.scope)
538              else
539                src0 = src
540              end
541              local _604_, _605_ = pcall(specials["load-code"], src0, env)
542              if ((_604_ == false) and (nil ~= _605_)) then
543                local msg = _605_
544                clear_stream()
545                on_error("Lua Compile", msg, src0)
546              elseif (true and (nil ~= _605_)) then
547                local _ = _604_
548                local chunk = _605_
549                local function _606_()
550                  return print_values(chunk())
551                end
552                local function _607_()
553                  local function _608_(...)
554                    return on_error("Runtime", ...)
555                  end
556                  return _608_
557                end
558                xpcall(_606_, _607_())
559              else
560              end
561            else
562            end
563          end
564          utils.root.options = old_root_options
565          return loop()
566        else
567          return nil
568        end
569      end
570    end
571    return loop()
572  end
573  return repl
574end
575package.preload["fennel.specials"] = package.preload["fennel.specials"] or function(...)
576  local utils = require("fennel.utils")
577  local view = require("fennel.view")
578  local parser = require("fennel.parser")
579  local compiler = require("fennel.compiler")
580  local unpack = (table.unpack or _G.unpack)
581  local SPECIALS = compiler.scopes.global.specials
582  local function wrap_env(env)
583    local function _345_(_, key)
584      if (type(key) == "string") then
585        return env[compiler["global-unmangling"](key)]
586      else
587        return env[key]
588      end
589    end
590    local function _347_(_, key, value)
591      if (type(key) == "string") then
592        env[compiler["global-unmangling"](key)] = value
593        return nil
594      else
595        env[key] = value
596        return nil
597      end
598    end
599    local function _349_()
600      local function putenv(k, v)
601        local _350_
602        if (type(k) == "string") then
603          _350_ = compiler["global-unmangling"](k)
604        else
605          _350_ = k
606        end
607        return _350_, v
608      end
609      return next, utils.kvmap(env, putenv), nil
610    end
611    return setmetatable({}, {__index = _345_, __newindex = _347_, __pairs = _349_})
612  end
613  local function current_global_names(_3fenv)
614    local mt
615    do
616      local _352_ = getmetatable(_3fenv)
617      local function _353_()
618        local __pairs = (_352_).__pairs
619        return __pairs
620      end
621      if (((_G.type(_352_) == "table") and true) and _353_()) then
622        local __pairs = (_352_).__pairs
623        local tbl_11_auto = {}
624        for k, v in __pairs(_3fenv) do
625          local _354_, _355_ = k, v
626          if ((nil ~= _354_) and (nil ~= _355_)) then
627            local k_12_auto = _354_
628            local v_13_auto = _355_
629            tbl_11_auto[k_12_auto] = v_13_auto
630          else
631          end
632        end
633        mt = tbl_11_auto
634      elseif (_352_ == nil) then
635        mt = (_3fenv or _G)
636      else
637        mt = nil
638      end
639    end
640    return (mt and utils.kvmap(mt, compiler["global-unmangling"]))
641  end
642  local function load_code(code, _3fenv, _3ffilename)
643    local env = (_3fenv or rawget(_G, "_ENV") or _G)
644    if (rawget(_G, "setfenv") and rawget(_G, "loadstring")) then
645      local f = assert(_G.loadstring(code, _3ffilename))
646      local _358_ = f
647      setfenv(_358_, env)
648      return _358_
649    else
650      return assert(load(code, _3ffilename, "t", env))
651    end
652  end
653  local function doc_2a(tgt, name)
654    if not tgt then
655      return (name .. " not found")
656    else
657      local docstring = (((compiler.metadata):get(tgt, "fnl/docstring") or "#<undocumented>")):gsub("\n$", ""):gsub("\n", "\n  ")
658      local mt = getmetatable(tgt)
659      if ((type(tgt) == "function") or ((type(mt) == "table") and (type(mt.__call) == "function"))) then
660        local arglist = table.concat(((compiler.metadata):get(tgt, "fnl/arglist") or {"#<unknown-arguments>"}), " ")
661        local _360_
662        if (#arglist > 0) then
663          _360_ = " "
664        else
665          _360_ = ""
666        end
667        return string.format("(%s%s%s)\n  %s", name, _360_, arglist, docstring)
668      else
669        return string.format("%s\n  %s", name, docstring)
670      end
671    end
672  end
673  local function doc_special(name, arglist, docstring, body_form_3f)
674    compiler.metadata[SPECIALS[name]] = {["fnl/arglist"] = arglist, ["fnl/docstring"] = docstring, ["fnl/body-form?"] = body_form_3f}
675    return nil
676  end
677  local function compile_do(ast, scope, parent, _3fstart)
678    local start = (_3fstart or 2)
679    local len = #ast
680    local sub_scope = compiler["make-scope"](scope)
681    for i = start, len do
682      compiler.compile1(ast[i], sub_scope, parent, {nval = 0})
683    end
684    return nil
685  end
686  SPECIALS["do"] = function(ast, scope, parent, opts, _3fstart, _3fchunk, _3fsub_scope, _3fpre_syms)
687    local start = (_3fstart or 2)
688    local sub_scope = (_3fsub_scope or compiler["make-scope"](scope))
689    local chunk = (_3fchunk or {})
690    local len = #ast
691    local retexprs = {returned = true}
692    local function compile_body(outer_target, outer_tail, outer_retexprs)
693      if (len < start) then
694        compiler.compile1(nil, sub_scope, chunk, {tail = outer_tail, target = outer_target})
695      else
696        for i = start, len do
697          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)}
698          local _ = utils["propagate-options"](opts, subopts)
699          local subexprs = compiler.compile1(ast[i], sub_scope, chunk, subopts)
700          if (i ~= len) then
701            compiler["keep-side-effects"](subexprs, parent, nil, ast[i])
702          else
703          end
704        end
705      end
706      compiler.emit(parent, chunk, ast)
707      compiler.emit(parent, "end", ast)
708      utils.hook("do", ast, sub_scope)
709      return (outer_retexprs or retexprs)
710    end
711    if (opts.target or (opts.nval == 0) or opts.tail) then
712      compiler.emit(parent, "do", ast)
713      return compile_body(opts.target, opts.tail)
714    elseif opts.nval then
715      local syms = {}
716      for i = 1, opts.nval do
717        local s = ((_3fpre_syms and (_3fpre_syms)[i]) or compiler.gensym(scope))
718        do end (syms)[i] = s
719        retexprs[i] = utils.expr(s, "sym")
720      end
721      local outer_target = table.concat(syms, ", ")
722      compiler.emit(parent, string.format("local %s", outer_target), ast)
723      compiler.emit(parent, "do", ast)
724      return compile_body(outer_target, opts.tail)
725    else
726      local fname = compiler.gensym(scope)
727      local fargs
728      if scope.vararg then
729        fargs = "..."
730      else
731        fargs = ""
732      end
733      compiler.emit(parent, string.format("local function %s(%s)", fname, fargs), ast)
734      return compile_body(nil, true, utils.expr((fname .. "(" .. fargs .. ")"), "statement"))
735    end
736  end
737  doc_special("do", {"..."}, "Evaluate multiple forms; return last value.", true)
738  SPECIALS.values = function(ast, scope, parent)
739    local len = #ast
740    local exprs = {}
741    for i = 2, len do
742      local subexprs = compiler.compile1(ast[i], scope, parent, {nval = ((i ~= len) and 1)})
743      table.insert(exprs, subexprs[1])
744      if (i == len) then
745        for j = 2, #subexprs do
746          table.insert(exprs, subexprs[j])
747        end
748      else
749      end
750    end
751    return exprs
752  end
753  doc_special("values", {"..."}, "Return multiple values from a function. Must be in tail position.")
754  local function deep_tostring(x, key_3f)
755    if utils["sequence?"](x) then
756      local _369_
757      do
758        local tbl_14_auto = {}
759        local i_15_auto = #tbl_14_auto
760        for _, v in ipairs(x) do
761          local val_16_auto = deep_tostring(v)
762          if (nil ~= val_16_auto) then
763            i_15_auto = (i_15_auto + 1)
764            do end (tbl_14_auto)[i_15_auto] = val_16_auto
765          else
766          end
767        end
768        _369_ = tbl_14_auto
769      end
770      return ("[" .. table.concat(_369_, " ") .. "]")
771    elseif utils["table?"](x) then
772      local _371_
773      do
774        local tbl_14_auto = {}
775        local i_15_auto = #tbl_14_auto
776        for k, v in pairs(x) do
777          local val_16_auto = (deep_tostring(k, true) .. " " .. deep_tostring(v))
778          if (nil ~= val_16_auto) then
779            i_15_auto = (i_15_auto + 1)
780            do end (tbl_14_auto)[i_15_auto] = val_16_auto
781          else
782          end
783        end
784        _371_ = tbl_14_auto
785      end
786      return ("{" .. table.concat(_371_, " ") .. "}")
787    elseif (key_3f and (type(x) == "string") and x:find("^[-%w?\\^_!$%&*+./@:|<=>]+$")) then
788      return (":" .. x)
789    elseif (type(x) == "string") then
790      return string.format("%q", x):gsub("\\\"", "\\\\\""):gsub("\"", "\\\"")
791    else
792      return tostring(x)
793    end
794  end
795  local function set_fn_metadata(arg_list, docstring, parent, fn_name)
796    if utils.root.options.useMetadata then
797      local args
798      local function _374_(_241)
799        return ("\"%s\""):format(deep_tostring(_241))
800      end
801      args = utils.map(arg_list, _374_)
802      local meta_fields = {"\"fnl/arglist\"", ("{" .. table.concat(args, ", ") .. "}")}
803      if docstring then
804        table.insert(meta_fields, "\"fnl/docstring\"")
805        table.insert(meta_fields, ("\"" .. docstring:gsub("%s+$", ""):gsub("\\", "\\\\"):gsub("\n", "\\n"):gsub("\"", "\\\"") .. "\""))
806      else
807      end
808      local meta_str = ("require(\"%s\").metadata"):format((utils.root.options.moduleName or "fennel"))
809      return compiler.emit(parent, ("pcall(function() %s:setall(%s, %s) end)"):format(meta_str, fn_name, table.concat(meta_fields, ", ")))
810    else
811      return nil
812    end
813  end
814  local function get_fn_name(ast, scope, fn_name, multi)
815    if (fn_name and (fn_name[1] ~= "nil")) then
816      local _377_
817      if not multi then
818        _377_ = compiler["declare-local"](fn_name, {}, scope, ast)
819      else
820        _377_ = (compiler["symbol-to-expression"](fn_name, scope))[1]
821      end
822      return _377_, not multi, 3
823    else
824      return nil, true, 2
825    end
826  end
827  local function compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, local_3f, arg_name_list, arg_list, docstring)
828    for i = (index + 1), #ast do
829      compiler.compile1(ast[i], f_scope, f_chunk, {nval = (((i ~= #ast) and 0) or nil), tail = (i == #ast)})
830    end
831    local _380_
832    if local_3f then
833      _380_ = "local function %s(%s)"
834    else
835      _380_ = "%s = function(%s)"
836    end
837    compiler.emit(parent, string.format(_380_, fn_name, table.concat(arg_name_list, ", ")), ast)
838    compiler.emit(parent, f_chunk, ast)
839    compiler.emit(parent, "end", ast)
840    set_fn_metadata(arg_list, docstring, parent, fn_name)
841    utils.hook("fn", ast, f_scope)
842    return utils.expr(fn_name, "sym")
843  end
844  local function compile_anonymous_fn(ast, f_scope, f_chunk, parent, index, arg_name_list, arg_list, docstring, scope)
845    local fn_name = compiler.gensym(scope)
846    return compile_named_fn(ast, f_scope, f_chunk, parent, index, fn_name, true, arg_name_list, arg_list, docstring)
847  end
848  SPECIALS.fn = function(ast, scope, parent)
849    local f_scope
850    do
851      local _382_ = compiler["make-scope"](scope)
852      do end (_382_)["vararg"] = false
853      f_scope = _382_
854    end
855    local f_chunk = {}
856    local fn_sym = utils["sym?"](ast[2])
857    local multi = (fn_sym and utils["multi-sym?"](fn_sym[1]))
858    local fn_name, local_3f, index = get_fn_name(ast, scope, fn_sym, multi)
859    local arg_list = compiler.assert(utils["table?"](ast[index]), "expected parameters table", ast)
860    compiler.assert((not multi or not multi["multi-sym-method-call"]), ("unexpected multi symbol " .. tostring(fn_name)), fn_sym)
861    local function get_arg_name(arg)
862      if utils["varg?"](arg) then
863        compiler.assert((arg == arg_list[#arg_list]), "expected vararg as last parameter", ast)
864        f_scope.vararg = true
865        return "..."
866      elseif (utils["sym?"](arg) and (tostring(arg) ~= "nil") and not utils["multi-sym?"](tostring(arg))) then
867        return compiler["declare-local"](arg, {}, f_scope, ast)
868      elseif utils["table?"](arg) then
869        local raw = utils.sym(compiler.gensym(scope))
870        local declared = compiler["declare-local"](raw, {}, f_scope, ast)
871        compiler.destructure(arg, raw, ast, f_scope, f_chunk, {declaration = true, nomulti = true, symtype = "arg"})
872        return declared
873      else
874        return compiler.assert(false, ("expected symbol for function parameter: %s"):format(tostring(arg)), ast[index])
875      end
876    end
877    local arg_name_list = utils.map(arg_list, get_arg_name)
878    local index0, docstring = nil, nil
879    if ((type(ast[(index + 1)]) == "string") and ((index + 1) < #ast)) then
880      index0, docstring = (index + 1), ast[(index + 1)]
881    else
882      index0, docstring = index, nil
883    end
884    if fn_name then
885      return compile_named_fn(ast, f_scope, f_chunk, parent, index0, fn_name, local_3f, arg_name_list, arg_list, docstring)
886    else
887      return compile_anonymous_fn(ast, f_scope, f_chunk, parent, index0, arg_name_list, arg_list, docstring, scope)
888    end
889  end
890  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.", true)
891  SPECIALS.lua = function(ast, _, parent)
892    compiler.assert(((#ast == 2) or (#ast == 3)), "expected 1 or 2 arguments", ast)
893    local _387_
894    do
895      local _386_ = utils["sym?"](ast[2])
896      if (nil ~= _386_) then
897        _387_ = tostring(_386_)
898      else
899        _387_ = _386_
900      end
901    end
902    if ("nil" ~= _387_) then
903      table.insert(parent, {ast = ast, leaf = tostring(ast[2])})
904    else
905    end
906    local _391_
907    do
908      local _390_ = utils["sym?"](ast[3])
909      if (nil ~= _390_) then
910        _391_ = tostring(_390_)
911      else
912        _391_ = _390_
913      end
914    end
915    if ("nil" ~= _391_) then
916      return tostring(ast[3])
917    else
918      return nil
919    end
920  end
921  local function dot(ast, scope, parent)
922    compiler.assert((1 < #ast), "expected table argument", ast)
923    local len = #ast
924    local _let_394_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
925    local lhs = _let_394_[1]
926    if (len == 2) then
927      return tostring(lhs)
928    else
929      local indices = {}
930      for i = 3, len do
931        local index = ast[i]
932        if ((type(index) == "string") and utils["valid-lua-identifier?"](index)) then
933          table.insert(indices, ("." .. index))
934        else
935          local _let_395_ = compiler.compile1(index, scope, parent, {nval = 1})
936          local index0 = _let_395_[1]
937          table.insert(indices, ("[" .. tostring(index0) .. "]"))
938        end
939      end
940      if (tostring(lhs):find("[{\"0-9]") or ("nil" == tostring(lhs))) then
941        return ("(" .. tostring(lhs) .. ")" .. table.concat(indices))
942      else
943        return (tostring(lhs) .. table.concat(indices))
944      end
945    end
946  end
947  SPECIALS["."] = dot
948  doc_special(".", {"tbl", "key1", "..."}, "Look up key1 in tbl table. If more args are provided, do a nested lookup.")
949  SPECIALS.global = function(ast, scope, parent)
950    compiler.assert((#ast == 3), "expected name and value", ast)
951    compiler.destructure(ast[2], ast[3], ast, scope, parent, {forceglobal = true, nomulti = true, symtype = "global"})
952    return nil
953  end
954  doc_special("global", {"name", "val"}, "Set name as a global with val.")
955  SPECIALS.set = function(ast, scope, parent)
956    compiler.assert((#ast == 3), "expected name and value", ast)
957    compiler.destructure(ast[2], ast[3], ast, scope, parent, {noundef = true, symtype = "set"})
958    return nil
959  end
960  doc_special("set", {"name", "val"}, "Set a local variable to a new value. Only works on locals using var.")
961  local function set_forcibly_21_2a(ast, scope, parent)
962    compiler.assert((#ast == 3), "expected name and value", ast)
963    compiler.destructure(ast[2], ast[3], ast, scope, parent, {forceset = true, symtype = "set"})
964    return nil
965  end
966  SPECIALS["set-forcibly!"] = set_forcibly_21_2a
967  local function local_2a(ast, scope, parent)
968    compiler.assert((#ast == 3), "expected name and value", ast)
969    compiler.destructure(ast[2], ast[3], ast, scope, parent, {declaration = true, nomulti = true, symtype = "local"})
970    return nil
971  end
972  SPECIALS["local"] = local_2a
973  doc_special("local", {"name", "val"}, "Introduce new top-level immutable local.")
974  SPECIALS.var = function(ast, scope, parent)
975    compiler.assert((#ast == 3), "expected name and value", ast)
976    compiler.destructure(ast[2], ast[3], ast, scope, parent, {declaration = true, isvar = true, nomulti = true, symtype = "var"})
977    return nil
978  end
979  doc_special("var", {"name", "val"}, "Introduce new mutable local.")
980  local function kv_3f(t)
981    local _399_
982    do
983      local tbl_14_auto = {}
984      local i_15_auto = #tbl_14_auto
985      for k in pairs(t) do
986        local val_16_auto
987        if not ("number" == type(k)) then
988          val_16_auto = k
989        else
990          val_16_auto = nil
991        end
992        if (nil ~= val_16_auto) then
993          i_15_auto = (i_15_auto + 1)
994          do end (tbl_14_auto)[i_15_auto] = val_16_auto
995        else
996        end
997      end
998      _399_ = tbl_14_auto
999    end
1000    return (_399_)[1]
1001  end
1002  SPECIALS.let = function(ast, scope, parent, opts)
1003    local bindings = ast[2]
1004    local pre_syms = {}
1005    compiler.assert((utils["table?"](bindings) and not kv_3f(bindings)), "expected binding sequence", bindings)
1006    compiler.assert(((#bindings % 2) == 0), "expected even number of name/value bindings", ast[2])
1007    compiler.assert((#ast >= 3), "expected body expression", ast[1])
1008    for _ = 1, (opts.nval or 0) do
1009      table.insert(pre_syms, compiler.gensym(scope))
1010    end
1011    local sub_scope = compiler["make-scope"](scope)
1012    local sub_chunk = {}
1013    for i = 1, #bindings, 2 do
1014      compiler.destructure(bindings[i], bindings[(i + 1)], ast, sub_scope, sub_chunk, {declaration = true, nomulti = true, symtype = "let"})
1015    end
1016    return SPECIALS["do"](ast, scope, parent, opts, 3, sub_chunk, sub_scope, pre_syms)
1017  end
1018  doc_special("let", {"[name1 val1 ... nameN valN]", "..."}, "Introduces a new scope in which a given set of local bindings are used.", true)
1019  local function get_prev_line(parent)
1020    if ("table" == type(parent)) then
1021      return get_prev_line((parent.leaf or parent[#parent]))
1022    else
1023      return (parent or "")
1024    end
1025  end
1026  local function disambiguate_3f(rootstr, parent)
1027    local function _404_()
1028      local _403_ = get_prev_line(parent)
1029      if (nil ~= _403_) then
1030        local prev_line = _403_
1031        return prev_line:match("%)$")
1032      else
1033        return nil
1034      end
1035    end
1036    return (rootstr:match("^{") or _404_())
1037  end
1038  SPECIALS.tset = function(ast, scope, parent)
1039    compiler.assert((#ast > 3), "expected table, key, and value arguments", ast)
1040    local root = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
1041    local keys = {}
1042    for i = 3, (#ast - 1) do
1043      local _let_406_ = compiler.compile1(ast[i], scope, parent, {nval = 1})
1044      local key = _let_406_[1]
1045      table.insert(keys, tostring(key))
1046    end
1047    local value = (compiler.compile1(ast[#ast], scope, parent, {nval = 1}))[1]
1048    local rootstr = tostring(root)
1049    local fmtstr
1050    if disambiguate_3f(rootstr, parent) then
1051      fmtstr = "do end (%s)[%s] = %s"
1052    else
1053      fmtstr = "%s[%s] = %s"
1054    end
1055    return compiler.emit(parent, fmtstr:format(rootstr, table.concat(keys, "]["), tostring(value)), ast)
1056  end
1057  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.")
1058  local function calculate_target(scope, opts)
1059    if not (opts.tail or opts.target or opts.nval) then
1060      return "iife", true, nil
1061    elseif (opts.nval and (opts.nval ~= 0) and not opts.target) then
1062      local accum = {}
1063      local target_exprs = {}
1064      for i = 1, opts.nval do
1065        local s = compiler.gensym(scope)
1066        do end (accum)[i] = s
1067        target_exprs[i] = utils.expr(s, "sym")
1068      end
1069      return "target", opts.tail, table.concat(accum, ", "), target_exprs
1070    else
1071      return "none", opts.tail, opts.target
1072    end
1073  end
1074  local function if_2a(ast, scope, parent, opts)
1075    compiler.assert((2 < #ast), "expected condition and body", ast)
1076    local do_scope = compiler["make-scope"](scope)
1077    local branches = {}
1078    local wrapper, inner_tail, inner_target, target_exprs = calculate_target(scope, opts)
1079    local body_opts = {nval = opts.nval, tail = inner_tail, target = inner_target}
1080    local function compile_body(i)
1081      local chunk = {}
1082      local cscope = compiler["make-scope"](do_scope)
1083      compiler["keep-side-effects"](compiler.compile1(ast[i], cscope, chunk, body_opts), chunk, nil, ast[i])
1084      return {chunk = chunk, scope = cscope}
1085    end
1086    if (1 == (#ast % 2)) then
1087      table.insert(ast, utils.sym("nil"))
1088    else
1089    end
1090    for i = 2, (#ast - 1), 2 do
1091      local condchunk = {}
1092      local res = compiler.compile1(ast[i], do_scope, condchunk, {nval = 1})
1093      local cond = res[1]
1094      local branch = compile_body((i + 1))
1095      branch.cond = cond
1096      branch.condchunk = condchunk
1097      branch.nested = ((i ~= 2) and (next(condchunk, nil) == nil))
1098      table.insert(branches, branch)
1099    end
1100    local else_branch = compile_body(#ast)
1101    local s = compiler.gensym(scope)
1102    local buffer = {}
1103    local last_buffer = buffer
1104    for i = 1, #branches do
1105      local branch = branches[i]
1106      local fstr
1107      if not branch.nested then
1108        fstr = "if %s then"
1109      else
1110        fstr = "elseif %s then"
1111      end
1112      local cond = tostring(branch.cond)
1113      local cond_line = fstr:format(cond)
1114      if branch.nested then
1115        compiler.emit(last_buffer, branch.condchunk, ast)
1116      else
1117        for _, v in ipairs(branch.condchunk) do
1118          compiler.emit(last_buffer, v, ast)
1119        end
1120      end
1121      compiler.emit(last_buffer, cond_line, ast)
1122      compiler.emit(last_buffer, branch.chunk, ast)
1123      if (i == #branches) then
1124        compiler.emit(last_buffer, "else", ast)
1125        compiler.emit(last_buffer, else_branch.chunk, ast)
1126        compiler.emit(last_buffer, "end", ast)
1127      elseif not (branches[(i + 1)]).nested then
1128        local next_buffer = {}
1129        compiler.emit(last_buffer, "else", ast)
1130        compiler.emit(last_buffer, next_buffer, ast)
1131        compiler.emit(last_buffer, "end", ast)
1132        last_buffer = next_buffer
1133      else
1134      end
1135    end
1136    if (wrapper == "iife") then
1137      local iifeargs = ((scope.vararg and "...") or "")
1138      compiler.emit(parent, ("local function %s(%s)"):format(tostring(s), iifeargs), ast)
1139      compiler.emit(parent, buffer, ast)
1140      compiler.emit(parent, "end", ast)
1141      return utils.expr(("%s(%s)"):format(tostring(s), iifeargs), "statement")
1142    elseif (wrapper == "none") then
1143      for i = 1, #buffer do
1144        compiler.emit(parent, buffer[i], ast)
1145      end
1146      return {returned = true}
1147    else
1148      compiler.emit(parent, ("local %s"):format(inner_target), ast)
1149      for i = 1, #buffer do
1150        compiler.emit(parent, buffer[i], ast)
1151      end
1152      return target_exprs
1153    end
1154  end
1155  SPECIALS["if"] = if_2a
1156  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.")
1157  local function remove_until_condition(bindings)
1158    if ("until" == bindings[(#bindings - 1)]) then
1159      table.remove(bindings, (#bindings - 1))
1160      return table.remove(bindings)
1161    else
1162      return nil
1163    end
1164  end
1165  local function compile_until(condition, scope, chunk)
1166    if condition then
1167      local _let_415_ = compiler.compile1(condition, scope, chunk, {nval = 1})
1168      local condition_lua = _let_415_[1]
1169      return compiler.emit(chunk, ("if %s then break end"):format(tostring(condition_lua)), utils.expr(condition, "expression"))
1170    else
1171      return nil
1172    end
1173  end
1174  SPECIALS.each = function(ast, scope, parent)
1175    compiler.assert((#ast >= 3), "expected body expression", ast[1])
1176    local binding = compiler.assert(utils["table?"](ast[2]), "expected binding table", ast)
1177    local _ = compiler.assert((2 <= #binding), "expected binding and iterator", binding)
1178    local until_condition = remove_until_condition(binding)
1179    local iter = table.remove(binding, #binding)
1180    local destructures = {}
1181    local new_manglings = {}
1182    local sub_scope = compiler["make-scope"](scope)
1183    local function destructure_binding(v)
1184      compiler.assert(("string" ~= type(v)), ("unexpected iterator clause " .. tostring(v)), binding)
1185      if utils["sym?"](v) then
1186        return compiler["declare-local"](v, {}, sub_scope, ast, new_manglings)
1187      else
1188        local raw = utils.sym(compiler.gensym(sub_scope))
1189        do end (destructures)[raw] = v
1190        return compiler["declare-local"](raw, {}, sub_scope, ast)
1191      end
1192    end
1193    local bind_vars = utils.map(binding, destructure_binding)
1194    local vals = compiler.compile1(iter, scope, parent)
1195    local val_names = utils.map(vals, tostring)
1196    local chunk = {}
1197    compiler.emit(parent, ("for %s in %s do"):format(table.concat(bind_vars, ", "), table.concat(val_names, ", ")), ast)
1198    for raw, args in utils.stablepairs(destructures) do
1199      compiler.destructure(args, raw, ast, sub_scope, chunk, {declaration = true, nomulti = true, symtype = "each"})
1200    end
1201    compiler["apply-manglings"](sub_scope, new_manglings, ast)
1202    compile_until(until_condition, sub_scope, chunk)
1203    compile_do(ast, sub_scope, chunk, 3)
1204    compiler.emit(parent, chunk, ast)
1205    return compiler.emit(parent, "end", ast)
1206  end
1207  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)
1208  local function while_2a(ast, scope, parent)
1209    local len1 = #parent
1210    local condition = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
1211    local len2 = #parent
1212    local sub_chunk = {}
1213    if (len1 ~= len2) then
1214      for i = (len1 + 1), len2 do
1215        table.insert(sub_chunk, parent[i])
1216        do end (parent)[i] = nil
1217      end
1218      compiler.emit(parent, "while true do", ast)
1219      compiler.emit(sub_chunk, ("if not %s then break end"):format(condition[1]), ast)
1220    else
1221      compiler.emit(parent, ("while " .. tostring(condition) .. " do"), ast)
1222    end
1223    compile_do(ast, compiler["make-scope"](scope), sub_chunk, 3)
1224    compiler.emit(parent, sub_chunk, ast)
1225    return compiler.emit(parent, "end", ast)
1226  end
1227  SPECIALS["while"] = while_2a
1228  doc_special("while", {"condition", "..."}, "The classic while loop. Evaluates body until a condition is non-truthy.", true)
1229  local function for_2a(ast, scope, parent)
1230    local ranges = compiler.assert(utils["table?"](ast[2]), "expected binding table", ast)
1231    local until_condition = remove_until_condition(ast[2])
1232    local binding_sym = table.remove(ast[2], 1)
1233    local sub_scope = compiler["make-scope"](scope)
1234    local range_args = {}
1235    local chunk = {}
1236    compiler.assert(utils["sym?"](binding_sym), ("unable to bind %s %s"):format(type(binding_sym), tostring(binding_sym)), ast[2])
1237    compiler.assert((#ast >= 3), "expected body expression", ast[1])
1238    compiler.assert((#ranges <= 3), "unexpected arguments", ranges[4])
1239    for i = 1, math.min(#ranges, 3) do
1240      range_args[i] = tostring((compiler.compile1(ranges[i], scope, parent, {nval = 1}))[1])
1241    end
1242    compiler.emit(parent, ("for %s = %s do"):format(compiler["declare-local"](binding_sym, {}, sub_scope, ast), table.concat(range_args, ", ")), ast)
1243    compile_until(until_condition, sub_scope, chunk)
1244    compile_do(ast, sub_scope, chunk, 3)
1245    compiler.emit(parent, chunk, ast)
1246    return compiler.emit(parent, "end", ast)
1247  end
1248  SPECIALS["for"] = for_2a
1249  doc_special("for", {"[index start stop step?]", "..."}, "Numeric loop construct.\nEvaluates body once for each value between start and stop (inclusive).", true)
1250  local function native_method_call(ast, _scope, _parent, target, args)
1251    local _let_419_ = ast
1252    local _ = _let_419_[1]
1253    local _0 = _let_419_[2]
1254    local method_string = _let_419_[3]
1255    local call_string
1256    if ((target.type == "literal") or (target.type == "varg") or (target.type == "expression")) then
1257      call_string = "(%s):%s(%s)"
1258    else
1259      call_string = "%s:%s(%s)"
1260    end
1261    return utils.expr(string.format(call_string, tostring(target), method_string, table.concat(args, ", ")), "statement")
1262  end
1263  local function nonnative_method_call(ast, scope, parent, target, args)
1264    local method_string = tostring((compiler.compile1(ast[3], scope, parent, {nval = 1}))[1])
1265    local args0 = {tostring(target), unpack(args)}
1266    return utils.expr(string.format("%s[%s](%s)", tostring(target), method_string, table.concat(args0, ", ")), "statement")
1267  end
1268  local function double_eval_protected_method_call(ast, scope, parent, target, args)
1269    local method_string = tostring((compiler.compile1(ast[3], scope, parent, {nval = 1}))[1])
1270    local call = "(function(tgt, m, ...) return tgt[m](tgt, ...) end)(%s, %s)"
1271    table.insert(args, 1, method_string)
1272    return utils.expr(string.format(call, tostring(target), table.concat(args, ", ")), "statement")
1273  end
1274  local function method_call(ast, scope, parent)
1275    compiler.assert((2 < #ast), "expected at least 2 arguments", ast)
1276    local _let_421_ = compiler.compile1(ast[2], scope, parent, {nval = 1})
1277    local target = _let_421_[1]
1278    local args = {}
1279    for i = 4, #ast do
1280      local subexprs
1281      local _422_
1282      if (i ~= #ast) then
1283        _422_ = 1
1284      else
1285        _422_ = nil
1286      end
1287      subexprs = compiler.compile1(ast[i], scope, parent, {nval = _422_})
1288      utils.map(subexprs, tostring, args)
1289    end
1290    if ((type(ast[3]) == "string") and utils["valid-lua-identifier?"](ast[3])) then
1291      return native_method_call(ast, scope, parent, target, args)
1292    elseif (target.type == "sym") then
1293      return nonnative_method_call(ast, scope, parent, target, args)
1294    else
1295      return double_eval_protected_method_call(ast, scope, parent, target, args)
1296    end
1297  end
1298  SPECIALS[":"] = method_call
1299  doc_special(":", {"tbl", "method-name", "..."}, "Call the named method on tbl with the provided args.\nMethod name doesn't have to be known at compile-time; if it is, use\n(tbl:method-name ...) instead.")
1300  SPECIALS.comment = function(ast, _, parent)
1301    local els = {}
1302    for i = 2, #ast do
1303      table.insert(els, view(ast[i], {["one-line?"] = true}))
1304    end
1305    return compiler.emit(parent, ("--[[ " .. table.concat(els, " ") .. " ]]--"), ast)
1306  end
1307  doc_special("comment", {"..."}, "Comment which will be emitted in Lua output.", true)
1308  local function hashfn_max_used(f_scope, i, max)
1309    local max0
1310    if f_scope.symmeta[("$" .. i)].used then
1311      max0 = i
1312    else
1313      max0 = max
1314    end
1315    if (i < 9) then
1316      return hashfn_max_used(f_scope, (i + 1), max0)
1317    else
1318      return max0
1319    end
1320  end
1321  SPECIALS.hashfn = function(ast, scope, parent)
1322    compiler.assert((#ast == 2), "expected one argument", ast)
1323    local f_scope
1324    do
1325      local _427_ = compiler["make-scope"](scope)
1326      do end (_427_)["vararg"] = false
1327      _427_["hashfn"] = true
1328      f_scope = _427_
1329    end
1330    local f_chunk = {}
1331    local name = compiler.gensym(scope)
1332    local symbol = utils.sym(name)
1333    local args = {}
1334    compiler["declare-local"](symbol, {}, scope, ast)
1335    for i = 1, 9 do
1336      args[i] = compiler["declare-local"](utils.sym(("$" .. i)), {}, f_scope, ast)
1337    end
1338    local function walker(idx, node, parent_node)
1339      if (utils["sym?"](node) and (tostring(node) == "$...")) then
1340        parent_node[idx] = utils.varg()
1341        f_scope.vararg = true
1342        return nil
1343      else
1344        return (utils["list?"](node) or utils["table?"](node))
1345      end
1346    end
1347    utils["walk-tree"](ast[2], walker)
1348    compiler.compile1(ast[2], f_scope, f_chunk, {tail = true})
1349    local max_used = hashfn_max_used(f_scope, 1, 0)
1350    if f_scope.vararg then
1351      compiler.assert((max_used == 0), "$ and $... in hashfn are mutually exclusive", ast)
1352    else
1353    end
1354    local arg_str
1355    if f_scope.vararg then
1356      arg_str = tostring(utils.varg())
1357    else
1358      arg_str = table.concat(args, ", ", 1, max_used)
1359    end
1360    compiler.emit(parent, string.format("local function %s(%s)", name, arg_str), ast)
1361    compiler.emit(parent, f_chunk, ast)
1362    compiler.emit(parent, "end", ast)
1363    return utils.expr(name, "sym")
1364  end
1365  doc_special("hashfn", {"..."}, "Function literal shorthand; args are either $... OR $1, $2, etc.")
1366  local function arithmetic_special(name, zero_arity, unary_prefix, ast, scope, parent)
1367    local len = #ast
1368    local operands = {}
1369    local padded_op = (" " .. name .. " ")
1370    for i = 2, len do
1371      local subexprs = compiler.compile1(ast[i], scope, parent)
1372      if (i == len) then
1373        utils.map(subexprs, tostring, operands)
1374      else
1375        table.insert(operands, tostring(subexprs[1]))
1376      end
1377    end
1378    local _432_ = #operands
1379    if (_432_ == 0) then
1380      local _434_
1381      do
1382        local _433_ = zero_arity
1383        compiler.assert(_433_, "Expected more than 0 arguments", ast)
1384        _434_ = _433_
1385      end
1386      return utils.expr(_434_, "literal")
1387    elseif (_432_ == 1) then
1388      if unary_prefix then
1389        return ("(" .. unary_prefix .. padded_op .. operands[1] .. ")")
1390      else
1391        return operands[1]
1392      end
1393    elseif true then
1394      local _ = _432_
1395      return ("(" .. table.concat(operands, padded_op) .. ")")
1396    else
1397      return nil
1398    end
1399  end
1400  local function define_arithmetic_special(name, zero_arity, unary_prefix, _3flua_name)
1401    local _440_
1402    do
1403      local _437_ = (_3flua_name or name)
1404      local _438_ = zero_arity
1405      local _439_ = unary_prefix
1406      local function _441_(...)
1407        return arithmetic_special(_437_, _438_, _439_, ...)
1408      end
1409      _440_ = _441_
1410    end
1411    SPECIALS[name] = _440_
1412    return doc_special(name, {"a", "b", "..."}, "Arithmetic operator; works the same as Lua but accepts more arguments.")
1413  end
1414  define_arithmetic_special("+", "0")
1415  define_arithmetic_special("..", "''")
1416  define_arithmetic_special("^")
1417  define_arithmetic_special("-", nil, "")
1418  define_arithmetic_special("*", "1")
1419  define_arithmetic_special("%")
1420  define_arithmetic_special("/", nil, "1")
1421  define_arithmetic_special("//", nil, "1")
1422  SPECIALS["or"] = function(ast, scope, parent)
1423    return arithmetic_special("or", "false", nil, ast, scope, parent)
1424  end
1425  SPECIALS["and"] = function(ast, scope, parent)
1426    return arithmetic_special("and", "true", nil, ast, scope, parent)
1427  end
1428  doc_special("and", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.")
1429  doc_special("or", {"a", "b", "..."}, "Boolean operator; works the same as Lua but accepts more arguments.")
1430  local function bitop_special(native_name, lib_name, zero_arity, unary_prefix, ast, scope, parent)
1431    if (#ast == 1) then
1432      return compiler.assert(zero_arity, "Expected more than 0 arguments.", ast)
1433    else
1434      local len = #ast
1435      local operands = {}
1436      local padded_native_name = (" " .. native_name .. " ")
1437      local prefixed_lib_name = ("bit." .. lib_name)
1438      for i = 2, len do
1439        local subexprs
1440        local _442_
1441        if (i ~= len) then
1442          _442_ = 1
1443        else
1444          _442_ = nil
1445        end
1446        subexprs = compiler.compile1(ast[i], scope, parent, {nval = _442_})
1447        utils.map(subexprs, tostring, operands)
1448      end
1449      if (#operands == 1) then
1450        if utils.root.options.useBitLib then
1451          return (prefixed_lib_name .. "(" .. unary_prefix .. ", " .. operands[1] .. ")")
1452        else
1453          return ("(" .. unary_prefix .. padded_native_name .. operands[1] .. ")")
1454        end
1455      else
1456        if utils.root.options.useBitLib then
1457          return (prefixed_lib_name .. "(" .. table.concat(operands, ", ") .. ")")
1458        else
1459          return ("(" .. table.concat(operands, padded_native_name) .. ")")
1460        end
1461      end
1462    end
1463  end
1464  local function define_bitop_special(name, zero_arity, unary_prefix, native)
1465    local _452_
1466    do
1467      local _448_ = native
1468      local _449_ = name
1469      local _450_ = zero_arity
1470      local _451_ = unary_prefix
1471      local function _453_(...)
1472        return bitop_special(_448_, _449_, _450_, _451_, ...)
1473      end
1474      _452_ = _453_
1475    end
1476    SPECIALS[name] = _452_
1477    return nil
1478  end
1479  define_bitop_special("lshift", nil, "1", "<<")
1480  define_bitop_special("rshift", nil, "1", ">>")
1481  define_bitop_special("band", "0", "0", "&")
1482  define_bitop_special("bor", "0", "0", "|")
1483  define_bitop_special("bxor", "0", "0", "~")
1484  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.")
1485  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.")
1486  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.")
1487  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.")
1488  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.")
1489  doc_special("..", {"a", "b", "..."}, "String concatenation operator; works the same as Lua but accepts more arguments.")
1490  local function native_comparator(op, _454_, scope, parent)
1491    local _arg_455_ = _454_
1492    local _ = _arg_455_[1]
1493    local lhs_ast = _arg_455_[2]
1494    local rhs_ast = _arg_455_[3]
1495    local _let_456_ = compiler.compile1(lhs_ast, scope, parent, {nval = 1})
1496    local lhs = _let_456_[1]
1497    local _let_457_ = compiler.compile1(rhs_ast, scope, parent, {nval = 1})
1498    local rhs = _let_457_[1]
1499    return string.format("(%s %s %s)", tostring(lhs), op, tostring(rhs))
1500  end
1501  local function double_eval_protected_comparator(op, chain_op, ast, scope, parent)
1502    local arglist = {}
1503    local comparisons = {}
1504    local vals = {}
1505    local chain = string.format(" %s ", (chain_op or "and"))
1506    for i = 2, #ast do
1507      table.insert(arglist, tostring(compiler.gensym(scope)))
1508      table.insert(vals, tostring((compiler.compile1(ast[i], scope, parent, {nval = 1}))[1]))
1509    end
1510    for i = 1, (#arglist - 1) do
1511      table.insert(comparisons, string.format("(%s %s %s)", arglist[i], op, arglist[(i + 1)]))
1512    end
1513    return string.format("(function(%s) return %s end)(%s)", table.concat(arglist, ","), table.concat(comparisons, chain), table.concat(vals, ","))
1514  end
1515  local function define_comparator_special(name, _3flua_op, _3fchain_op)
1516    do
1517      local op = (_3flua_op or name)
1518      local function opfn(ast, scope, parent)
1519        compiler.assert((2 < #ast), "expected at least two arguments", ast)
1520        if (3 == #ast) then
1521          return native_comparator(op, ast, scope, parent)
1522        else
1523          return double_eval_protected_comparator(op, _3fchain_op, ast, scope, parent)
1524        end
1525      end
1526      SPECIALS[name] = opfn
1527    end
1528    return doc_special(name, {"a", "b", "..."}, "Comparison operator; works the same as Lua but accepts more arguments.")
1529  end
1530  define_comparator_special(">")
1531  define_comparator_special("<")
1532  define_comparator_special(">=")
1533  define_comparator_special("<=")
1534  define_comparator_special("=", "==")
1535  define_comparator_special("not=", "~=", "or")
1536  local function define_unary_special(op, _3frealop)
1537    local function opfn(ast, scope, parent)
1538      compiler.assert((#ast == 2), "expected one argument", ast)
1539      local tail = compiler.compile1(ast[2], scope, parent, {nval = 1})
1540      return ((_3frealop or op) .. tostring(tail[1]))
1541    end
1542    SPECIALS[op] = opfn
1543    return nil
1544  end
1545  define_unary_special("not", "not ")
1546  doc_special("not", {"x"}, "Logical operator; works the same as Lua.")
1547  define_unary_special("bnot", "~")
1548  doc_special("bnot", {"x"}, "Bitwise negation; only works in Lua 5.3+ or LuaJIT with the --use-bit-lib flag.")
1549  define_unary_special("length", "#")
1550  doc_special("length", {"x"}, "Returns the length of a table or string.")
1551  do end (SPECIALS)["~="] = SPECIALS["not="]
1552  SPECIALS["#"] = SPECIALS.length
1553  SPECIALS.quote = function(ast, scope, parent)
1554    compiler.assert((#ast == 2), "expected one argument", ast)
1555    local runtime, this_scope = true, scope
1556    while this_scope do
1557      this_scope = this_scope.parent
1558      if (this_scope == compiler.scopes.compiler) then
1559        runtime = false
1560      else
1561      end
1562    end
1563    return compiler["do-quote"](ast[2], scope, parent, runtime)
1564  end
1565  doc_special("quote", {"x"}, "Quasiquote the following form. Only works in macro/compiler scope.")
1566  local macro_loaded = {}
1567  local function safe_getmetatable(tbl)
1568    local mt = getmetatable(tbl)
1569    assert((mt ~= getmetatable("")), "Illegal metatable access!")
1570    return mt
1571  end
1572  local safe_require = nil
1573  local function safe_compiler_env()
1574    return {table = utils.copy(table), math = utils.copy(math), string = utils.copy(string), pairs = pairs, 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}
1575  end
1576  local function combined_mt_pairs(env)
1577    local combined = {}
1578    local _let_460_ = getmetatable(env)
1579    local __index = _let_460_["__index"]
1580    if ("table" == type(__index)) then
1581      for k, v in pairs(__index) do
1582        combined[k] = v
1583      end
1584    else
1585    end
1586    for k, v in next, env, nil do
1587      combined[k] = v
1588    end
1589    return next, combined, nil
1590  end
1591  local function make_compiler_env(ast, scope, parent, _3fopts)
1592    local provided
1593    do
1594      local _462_ = (_3fopts or utils.root.options)
1595      if ((_G.type(_462_) == "table") and ((_462_)["compiler-env"] == "strict")) then
1596        provided = safe_compiler_env()
1597      elseif ((_G.type(_462_) == "table") and (nil ~= (_462_).compilerEnv)) then
1598        local compilerEnv = (_462_).compilerEnv
1599        provided = compilerEnv
1600      elseif ((_G.type(_462_) == "table") and (nil ~= (_462_)["compiler-env"])) then
1601        local compiler_env = (_462_)["compiler-env"]
1602        provided = compiler_env
1603      elseif true then
1604        local _ = _462_
1605        provided = safe_compiler_env(false)
1606      else
1607        provided = nil
1608      end
1609    end
1610    local env
1611    local function _464_(base)
1612      return utils.sym(compiler.gensym((compiler.scopes.macro or scope), base))
1613    end
1614    local function _465_()
1615      return compiler.scopes.macro
1616    end
1617    local function _466_(symbol)
1618      compiler.assert(compiler.scopes.macro, "must call from macro", ast)
1619      return compiler.scopes.macro.manglings[tostring(symbol)]
1620    end
1621    local function _467_(form)
1622      compiler.assert(compiler.scopes.macro, "must call from macro", ast)
1623      return compiler.macroexpand(form, compiler.scopes.macro)
1624    end
1625    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, 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 = _464_, ["get-scope"] = _465_, ["in-scope?"] = _466_, macroexpand = _467_}
1626    env._G = env
1627    return setmetatable(env, {__index = provided, __newindex = provided, __pairs = combined_mt_pairs})
1628  end
1629  local function _469_(...)
1630    local tbl_14_auto = {}
1631    local i_15_auto = #tbl_14_auto
1632    for c in string.gmatch((package.config or ""), "([^\n]+)") do
1633      local val_16_auto = c
1634      if (nil ~= val_16_auto) then
1635        i_15_auto = (i_15_auto + 1)
1636        do end (tbl_14_auto)[i_15_auto] = val_16_auto
1637      else
1638      end
1639    end
1640    return tbl_14_auto
1641  end
1642  local _local_468_ = _469_(...)
1643  local dirsep = _local_468_[1]
1644  local pathsep = _local_468_[2]
1645  local pathmark = _local_468_[3]
1646  local pkg_config = {dirsep = (dirsep or "/"), pathmark = (pathmark or ";"), pathsep = (pathsep or "?")}
1647  local function escapepat(str)
1648    return string.gsub(str, "[^%w]", "%%%1")
1649  end
1650  local function search_module(modulename, _3fpathstring)
1651    local pathsepesc = escapepat(pkg_config.pathsep)
1652    local pattern = ("([^%s]*)%s"):format(pathsepesc, pathsepesc)
1653    local no_dot_module = modulename:gsub("%.", pkg_config.dirsep)
1654    local fullpath = ((_3fpathstring or utils["fennel-module"].path) .. pkg_config.pathsep)
1655    local function try_path(path)
1656      local filename = path:gsub(escapepat(pkg_config.pathmark), no_dot_module)
1657      local filename2 = path:gsub(escapepat(pkg_config.pathmark), modulename)
1658      local _471_ = (io.open(filename) or io.open(filename2))
1659      if (nil ~= _471_) then
1660        local file = _471_
1661        file:close()
1662        return filename
1663      else
1664        return nil
1665      end
1666    end
1667    local function find_in_path(start)
1668      local _473_ = fullpath:match(pattern, start)
1669      if (nil ~= _473_) then
1670        local path = _473_
1671        return (try_path(path) or find_in_path((start + #path + 1)))
1672      else
1673        return nil
1674      end
1675    end
1676    return find_in_path(1)
1677  end
1678  local function make_searcher(_3foptions)
1679    local function _475_(module_name)
1680      local opts = utils.copy(utils.root.options)
1681      for k, v in pairs((_3foptions or {})) do
1682        opts[k] = v
1683      end
1684      opts["module-name"] = module_name
1685      local _476_ = search_module(module_name)
1686      if (nil ~= _476_) then
1687        local filename = _476_
1688        local _479_
1689        do
1690          local _477_ = filename
1691          local _478_ = opts
1692          local function _480_(...)
1693            return utils["fennel-module"].dofile(_477_, _478_, ...)
1694          end
1695          _479_ = _480_
1696        end
1697        return _479_, filename
1698      else
1699        return nil
1700      end
1701    end
1702    return _475_
1703  end
1704  local function fennel_macro_searcher(module_name)
1705    local opts
1706    do
1707      local _482_ = utils.copy(utils.root.options)
1708      do end (_482_)["env"] = "_COMPILER"
1709      _482_["requireAsInclude"] = false
1710      _482_["allowedGlobals"] = nil
1711      opts = _482_
1712    end
1713    local _483_ = search_module(module_name, utils["fennel-module"]["macro-path"])
1714    if (nil ~= _483_) then
1715      local filename = _483_
1716      local _486_
1717      do
1718        local _484_ = filename
1719        local _485_ = opts
1720        local function _487_(...)
1721          return utils["fennel-module"].dofile(_484_, _485_, ...)
1722        end
1723        _486_ = _487_
1724      end
1725      return _486_, filename
1726    else
1727      return nil
1728    end
1729  end
1730  local function lua_macro_searcher(module_name)
1731    local _489_ = search_module(module_name, package.path)
1732    if (nil ~= _489_) then
1733      local filename = _489_
1734      local code
1735      do
1736        local f = io.open(filename)
1737        local function close_handlers_8_auto(ok_9_auto, ...)
1738          f:close()
1739          if ok_9_auto then
1740            return ...
1741          else
1742            return error(..., 0)
1743          end
1744        end
1745        local function _491_()
1746          return assert(f:read("*a"))
1747        end
1748        code = close_handlers_8_auto(_G.xpcall(_491_, (package.loaded.fennel or debug).traceback))
1749      end
1750      local chunk = load_code(code, make_compiler_env(), filename)
1751      return chunk, filename
1752    else
1753      return nil
1754    end
1755  end
1756  local macro_searchers = {fennel_macro_searcher, lua_macro_searcher}
1757  local function search_macro_module(modname, n)
1758    local _493_ = macro_searchers[n]
1759    if (nil ~= _493_) then
1760      local f = _493_
1761      local _494_, _495_ = f(modname)
1762      if ((nil ~= _494_) and true) then
1763        local loader = _494_
1764        local _3ffilename = _495_
1765        return loader, _3ffilename
1766      elseif true then
1767        local _ = _494_
1768        return search_macro_module(modname, (n + 1))
1769      else
1770        return nil
1771      end
1772    else
1773      return nil
1774    end
1775  end
1776  local function metadata_only_fennel(modname)
1777    if ((modname == "fennel.macros") or (package and package.loaded and ("table" == type(package.loaded[modname])) and (package.loaded[modname].metadata == compiler.metadata))) then
1778      return {metadata = compiler.metadata}
1779    else
1780      return nil
1781    end
1782  end
1783  local function _499_(modname)
1784    local function _500_()
1785      local loader, filename = search_macro_module(modname, 1)
1786      compiler.assert(loader, (modname .. " module not found."))
1787      do end (macro_loaded)[modname] = loader(modname, filename)
1788      return macro_loaded[modname]
1789    end
1790    return (macro_loaded[modname] or metadata_only_fennel(modname) or _500_())
1791  end
1792  safe_require = _499_
1793  local function add_macros(macros_2a, ast, scope)
1794    compiler.assert(utils["table?"](macros_2a), "expected macros to be table", ast)
1795    for k, v in pairs(macros_2a) do
1796      compiler.assert((type(v) == "function"), "expected each macro to be function", ast)
1797      do end (scope.macros)[k] = v
1798    end
1799    return nil
1800  end
1801  local function resolve_module_name(_501_, _scope, _parent, opts)
1802    local _arg_502_ = _501_
1803    local filename = _arg_502_["filename"]
1804    local second = _arg_502_[2]
1805    local filename0 = (filename or (utils["table?"](second) and second.filename))
1806    local module_name = utils.root.options["module-name"]
1807    local modexpr = compiler.compile(second, opts)
1808    local modname_chunk = load_code(modexpr)
1809    return modname_chunk(module_name, filename0)
1810  end
1811  SPECIALS["require-macros"] = function(ast, scope, parent, _3freal_ast)
1812    compiler.assert((#ast == 2), "Expected one module name argument", (_3freal_ast or ast))
1813    local modname = resolve_module_name(ast, scope, parent, {})
1814    compiler.assert(("string" == type(modname)), "module name must compile to string", (_3freal_ast or ast))
1815    if not macro_loaded[modname] then
1816      local loader, filename = search_macro_module(modname, 1)
1817      compiler.assert(loader, (modname .. " module not found."), ast)
1818      do end (macro_loaded)[modname] = loader(modname, filename)
1819    else
1820    end
1821    if ("import-macros" == tostring(ast[1])) then
1822      return macro_loaded[modname]
1823    else
1824      return add_macros(macro_loaded[modname], ast, scope, parent)
1825    end
1826  end
1827  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.")
1828  local function emit_included_fennel(src, path, opts, sub_chunk)
1829    local subscope = compiler["make-scope"](utils.root.scope.parent)
1830    local forms = {}
1831    if utils.root.options.requireAsInclude then
1832      subscope.specials.require = compiler["require-include"]
1833    else
1834    end
1835    for _, val in parser.parser(parser["string-stream"](src), path) do
1836      table.insert(forms, val)
1837    end
1838    for i = 1, #forms do
1839      local subopts
1840      if (i == #forms) then
1841        subopts = {tail = true}
1842      else
1843        subopts = {nval = 0}
1844      end
1845      utils["propagate-options"](opts, subopts)
1846      compiler.compile1(forms[i], subscope, sub_chunk, subopts)
1847    end
1848    return nil
1849  end
1850  local function include_path(ast, opts, path, mod, fennel_3f)
1851    utils.root.scope.includes[mod] = "fnl/loading"
1852    local src
1853    do
1854      local f = assert(io.open(path))
1855      local function close_handlers_8_auto(ok_9_auto, ...)
1856        f:close()
1857        if ok_9_auto then
1858          return ...
1859        else
1860          return error(..., 0)
1861        end
1862      end
1863      local function _508_()
1864        return f:read("*all"):gsub("[\13\n]*$", "")
1865      end
1866      src = close_handlers_8_auto(_G.xpcall(_508_, (package.loaded.fennel or debug).traceback))
1867    end
1868    local ret = utils.expr(("require(\"" .. mod .. "\")"), "statement")
1869    local target = ("package.preload[%q]"):format(mod)
1870    local preload_str = (target .. " = " .. target .. " or function(...)")
1871    local temp_chunk, sub_chunk = {}, {}
1872    compiler.emit(temp_chunk, preload_str, ast)
1873    compiler.emit(temp_chunk, sub_chunk)
1874    compiler.emit(temp_chunk, "end", ast)
1875    for i, v in ipairs(temp_chunk) do
1876      table.insert(utils.root.chunk, i, v)
1877    end
1878    if fennel_3f then
1879      emit_included_fennel(src, path, opts, sub_chunk)
1880    else
1881      compiler.emit(sub_chunk, src, ast)
1882    end
1883    utils.root.scope.includes[mod] = ret
1884    return ret
1885  end
1886  local function include_circular_fallback(mod, modexpr, fallback, ast)
1887    if (utils.root.scope.includes[mod] == "fnl/loading") then
1888      compiler.assert(fallback, "circular include detected", ast)
1889      return fallback(modexpr)
1890    else
1891      return nil
1892    end
1893  end
1894  SPECIALS.include = function(ast, scope, parent, opts)
1895    compiler.assert((#ast == 2), "expected one argument", ast)
1896    local modexpr
1897    do
1898      local _511_, _512_ = pcall(resolve_module_name, ast, scope, parent, opts)
1899      if ((_511_ == true) and (nil ~= _512_)) then
1900        local modname = _512_
1901        modexpr = utils.expr(string.format("%q", modname), "literal")
1902      elseif true then
1903        local _ = _511_
1904        modexpr = (compiler.compile1(ast[2], scope, parent, {nval = 1}))[1]
1905      else
1906        modexpr = nil
1907      end
1908    end
1909    if ((modexpr.type ~= "literal") or ((modexpr[1]):byte() ~= 34)) then
1910      if opts.fallback then
1911        return opts.fallback(modexpr)
1912      else
1913        return compiler.assert(false, "module name must be string literal", ast)
1914      end
1915    else
1916      local mod = load_code(("return " .. modexpr[1]))()
1917      local oldmod = utils.root.options["module-name"]
1918      local _
1919      utils.root.options["module-name"] = mod
1920      _ = nil
1921      local res
1922      local function _516_()
1923        local _515_ = search_module(mod)
1924        if (nil ~= _515_) then
1925          local fennel_path = _515_
1926          return include_path(ast, opts, fennel_path, mod, true)
1927        elseif true then
1928          local _0 = _515_
1929          local lua_path = search_module(mod, package.path)
1930          if lua_path then
1931            return include_path(ast, opts, lua_path, mod, false)
1932          elseif opts.fallback then
1933            return opts.fallback(modexpr)
1934          else
1935            return compiler.assert(false, ("module not found " .. mod), ast)
1936          end
1937        else
1938          return nil
1939        end
1940      end
1941      res = ((utils["member?"](mod, (utils.root.options.skipInclude or {})) and utils.expr("nil --[[SKIPPED INCLUDE]]--", "literal")) or include_circular_fallback(mod, modexpr, opts.fallback, ast) or utils.root.scope.includes[mod] or _516_())
1942      utils.root.options["module-name"] = oldmod
1943      return res
1944    end
1945  end
1946  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.")
1947  local function eval_compiler_2a(ast, scope, parent)
1948    local env = make_compiler_env(ast, scope, parent)
1949    local opts = utils.copy(utils.root.options)
1950    opts.scope = compiler["make-scope"](compiler.scopes.compiler)
1951    opts.allowedGlobals = current_global_names(env)
1952    return load_code(compiler.compile(ast, opts), wrap_env(env))(opts["module-name"], ast.filename)
1953  end
1954  SPECIALS.macros = function(ast, scope, parent)
1955    compiler.assert((#ast == 2), "Expected one table argument", ast)
1956    return add_macros(eval_compiler_2a(ast[2], scope, parent), ast, scope, parent)
1957  end
1958  doc_special("macros", {"{:macro-name-1 (fn [...] ...) ... :macro-name-N macro-body-N}"}, "Define all functions in the given table as macros local to the current scope.")
1959  SPECIALS["eval-compiler"] = function(ast, scope, parent)
1960    local old_first = ast[1]
1961    ast[1] = utils.sym("do")
1962    local val = eval_compiler_2a(ast, scope, parent)
1963    do end (ast)[1] = old_first
1964    return val
1965  end
1966  doc_special("eval-compiler", {"..."}, "Evaluate the body at compile-time. Use the macro system instead if possible.", true)
1967  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}
1968end
1969package.preload["fennel.compiler"] = package.preload["fennel.compiler"] or function(...)
1970  local utils = require("fennel.utils")
1971  local parser = require("fennel.parser")
1972  local friend = require("fennel.friend")
1973  local unpack = (table.unpack or _G.unpack)
1974  local scopes = {}
1975  local function make_scope(_3fparent)
1976    local parent = (_3fparent or scopes.global)
1977    local _203_
1978    if parent then
1979      _203_ = ((parent.depth or 0) + 1)
1980    else
1981      _203_ = 0
1982    end
1983    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 = _203_, hashfn = (parent and parent.hashfn), refedglobals = {}, parent = parent}
1984  end
1985  local function assert_msg(ast, msg)
1986    local ast_tbl
1987    if ("table" == type(ast)) then
1988      ast_tbl = ast
1989    else
1990      ast_tbl = {}
1991    end
1992    local m = getmetatable(ast)
1993    local filename = ((m and m.filename) or ast_tbl.filename or "unknown")
1994    local line = ((m and m.line) or ast_tbl.line or "?")
1995    local target = tostring((utils["sym?"](ast_tbl[1]) or ast_tbl[1] or "()"))
1996    return string.format("%s:%s: Compile error in '%s': %s", filename, line, target, msg)
1997  end
1998  local function assert_compile(condition, msg, ast)
1999    if not condition then
2000      local _let_206_ = (utils.root.options or {})
2001      local source = _let_206_["source"]
2002      local unfriendly = _let_206_["unfriendly"]
2003      if (nil == utils.hook("assert-compile", condition, msg, ast, utils.root.reset)) then
2004        utils.root.reset()
2005        if (unfriendly or not friend or not _G.io or not _G.io.read) then
2006          error(assert_msg(ast, msg), 0)
2007        else
2008          friend["assert-compile"](condition, msg, ast, source)
2009        end
2010      else
2011      end
2012    else
2013    end
2014    return condition
2015  end
2016  scopes.global = make_scope()
2017  scopes.global.vararg = true
2018  scopes.compiler = make_scope(scopes.global)
2019  scopes.macro = scopes.global
2020  local serialize_subst = {["\7"] = "\\a", ["\8"] = "\\b", ["\9"] = "\\t", ["\n"] = "n", ["\11"] = "\\v", ["\12"] = "\\f"}
2021  local function serialize_string(str)
2022    local function _210_(_241)
2023      return ("\\" .. _241:byte())
2024    end
2025    return string.gsub(string.gsub(string.format("%q", str), ".", serialize_subst), "[\128-\255]", _210_)
2026  end
2027  local function global_mangling(str)
2028    if utils["valid-lua-identifier?"](str) then
2029      return str
2030    else
2031      local function _211_(_241)
2032        return string.format("_%02x", _241:byte())
2033      end
2034      return ("__fnl_global__" .. str:gsub("[^%w]", _211_))
2035    end
2036  end
2037  local function global_unmangling(identifier)
2038    local _213_ = string.match(identifier, "^__fnl_global__(.*)$")
2039    if (nil ~= _213_) then
2040      local rest = _213_
2041      local _214_
2042      local function _215_(_241)
2043        return string.char(tonumber(_241:sub(2), 16))
2044      end
2045      _214_ = string.gsub(rest, "_[%da-f][%da-f]", _215_)
2046      return _214_
2047    elseif true then
2048      local _ = _213_
2049      return identifier
2050    else
2051      return nil
2052    end
2053  end
2054  local allowed_globals = nil
2055  local function global_allowed_3f(name)
2056    return (not allowed_globals or utils["member?"](name, allowed_globals))
2057  end
2058  local function unique_mangling(original, mangling, scope, append)
2059    if (scope.unmanglings[mangling] and not scope.gensyms[mangling]) then
2060      return unique_mangling(original, (original .. append), scope, (append + 1))
2061    else
2062      return mangling
2063    end
2064  end
2065  local function local_mangling(str, scope, ast, _3ftemp_manglings)
2066    assert_compile(not utils["multi-sym?"](str), ("unexpected multi symbol " .. str), ast)
2067    local raw
2068    if ((utils["lua-keywords"])[str] or str:match("^%d")) then
2069      raw = ("_" .. str)
2070    else
2071      raw = str
2072    end
2073    local mangling
2074    local function _219_(_241)
2075      return string.format("_%02x", _241:byte())
2076    end
2077    mangling = string.gsub(string.gsub(raw, "-", "_"), "[^%w_]", _219_)
2078    local unique = unique_mangling(mangling, mangling, scope, 0)
2079    do end (scope.unmanglings)[unique] = str
2080    do
2081      local manglings = (_3ftemp_manglings or scope.manglings)
2082      do end (manglings)[str] = unique
2083    end
2084    return unique
2085  end
2086  local function apply_manglings(scope, new_manglings, ast)
2087    for raw, mangled in pairs(new_manglings) do
2088      assert_compile(not scope.refedglobals[mangled], ("use of global " .. raw .. " is aliased by a local"), ast)
2089      do end (scope.manglings)[raw] = mangled
2090    end
2091    return nil
2092  end
2093  local function combine_parts(parts, scope)
2094    local ret = (scope.manglings[parts[1]] or global_mangling(parts[1]))
2095    for i = 2, #parts do
2096      if utils["valid-lua-identifier?"](parts[i]) then
2097        if (parts["multi-sym-method-call"] and (i == #parts)) then
2098          ret = (ret .. ":" .. parts[i])
2099        else
2100          ret = (ret .. "." .. parts[i])
2101        end
2102      else
2103        ret = (ret .. "[" .. serialize_string(parts[i]) .. "]")
2104      end
2105    end
2106    return ret
2107  end
2108  local function next_append()
2109    utils.root.scope["gensym-append"] = ((utils.root.scope["gensym-append"] or 0) + 1)
2110    return ("_" .. utils.root.scope["gensym-append"] .. "_")
2111  end
2112  local function gensym(scope, _3fbase, _3fsuffix)
2113    local mangling = ((_3fbase or "") .. next_append() .. (_3fsuffix or ""))
2114    while scope.unmanglings[mangling] do
2115      mangling = ((_3fbase or "") .. next_append() .. (_3fsuffix or ""))
2116    end
2117    scope.unmanglings[mangling] = (_3fbase or true)
2118    do end (scope.gensyms)[mangling] = true
2119    return mangling
2120  end
2121  local function autogensym(base, scope)
2122    local _222_ = utils["multi-sym?"](base)
2123    if (nil ~= _222_) then
2124      local parts = _222_
2125      parts[1] = autogensym(parts[1], scope)
2126      return table.concat(parts, ((parts["multi-sym-method-call"] and ":") or "."))
2127    elseif true then
2128      local _ = _222_
2129      local function _223_()
2130        local mangling = gensym(scope, base:sub(1, ( - 2)), "auto")
2131        do end (scope.autogensyms)[base] = mangling
2132        return mangling
2133      end
2134      return (scope.autogensyms[base] or _223_())
2135    else
2136      return nil
2137    end
2138  end
2139  local function check_binding_valid(symbol, scope, ast)
2140    local name = tostring(symbol)
2141    assert_compile(not name:find("&"), "illegal character &")
2142    assert_compile(not (scope.specials[name] or scope.macros[name]), ("local %s was overshadowed by a special form or macro"):format(name), ast)
2143    return assert_compile(not utils["quoted?"](symbol), string.format("macro tried to bind %s without gensym", name), symbol)
2144  end
2145  local function declare_local(symbol, meta, scope, ast, _3ftemp_manglings)
2146    check_binding_valid(symbol, scope, ast)
2147    local name = tostring(symbol)
2148    assert_compile(not utils["multi-sym?"](name), ("unexpected multi symbol " .. name), ast)
2149    do end (scope.symmeta)[name] = meta
2150    return local_mangling(name, scope, ast, _3ftemp_manglings)
2151  end
2152  local function hashfn_arg_name(name, multi_sym_parts, scope)
2153    if not scope.hashfn then
2154      return nil
2155    elseif (name == "$") then
2156      return "$1"
2157    elseif multi_sym_parts then
2158      if (multi_sym_parts and (multi_sym_parts[1] == "$")) then
2159        multi_sym_parts[1] = "$1"
2160      else
2161      end
2162      return table.concat(multi_sym_parts, ".")
2163    else
2164      return nil
2165    end
2166  end
2167  local function symbol_to_expression(symbol, scope, _3freference_3f)
2168    utils.hook("symbol-to-expression", symbol, scope, _3freference_3f)
2169    local name = symbol[1]
2170    local multi_sym_parts = utils["multi-sym?"](name)
2171    local name0 = (hashfn_arg_name(name, multi_sym_parts, scope) or name)
2172    local parts = (multi_sym_parts or {name0})
2173    local etype = (((#parts > 1) and "expression") or "sym")
2174    local local_3f = scope.manglings[parts[1]]
2175    if (local_3f and scope.symmeta[parts[1]]) then
2176      scope.symmeta[parts[1]]["used"] = true
2177    else
2178    end
2179    assert_compile(not scope.macros[parts[1]], "tried to reference a macro at runtime", symbol)
2180    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)
2181    if (allowed_globals and not local_3f and scope.parent) then
2182      scope.parent.refedglobals[parts[1]] = true
2183    else
2184    end
2185    return utils.expr(combine_parts(parts, scope), etype)
2186  end
2187  local function emit(chunk, out, _3fast)
2188    if (type(out) == "table") then
2189      return table.insert(chunk, out)
2190    else
2191      return table.insert(chunk, {ast = _3fast, leaf = out})
2192    end
2193  end
2194  local function peephole(chunk)
2195    if chunk.leaf then
2196      return chunk
2197    elseif ((#chunk >= 3) and ((chunk[(#chunk - 2)]).leaf == "do") and not (chunk[(#chunk - 1)]).leaf and (chunk[#chunk].leaf == "end")) then
2198      local kid = peephole(chunk[(#chunk - 1)])
2199      local new_chunk = {ast = chunk.ast}
2200      for i = 1, (#chunk - 3) do
2201        table.insert(new_chunk, peephole(chunk[i]))
2202      end
2203      for i = 1, #kid do
2204        table.insert(new_chunk, kid[i])
2205      end
2206      return new_chunk
2207    else
2208      return utils.map(chunk, peephole)
2209    end
2210  end
2211  local function flatten_chunk_correlated(main_chunk, options)
2212    local function flatten(chunk, out, last_line, file)
2213      local last_line0 = last_line
2214      if chunk.leaf then
2215        out[last_line0] = ((out[last_line0] or "") .. " " .. chunk.leaf)
2216      else
2217        for _, subchunk in ipairs(chunk) do
2218          if (subchunk.leaf or (#subchunk > 0)) then
2219            local source = utils["ast-source"](subchunk.ast)
2220            if (file == source.filename) then
2221              last_line0 = math.max(last_line0, (source.line or 0))
2222            else
2223            end
2224            last_line0 = flatten(subchunk, out, last_line0, file)
2225          else
2226          end
2227        end
2228      end
2229      return last_line0
2230    end
2231    local out = {}
2232    local last = flatten(main_chunk, out, 1, options.filename)
2233    for i = 1, last do
2234      if (out[i] == nil) then
2235        out[i] = ""
2236      else
2237      end
2238    end
2239    return table.concat(out, "\n")
2240  end
2241  local function flatten_chunk(sm, chunk, tab, depth)
2242    if chunk.leaf then
2243      local code = chunk.leaf
2244      local info = chunk.ast
2245      if sm then
2246        table.insert(sm, {(info and info.filename), (info and info.line)})
2247      else
2248      end
2249      return code
2250    else
2251      local tab0
2252      do
2253        local _236_ = tab
2254        if (_236_ == true) then
2255          tab0 = "  "
2256        elseif (_236_ == false) then
2257          tab0 = ""
2258        elseif (_236_ == tab) then
2259          tab0 = tab
2260        elseif (_236_ == nil) then
2261          tab0 = ""
2262        else
2263          tab0 = nil
2264        end
2265      end
2266      local function parter(c)
2267        if (c.leaf or (#c > 0)) then
2268          local sub = flatten_chunk(sm, c, tab0, (depth + 1))
2269          if (depth > 0) then
2270            return (tab0 .. sub:gsub("\n", ("\n" .. tab0)))
2271          else
2272            return sub
2273          end
2274        else
2275          return nil
2276        end
2277      end
2278      return table.concat(utils.map(chunk, parter), "\n")
2279    end
2280  end
2281  local sourcemap = {}
2282  local function make_short_src(source)
2283    local source0 = source:gsub("\n", " ")
2284    if (#source0 <= 49) then
2285      return ("[fennel \"" .. source0 .. "\"]")
2286    else
2287      return ("[fennel \"" .. source0:sub(1, 46) .. "...\"]")
2288    end
2289  end
2290  local function flatten(chunk, options)
2291    local chunk0 = peephole(chunk)
2292    if options.correlate then
2293      return flatten_chunk_correlated(chunk0, options), {}
2294    else
2295      local sm = {}
2296      local ret = flatten_chunk(sm, chunk0, options.indent, 0)
2297      if sm then
2298        sm.short_src = (options.filename or make_short_src((options.source or ret)))
2299        if options.filename then
2300          sm.key = ("@" .. options.filename)
2301        else
2302          sm.key = ret
2303        end
2304        sourcemap[sm.key] = sm
2305      else
2306      end
2307      return ret, sm
2308    end
2309  end
2310  local function make_metadata()
2311    local function _245_(self, tgt, key)
2312      if self[tgt] then
2313        return self[tgt][key]
2314      else
2315        return nil
2316      end
2317    end
2318    local function _247_(self, tgt, key, value)
2319      self[tgt] = (self[tgt] or {})
2320      do end (self[tgt])[key] = value
2321      return tgt
2322    end
2323    local function _248_(self, tgt, ...)
2324      local kv_len = select("#", ...)
2325      local kvs = {...}
2326      if ((kv_len % 2) ~= 0) then
2327        error("metadata:setall() expected even number of k/v pairs")
2328      else
2329      end
2330      self[tgt] = (self[tgt] or {})
2331      for i = 1, kv_len, 2 do
2332        self[tgt][kvs[i]] = kvs[(i + 1)]
2333      end
2334      return tgt
2335    end
2336    return setmetatable({}, {__index = {get = _245_, set = _247_, setall = _248_}, __mode = "k"})
2337  end
2338  local function exprs1(exprs)
2339    return table.concat(utils.map(exprs, tostring), ", ")
2340  end
2341  local function keep_side_effects(exprs, chunk, start, ast)
2342    local start0 = (start or 1)
2343    for j = start0, #exprs do
2344      local se = exprs[j]
2345      if ((se.type == "expression") and (se[1] ~= "nil")) then
2346        emit(chunk, string.format("do local _ = %s end", tostring(se)), ast)
2347      elseif (se.type == "statement") then
2348        local code = tostring(se)
2349        local disambiguated
2350        if (code:byte() == 40) then
2351          disambiguated = ("do end " .. code)
2352        else
2353          disambiguated = code
2354        end
2355        emit(chunk, disambiguated, ast)
2356      else
2357      end
2358    end
2359    return nil
2360  end
2361  local function handle_compile_opts(exprs, parent, opts, ast)
2362    if opts.nval then
2363      local n = opts.nval
2364      local len = #exprs
2365      if (n ~= len) then
2366        if (len > n) then
2367          keep_side_effects(exprs, parent, (n + 1), ast)
2368          for i = (n + 1), len do
2369            exprs[i] = nil
2370          end
2371        else
2372          for i = (#exprs + 1), n do
2373            exprs[i] = utils.expr("nil", "literal")
2374          end
2375        end
2376      else
2377      end
2378    else
2379    end
2380    if opts.tail then
2381      emit(parent, string.format("return %s", exprs1(exprs)), ast)
2382    else
2383    end
2384    if opts.target then
2385      local result = exprs1(exprs)
2386      local function _256_()
2387        if (result == "") then
2388          return "nil"
2389        else
2390          return result
2391        end
2392      end
2393      emit(parent, string.format("%s = %s", opts.target, _256_()), ast)
2394    else
2395    end
2396    if (opts.tail or opts.target) then
2397      return {returned = true}
2398    else
2399      local _258_ = exprs
2400      _258_["returned"] = true
2401      return _258_
2402    end
2403  end
2404  local function find_macro(ast, scope, multi_sym_parts)
2405    local function find_in_table(t, i)
2406      if (i <= #multi_sym_parts) then
2407        return find_in_table((utils["table?"](t) and t[multi_sym_parts[i]]), (i + 1))
2408      else
2409        return t
2410      end
2411    end
2412    local macro_2a = (utils["sym?"](ast[1]) and scope.macros[tostring(ast[1])])
2413    if (not macro_2a and multi_sym_parts) then
2414      local nested_macro = find_in_table(scope.macros, 1)
2415      assert_compile((not scope.macros[multi_sym_parts[1]] or (type(nested_macro) == "function")), "macro not found in imported macro module", ast)
2416      return nested_macro
2417    else
2418      return macro_2a
2419    end
2420  end
2421  local function propagate_trace_info(_262_, _index, node)
2422    local _arg_263_ = _262_
2423    local filename = _arg_263_["filename"]
2424    local line = _arg_263_["line"]
2425    local bytestart = _arg_263_["bytestart"]
2426    local byteend = _arg_263_["byteend"]
2427    if (("table" == type(node)) and (filename ~= node.filename)) then
2428      local src = utils["ast-source"](node)
2429      src.filename, src.line = filename, line
2430      src.bytestart, src.byteend = bytestart, byteend
2431    else
2432    end
2433    return ("table" == type(node))
2434  end
2435  local function macroexpand_2a(ast, scope, _3fonce)
2436    local _265_
2437    if utils["list?"](ast) then
2438      _265_ = find_macro(ast, scope, utils["multi-sym?"](ast[1]))
2439    else
2440      _265_ = nil
2441    end
2442    if (_265_ == false) then
2443      return ast
2444    elseif (nil ~= _265_) then
2445      local macro_2a = _265_
2446      local old_scope = scopes.macro
2447      local _
2448      scopes.macro = scope
2449      _ = nil
2450      local ok, transformed = nil, nil
2451      local function _267_()
2452        return macro_2a(unpack(ast, 2))
2453      end
2454      ok, transformed = xpcall(_267_, debug.traceback)
2455      local function _269_()
2456        local _268_ = ast
2457        local function _270_(...)
2458          return propagate_trace_info(_268_, ...)
2459        end
2460        return _270_
2461      end
2462      utils["walk-tree"](transformed, _269_())
2463      scopes.macro = old_scope
2464      assert_compile(ok, transformed, ast)
2465      if (_3fonce or not transformed) then
2466        return transformed
2467      else
2468        return macroexpand_2a(transformed, scope)
2469      end
2470    elseif true then
2471      local _ = _265_
2472      return ast
2473    else
2474      return nil
2475    end
2476  end
2477  local function compile_special(ast, scope, parent, opts, special)
2478    local exprs = (special(ast, scope, parent, opts) or utils.expr("nil", "literal"))
2479    local exprs0
2480    if ("table" ~= type(exprs)) then
2481      exprs0 = utils.expr(exprs, "expression")
2482    else
2483      exprs0 = exprs
2484    end
2485    local exprs2
2486    if utils["expr?"](exprs0) then
2487      exprs2 = {exprs0}
2488    else
2489      exprs2 = exprs0
2490    end
2491    if not exprs2.returned then
2492      return handle_compile_opts(exprs2, parent, opts, ast)
2493    elseif (opts.tail or opts.target) then
2494      return {returned = true}
2495    else
2496      return exprs2
2497    end
2498  end
2499  local function compile_function_call(ast, scope, parent, opts, compile1, len)
2500    local fargs = {}
2501    local fcallee = (compile1(ast[1], scope, parent, {nval = 1}))[1]
2502    assert_compile((("string" == type(ast[1])) or (fcallee.type ~= "literal")), ("cannot call literal value " .. tostring(ast[1])), ast)
2503    for i = 2, len do
2504      local subexprs
2505      local _276_
2506      if (i ~= len) then
2507        _276_ = 1
2508      else
2509        _276_ = nil
2510      end
2511      subexprs = compile1(ast[i], scope, parent, {nval = _276_})
2512      table.insert(fargs, (subexprs[1] or utils.expr("nil", "literal")))
2513      if (i == len) then
2514        for j = 2, #subexprs do
2515          table.insert(fargs, subexprs[j])
2516        end
2517      else
2518        keep_side_effects(subexprs, parent, 2, ast[i])
2519      end
2520    end
2521    local pat
2522    if ("string" == type(ast[1])) then
2523      pat = "(%s)(%s)"
2524    else
2525      pat = "%s(%s)"
2526    end
2527    local call = string.format(pat, tostring(fcallee), exprs1(fargs))
2528    return handle_compile_opts({utils.expr(call, "statement")}, parent, opts, ast)
2529  end
2530  local function compile_call(ast, scope, parent, opts, compile1)
2531    utils.hook("call", ast, scope)
2532    local len = #ast
2533    local first = ast[1]
2534    local multi_sym_parts = utils["multi-sym?"](first)
2535    local special = (utils["sym?"](first) and scope.specials[tostring(first)])
2536    assert_compile((len > 0), "expected a function, macro, or special to call", ast)
2537    if special then
2538      return compile_special(ast, scope, parent, opts, special)
2539    elseif (multi_sym_parts and multi_sym_parts["multi-sym-method-call"]) then
2540      local table_with_method = table.concat({unpack(multi_sym_parts, 1, (#multi_sym_parts - 1))}, ".")
2541      local method_to_call = multi_sym_parts[#multi_sym_parts]
2542      local new_ast = utils.list(utils.sym(":", nil, scope), utils.sym(table_with_method, nil, scope), method_to_call, select(2, unpack(ast)))
2543      return compile1(new_ast, scope, parent, opts)
2544    else
2545      return compile_function_call(ast, scope, parent, opts, compile1, len)
2546    end
2547  end
2548  local function compile_varg(ast, scope, parent, opts)
2549    assert_compile(scope.vararg, "unexpected vararg", ast)
2550    return handle_compile_opts({utils.expr("...", "varg")}, parent, opts, ast)
2551  end
2552  local function compile_sym(ast, scope, parent, opts)
2553    local multi_sym_parts = utils["multi-sym?"](ast)
2554    assert_compile(not (multi_sym_parts and multi_sym_parts["multi-sym-method-call"]), "multisym method calls may only be in call position", ast)
2555    local e
2556    if (ast[1] == "nil") then
2557      e = utils.expr("nil", "literal")
2558    else
2559      e = symbol_to_expression(ast, scope, true)
2560    end
2561    return handle_compile_opts({e}, parent, opts, ast)
2562  end
2563  local function serialize_number(n)
2564    local _282_ = string.gsub(tostring(n), ",", ".")
2565    return _282_
2566  end
2567  local function compile_scalar(ast, _scope, parent, opts)
2568    local serialize
2569    do
2570      local _283_ = type(ast)
2571      if (_283_ == "nil") then
2572        serialize = tostring
2573      elseif (_283_ == "boolean") then
2574        serialize = tostring
2575      elseif (_283_ == "string") then
2576        serialize = serialize_string
2577      elseif (_283_ == "number") then
2578        serialize = serialize_number
2579      else
2580        serialize = nil
2581      end
2582    end
2583    return handle_compile_opts({utils.expr(serialize(ast), "literal")}, parent, opts)
2584  end
2585  local function compile_table(ast, scope, parent, opts, compile1)
2586    local buffer = {}
2587    local function write_other_values(k)
2588      if ((type(k) ~= "number") or (math.floor(k) ~= k) or (k < 1) or (k > #ast)) then
2589        if ((type(k) == "string") and utils["valid-lua-identifier?"](k)) then
2590          return {k, k}
2591        else
2592          local _let_285_ = compile1(k, scope, parent, {nval = 1})
2593          local compiled = _let_285_[1]
2594          local kstr = ("[" .. tostring(compiled) .. "]")
2595          return {kstr, k}
2596        end
2597      else
2598        return nil
2599      end
2600    end
2601    do
2602      local keys
2603      do
2604        local tbl_14_auto = {}
2605        local i_15_auto = #tbl_14_auto
2606        for k, v in utils.stablepairs(ast) do
2607          local val_16_auto = write_other_values(k, v)
2608          if (nil ~= val_16_auto) then
2609            i_15_auto = (i_15_auto + 1)
2610            do end (tbl_14_auto)[i_15_auto] = val_16_auto
2611          else
2612          end
2613        end
2614        keys = tbl_14_auto
2615      end
2616      local function _291_(_289_)
2617        local _arg_290_ = _289_
2618        local k1 = _arg_290_[1]
2619        local k2 = _arg_290_[2]
2620        local _let_292_ = compile1(ast[k2], scope, parent, {nval = 1})
2621        local v = _let_292_[1]
2622        return string.format("%s = %s", k1, tostring(v))
2623      end
2624      utils.map(keys, _291_, buffer)
2625    end
2626    for i = 1, #ast do
2627      local nval = ((i ~= #ast) and 1)
2628      table.insert(buffer, exprs1(compile1(ast[i], scope, parent, {nval = nval})))
2629    end
2630    return handle_compile_opts({utils.expr(("{" .. table.concat(buffer, ", ") .. "}"), "expression")}, parent, opts, ast)
2631  end
2632  local function compile1(ast, scope, parent, _3fopts)
2633    local opts = (_3fopts or {})
2634    local ast0 = macroexpand_2a(ast, scope)
2635    if utils["list?"](ast0) then
2636      return compile_call(ast0, scope, parent, opts, compile1)
2637    elseif utils["varg?"](ast0) then
2638      return compile_varg(ast0, scope, parent, opts)
2639    elseif utils["sym?"](ast0) then
2640      return compile_sym(ast0, scope, parent, opts)
2641    elseif (type(ast0) == "table") then
2642      return compile_table(ast0, scope, parent, opts, compile1)
2643    elseif ((type(ast0) == "nil") or (type(ast0) == "boolean") or (type(ast0) == "number") or (type(ast0) == "string")) then
2644      return compile_scalar(ast0, scope, parent, opts)
2645    else
2646      return assert_compile(false, ("could not compile value of type " .. type(ast0)), ast0)
2647    end
2648  end
2649  local function destructure(to, from, ast, scope, parent, opts)
2650    local opts0 = (opts or {})
2651    local _let_294_ = opts0
2652    local isvar = _let_294_["isvar"]
2653    local declaration = _let_294_["declaration"]
2654    local forceglobal = _let_294_["forceglobal"]
2655    local forceset = _let_294_["forceset"]
2656    local symtype = _let_294_["symtype"]
2657    local symtype0 = ("_" .. (symtype or "dst"))
2658    local setter
2659    if declaration then
2660      setter = "local %s = %s"
2661    else
2662      setter = "%s = %s"
2663    end
2664    local new_manglings = {}
2665    local function getname(symbol, up1)
2666      local raw = symbol[1]
2667      assert_compile(not (opts0.nomulti and utils["multi-sym?"](raw)), ("unexpected multi symbol " .. raw), up1)
2668      if declaration then
2669        return declare_local(symbol, nil, scope, symbol, new_manglings)
2670      else
2671        local parts = (utils["multi-sym?"](raw) or {raw})
2672        local meta = scope.symmeta[parts[1]]
2673        assert_compile(not raw:find(":"), "cannot set method sym", symbol)
2674        if ((#parts == 1) and not forceset) then
2675          assert_compile(not (forceglobal and meta), string.format("global %s conflicts with local", tostring(symbol)), symbol)
2676          assert_compile(not (meta and not meta.var), ("expected var " .. raw), symbol)
2677          assert_compile((meta or not opts0.noundef), ("expected local " .. parts[1]), symbol)
2678        else
2679        end
2680        if forceglobal then
2681          assert_compile(not scope.symmeta[scope.unmanglings[raw]], ("global " .. raw .. " conflicts with local"), symbol)
2682          do end (scope.manglings)[raw] = global_mangling(raw)
2683          do end (scope.unmanglings)[global_mangling(raw)] = raw
2684          if allowed_globals then
2685            table.insert(allowed_globals, raw)
2686          else
2687          end
2688        else
2689        end
2690        return symbol_to_expression(symbol, scope)[1]
2691      end
2692    end
2693    local function compile_top_target(lvalues)
2694      local inits
2695      local function _300_(_241)
2696        if scope.manglings[_241] then
2697          return _241
2698        else
2699          return "nil"
2700        end
2701      end
2702      inits = utils.map(lvalues, _300_)
2703      local init = table.concat(inits, ", ")
2704      local lvalue = table.concat(lvalues, ", ")
2705      local plen, plast = #parent, parent[#parent]
2706      local ret = compile1(from, scope, parent, {target = lvalue})
2707      if declaration then
2708        for pi = plen, #parent do
2709          if (parent[pi] == plast) then
2710            plen = pi
2711          else
2712          end
2713        end
2714        if ((#parent == (plen + 1)) and parent[#parent].leaf) then
2715          parent[#parent]["leaf"] = ("local " .. parent[#parent].leaf)
2716        elseif (init == "nil") then
2717          table.insert(parent, (plen + 1), {ast = ast, leaf = ("local " .. lvalue)})
2718        else
2719          table.insert(parent, (plen + 1), {ast = ast, leaf = ("local " .. lvalue .. " = " .. init)})
2720        end
2721      else
2722      end
2723      return ret
2724    end
2725    local function destructure_sym(left, rightexprs, up1, top_3f)
2726      local lname = getname(left, up1)
2727      check_binding_valid(left, scope, left)
2728      if top_3f then
2729        compile_top_target({lname})
2730      else
2731        emit(parent, setter:format(lname, exprs1(rightexprs)), left)
2732      end
2733      if declaration then
2734        scope.symmeta[tostring(left)] = {var = isvar}
2735        return nil
2736      else
2737        return nil
2738      end
2739    end
2740    local function destructure_table(left, rightexprs, top_3f, destructure1)
2741      local s = gensym(scope, symtype0)
2742      local right
2743      do
2744        local _307_
2745        if top_3f then
2746          _307_ = exprs1(compile1(from, scope, parent))
2747        else
2748          _307_ = exprs1(rightexprs)
2749        end
2750        if (_307_ == "") then
2751          right = "nil"
2752        elseif (nil ~= _307_) then
2753          local right0 = _307_
2754          right = right0
2755        else
2756          right = nil
2757        end
2758      end
2759      emit(parent, string.format("local %s = %s", s, right), left)
2760      for k, v in utils.stablepairs(left) do
2761        if not (("number" == type(k)) and tostring(left[(k - 1)]):find("^&")) then
2762          if (utils["sym?"](v) and (tostring(v) == "&")) then
2763            local unpack_str = "(function (t, k)\n                                      local mt = getmetatable(t)\n                                      if \"table\" == type(mt) and mt.__fennelrest then\n                                         return mt.__fennelrest(t, k)\n                                      else\n                                         return {(table.unpack or unpack)(t, k)}\n                                      end\n                                   end)(%s, %s)"
2764            local formatted = string.format(string.gsub(unpack_str, "\n%s*", " "), s, k)
2765            local subexpr = utils.expr(formatted, "expression")
2766            assert_compile((utils["sequence?"](left) and (nil == left[(k + 2)])), "expected rest argument before last parameter", left)
2767            destructure1(left[(k + 1)], {subexpr}, left)
2768          elseif (utils["sym?"](k) and (tostring(k) == "&as")) then
2769            destructure_sym(v, {utils.expr(tostring(s))}, left)
2770          elseif (utils["sequence?"](left) and (tostring(v) == "&as")) then
2771            local _, next_sym, trailing = select(k, unpack(left))
2772            assert_compile((nil == trailing), "expected &as argument before last parameter", left)
2773            destructure_sym(next_sym, {utils.expr(tostring(s))}, left)
2774          else
2775            local key
2776            if (type(k) == "string") then
2777              key = serialize_string(k)
2778            else
2779              key = k
2780            end
2781            local subexpr = utils.expr(string.format("%s[%s]", s, key), "expression")
2782            destructure1(v, {subexpr}, left)
2783          end
2784        else
2785        end
2786      end
2787      return nil
2788    end
2789    local function destructure_values(left, up1, top_3f, destructure1)
2790      local left_names, tables = {}, {}
2791      for i, name in ipairs(left) do
2792        if utils["sym?"](name) then
2793          table.insert(left_names, getname(name, up1))
2794        else
2795          local symname = gensym(scope, symtype0)
2796          table.insert(left_names, symname)
2797          do end (tables)[i] = {name, utils.expr(symname, "sym")}
2798        end
2799      end
2800      assert_compile(top_3f, "can't nest multi-value destructuring", left)
2801      compile_top_target(left_names)
2802      if declaration then
2803        for _, sym in ipairs(left) do
2804          if utils["sym?"](sym) then
2805            scope.symmeta[tostring(sym)] = {var = isvar}
2806          else
2807          end
2808        end
2809      else
2810      end
2811      for _, pair in utils.stablepairs(tables) do
2812        destructure1(pair[1], {pair[2]}, left)
2813      end
2814      return nil
2815    end
2816    local function destructure1(left, rightexprs, up1, top_3f)
2817      if (utils["sym?"](left) and (left[1] ~= "nil")) then
2818        destructure_sym(left, rightexprs, up1, top_3f)
2819      elseif utils["table?"](left) then
2820        destructure_table(left, rightexprs, top_3f, destructure1)
2821      elseif utils["list?"](left) then
2822        destructure_values(left, up1, top_3f, destructure1)
2823      else
2824        assert_compile(false, string.format("unable to bind %s %s", type(left), tostring(left)), (((type((up1)[2]) == "table") and (up1)[2]) or up1))
2825      end
2826      if top_3f then
2827        return {returned = true}
2828      else
2829        return nil
2830      end
2831    end
2832    local ret = destructure1(to, nil, ast, true)
2833    utils.hook("destructure", from, to, scope)
2834    apply_manglings(scope, new_manglings, ast)
2835    return ret
2836  end
2837  local function require_include(ast, scope, parent, opts)
2838    opts.fallback = function(e)
2839      utils.warn(("include module not found, falling back to require: %s"):format(tostring(e)))
2840      return utils.expr(string.format("require(%s)", tostring(e)), "statement")
2841    end
2842    return scopes.global.specials.include(ast, scope, parent, opts)
2843  end
2844  local function compile_stream(strm, options)
2845    local opts = utils.copy(options)
2846    local old_globals = allowed_globals
2847    local scope = (opts.scope or make_scope(scopes.global))
2848    local vals = {}
2849    local chunk = {}
2850    do end (function(tgt, m, ...) return tgt[m](tgt, ...) end)(utils.root, "set-reset")
2851    allowed_globals = opts.allowedGlobals
2852    if (opts.indent == nil) then
2853      opts.indent = "  "
2854    else
2855    end
2856    if opts.requireAsInclude then
2857      scope.specials.require = require_include
2858    else
2859    end
2860    utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts
2861    for _, val in parser.parser(strm, opts.filename, opts) do
2862      table.insert(vals, val)
2863    end
2864    for i = 1, #vals do
2865      local exprs = compile1(vals[i], scope, chunk, {nval = (((i < #vals) and 0) or nil), tail = (i == #vals)})
2866      keep_side_effects(exprs, chunk, nil, vals[i])
2867      if (i == #vals) then
2868        utils.hook("chunk", vals[i], scope)
2869      else
2870      end
2871    end
2872    allowed_globals = old_globals
2873    utils.root.reset()
2874    return flatten(chunk, opts)
2875  end
2876  local function compile_string(str, opts)
2877    return compile_stream(parser["string-stream"](str), (opts or {}))
2878  end
2879  local function compile(ast, opts)
2880    local opts0 = utils.copy(opts)
2881    local old_globals = allowed_globals
2882    local chunk = {}
2883    local scope = (opts0.scope or make_scope(scopes.global))
2884    do end (function(tgt, m, ...) return tgt[m](tgt, ...) end)(utils.root, "set-reset")
2885    allowed_globals = opts0.allowedGlobals
2886    if (opts0.indent == nil) then
2887      opts0.indent = "  "
2888    else
2889    end
2890    if opts0.requireAsInclude then
2891      scope.specials.require = require_include
2892    else
2893    end
2894    utils.root.chunk, utils.root.scope, utils.root.options = chunk, scope, opts0
2895    local exprs = compile1(ast, scope, chunk, {tail = true})
2896    keep_side_effects(exprs, chunk, nil, ast)
2897    utils.hook("chunk", ast, scope)
2898    allowed_globals = old_globals
2899    utils.root.reset()
2900    return flatten(chunk, opts0)
2901  end
2902  local function traceback_frame(info)
2903    if ((info.what == "C") and info.name) then
2904      return string.format("  [C]: in function '%s'", info.name)
2905    elseif (info.what == "C") then
2906      return "  [C]: in ?"
2907    else
2908      local remap = sourcemap[info.source]
2909      if (remap and remap[info.currentline]) then
2910        if remap[info.currentline][1] then
2911          info.short_src = sourcemap[("@" .. remap[info.currentline][1])].short_src
2912        else
2913          info.short_src = remap.short_src
2914        end
2915        info.currentline = (remap[info.currentline][2] or -1)
2916      else
2917      end
2918      if (info.what == "Lua") then
2919        local function _325_()
2920          if info.name then
2921            return ("'" .. info.name .. "'")
2922          else
2923            return "?"
2924          end
2925        end
2926        return string.format("  %s:%d: in function %s", info.short_src, info.currentline, _325_())
2927      elseif (info.short_src == "(tail call)") then
2928        return "  (tail call)"
2929      else
2930        return string.format("  %s:%d: in main chunk", info.short_src, info.currentline)
2931      end
2932    end
2933  end
2934  local function traceback(msg, start)
2935    local msg0 = tostring((msg or ""))
2936    if ((msg0:find("^Compile error") or msg0:find("^Parse error")) and not utils["debug-on?"]("trace")) then
2937      return msg0
2938    else
2939      local lines = {}
2940      if (msg0:find(":%d+: Compile error") or msg0:find(":%d+: Parse error")) then
2941        table.insert(lines, msg0)
2942      else
2943        local newmsg = msg0:gsub("^[^:]*:%d+:%s+", "runtime error: ")
2944        table.insert(lines, newmsg)
2945      end
2946      table.insert(lines, "stack traceback:")
2947      local done_3f, level = false, (start or 2)
2948      while not done_3f do
2949        do
2950          local _329_ = debug.getinfo(level, "Sln")
2951          if (_329_ == nil) then
2952            done_3f = true
2953          elseif (nil ~= _329_) then
2954            local info = _329_
2955            table.insert(lines, traceback_frame(info))
2956          else
2957          end
2958        end
2959        level = (level + 1)
2960      end
2961      return table.concat(lines, "\n")
2962    end
2963  end
2964  local function entry_transform(fk, fv)
2965    local function _332_(k, v)
2966      if (type(k) == "number") then
2967        return k, fv(v)
2968      else
2969        return fk(k), fv(v)
2970      end
2971    end
2972    return _332_
2973  end
2974  local function mixed_concat(t, joiner)
2975    local seen = {}
2976    local ret, s = "", ""
2977    for k, v in ipairs(t) do
2978      table.insert(seen, k)
2979      ret = (ret .. s .. v)
2980      s = joiner
2981    end
2982    for k, v in utils.stablepairs(t) do
2983      if not seen[k] then
2984        ret = (ret .. s .. "[" .. k .. "]" .. "=" .. v)
2985        s = joiner
2986      else
2987      end
2988    end
2989    return ret
2990  end
2991  local function do_quote(form, scope, parent, runtime_3f)
2992    local function q(x)
2993      return do_quote(x, scope, parent, runtime_3f)
2994    end
2995    if utils["varg?"](form) then
2996      assert_compile(not runtime_3f, "quoted ... may only be used at compile time", form)
2997      return "_VARARG"
2998    elseif utils["sym?"](form) then
2999      local filename
3000      if form.filename then
3001        filename = string.format("%q", form.filename)
3002      else
3003        filename = "nil"
3004      end
3005      local symstr = tostring(form)
3006      assert_compile(not runtime_3f, "symbols may only be used at compile time", form)
3007      if (symstr:find("#$") or symstr:find("#[:.]")) then
3008        return string.format("sym('%s', {filename=%s, line=%s})", autogensym(symstr, scope), filename, (form.line or "nil"))
3009      else
3010        return string.format("sym('%s', {quoted=true, filename=%s, line=%s})", symstr, filename, (form.line or "nil"))
3011      end
3012    elseif (utils["list?"](form) and utils["sym?"](form[1]) and (tostring(form[1]) == "unquote")) then
3013      local payload = form[2]
3014      local res = unpack(compile1(payload, scope, parent))
3015      return res[1]
3016    elseif utils["list?"](form) then
3017      local mapped
3018      local function _337_()
3019        return nil
3020      end
3021      mapped = utils.kvmap(form, entry_transform(_337_, q))
3022      local filename
3023      if form.filename then
3024        filename = string.format("%q", form.filename)
3025      else
3026        filename = "nil"
3027      end
3028      assert_compile(not runtime_3f, "lists may only be used at compile time", form)
3029      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, ", "))
3030    elseif utils["sequence?"](form) then
3031      local mapped = utils.kvmap(form, entry_transform(q, q))
3032      local source = getmetatable(form)
3033      local filename
3034      if source.filename then
3035        filename = string.format("%q", source.filename)
3036      else
3037        filename = "nil"
3038      end
3039      local _340_
3040      if source then
3041        _340_ = source.line
3042      else
3043        _340_ = "nil"
3044      end
3045      return string.format("setmetatable({%s}, {filename=%s, line=%s, sequence=%s})", mixed_concat(mapped, ", "), filename, _340_, "(getmetatable(sequence()))['sequence']")
3046    elseif (type(form) == "table") then
3047      local mapped = utils.kvmap(form, entry_transform(q, q))
3048      local source = getmetatable(form)
3049      local filename
3050      if source.filename then
3051        filename = string.format("%q", source.filename)
3052      else
3053        filename = "nil"
3054      end
3055      local function _343_()
3056        if source then
3057          return source.line
3058        else
3059          return "nil"
3060        end
3061      end
3062      return string.format("setmetatable({%s}, {filename=%s, line=%s})", mixed_concat(mapped, ", "), filename, _343_())
3063    elseif (type(form) == "string") then
3064      return serialize_string(form)
3065    else
3066      return tostring(form)
3067    end
3068  end
3069  return {compile = compile, compile1 = compile1, ["compile-stream"] = compile_stream, ["compile-string"] = compile_string, 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}
3070end
3071package.preload["fennel.friend"] = package.preload["fennel.friend"] or function(...)
3072  local utils = require("fennel.utils")
3073  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"}, ["illegal 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"}, ["expected even number of pattern/body pairs"] = {"checking that every pattern has a body to go with it", "adding _ before the final body"}, ["unexpected arguments"] = {"removing an argument", "checking for typos"}, ["unexpected iterator clause"] = {"removing an argument", "checking for typos"}}
3074  local unpack = (table.unpack or _G.unpack)
3075  local function suggest(msg)
3076    local suggestion = nil
3077    for pat, sug in pairs(suggestions) do
3078      local matches = {msg:match(pat)}
3079      if (0 < #matches) then
3080        if ("table" == type(sug)) then
3081          local out = {}
3082          for _, s in ipairs(sug) do
3083            table.insert(out, s:format(unpack(matches)))
3084          end
3085          suggestion = out
3086        else
3087          suggestion = sug(matches)
3088        end
3089      else
3090      end
3091    end
3092    return suggestion
3093  end
3094  local function read_line_from_file(filename, line)
3095    local bytes = 0
3096    local f = assert(io.open(filename))
3097    local _
3098    for _0 = 1, (line - 1) do
3099      bytes = (bytes + 1 + #f:read())
3100    end
3101    _ = nil
3102    local codeline = f:read()
3103    f:close()
3104    return codeline, bytes
3105  end
3106  local function read_line_from_string(matcher, target_line, _3fcurrent_line, _3fbytes)
3107    local this_line, newline = matcher()
3108    local current_line = (_3fcurrent_line or 1)
3109    local bytes = ((_3fbytes or 0) + #this_line + #newline)
3110    if (target_line == current_line) then
3111      return this_line, (bytes - #this_line - 1)
3112    elseif this_line then
3113      return read_line_from_string(matcher, target_line, (current_line + 1), bytes)
3114    else
3115      return nil
3116    end
3117  end
3118  local function read_line(filename, line, source)
3119    if source then
3120      return read_line_from_string(string.gmatch((source .. "\n"), "(.-)(\13?\n)"), line)
3121    else
3122      return read_line_from_file(filename, line)
3123    end
3124  end
3125  local function friendly_msg(msg, _142_, source)
3126    local _arg_143_ = _142_
3127    local filename = _arg_143_["filename"]
3128    local line = _arg_143_["line"]
3129    local bytestart = _arg_143_["bytestart"]
3130    local byteend = _arg_143_["byteend"]
3131    local ok, codeline, bol = pcall(read_line, filename, line, source)
3132    local suggestions0 = suggest(msg)
3133    local out = {msg, ""}
3134    if (ok and codeline) then
3135      table.insert(out, codeline)
3136    else
3137    end
3138    if (ok and codeline and bytestart and byteend) then
3139      table.insert(out, (string.rep(" ", (bytestart - bol - 1)) .. "^" .. string.rep("^", math.min((byteend - bytestart), ((bol + #codeline) - bytestart)))))
3140    else
3141    end
3142    if (ok and codeline and bytestart and not byteend) then
3143      table.insert(out, (string.rep("-", (bytestart - bol - 1)) .. "^"))
3144      table.insert(out, "")
3145    else
3146    end
3147    if suggestions0 then
3148      for _, suggestion in ipairs(suggestions0) do
3149        table.insert(out, ("* Try %s."):format(suggestion))
3150      end
3151    else
3152    end
3153    return table.concat(out, "\n")
3154  end
3155  local function assert_compile(condition, msg, ast, source)
3156    if not condition then
3157      local _let_148_ = utils["ast-source"](ast)
3158      local filename = _let_148_["filename"]
3159      local line = _let_148_["line"]
3160      error(friendly_msg(("Compile error in %s:%s\n  %s"):format((filename or "unknown"), (line or "?"), msg), utils["ast-source"](ast), source), 0)
3161    else
3162    end
3163    return condition
3164  end
3165  local function parse_error(msg, filename, line, bytestart, source)
3166    return error(friendly_msg(("Parse error in %s:%s\n  %s"):format(filename, line, msg), {filename = filename, line = line, bytestart = bytestart}, source), 0)
3167  end
3168  return {["assert-compile"] = assert_compile, ["parse-error"] = parse_error}
3169end
3170package.preload["fennel.parser"] = package.preload["fennel.parser"] or function(...)
3171  local utils = require("fennel.utils")
3172  local friend = require("fennel.friend")
3173  local unpack = (table.unpack or _G.unpack)
3174  local function granulate(getchunk)
3175    local c, index, done_3f = "", 1, false
3176    local function _150_(parser_state)
3177      if not done_3f then
3178        if (index <= #c) then
3179          local b = c:byte(index)
3180          index = (index + 1)
3181          return b
3182        else
3183          local _151_ = getchunk(parser_state)
3184          local function _152_()
3185            local char = _151_
3186            return (char ~= "")
3187          end
3188          if ((nil ~= _151_) and _152_()) then
3189            local char = _151_
3190            c = char
3191            index = 2
3192            return c:byte()
3193          elseif true then
3194            local _ = _151_
3195            done_3f = true
3196            return nil
3197          else
3198            return nil
3199          end
3200        end
3201      else
3202        return nil
3203      end
3204    end
3205    local function _156_()
3206      c = ""
3207      return nil
3208    end
3209    return _150_, _156_
3210  end
3211  local function string_stream(str)
3212    local str0 = str:gsub("^#!", ";;")
3213    local index = 1
3214    local function _157_()
3215      local r = str0:byte(index)
3216      index = (index + 1)
3217      return r
3218    end
3219    return _157_
3220  end
3221  local delims = {[40] = 41, [41] = true, [91] = 93, [93] = true, [123] = 125, [125] = true}
3222  local function whitespace_3f(b)
3223    return ((b == 32) or ((b >= 9) and (b <= 13)))
3224  end
3225  local function sym_char_3f(b)
3226    local b0
3227    if ("number" == type(b)) then
3228      b0 = b
3229    else
3230      b0 = string.byte(b)
3231    end
3232    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))
3233  end
3234  local prefixes = {[35] = "hashfn", [39] = "quote", [44] = "unquote", [96] = "quote"}
3235  local function parser(getbyte, _3ffilename, _3foptions)
3236    local stack = {}
3237    local line = 1
3238    local byteindex = 0
3239    local lastb = nil
3240    local function ungetb(ub)
3241      if (ub == 10) then
3242        line = (line - 1)
3243      else
3244      end
3245      byteindex = (byteindex - 1)
3246      lastb = ub
3247      return nil
3248    end
3249    local function getb()
3250      local r = nil
3251      if lastb then
3252        r, lastb = lastb, nil
3253      else
3254        r = getbyte({["stack-size"] = #stack})
3255      end
3256      byteindex = (byteindex + 1)
3257      if (r == 10) then
3258        line = (line + 1)
3259      else
3260      end
3261      return r
3262    end
3263    assert(((nil == _3ffilename) or ("string" == type(_3ffilename))), "expected filename as second argument to parser")
3264    local function parse_error(msg, byteindex_override)
3265      local _let_162_ = (_3foptions or utils.root.options or {})
3266      local source = _let_162_["source"]
3267      local unfriendly = _let_162_["unfriendly"]
3268      if (nil == utils.hook("parse-error", msg, (_3ffilename or "unknown"), (line or "?"), (byteindex_override or byteindex), source, utils.root.reset)) then
3269        utils.root.reset()
3270        if (unfriendly or not friend or not _G.io or not _G.io.read) then
3271          return error(string.format("%s:%s: Parse error: %s", (_3ffilename or "unknown"), (line or "?"), msg), 0)
3272        else
3273          return friend["parse-error"](msg, (_3ffilename or "unknown"), (line or "?"), (byteindex_override or byteindex), source)
3274        end
3275      else
3276        return nil
3277      end
3278    end
3279    local function parse_stream()
3280      local whitespace_since_dispatch, done_3f, retval = true
3281      local function dispatch(v)
3282        local _165_ = stack[#stack]
3283        if (_165_ == nil) then
3284          retval, done_3f, whitespace_since_dispatch = v, true, false
3285          return nil
3286        elseif ((_G.type(_165_) == "table") and (nil ~= (_165_).prefix)) then
3287          local prefix = (_165_).prefix
3288          local source
3289          do
3290            local _166_ = table.remove(stack)
3291            do end (_166_)["byteend"] = byteindex
3292            source = _166_
3293          end
3294          local list = utils.list(utils.sym(prefix, source), v)
3295          for k, v0 in pairs(source) do
3296            list[k] = v0
3297          end
3298          return dispatch(list)
3299        elseif (nil ~= _165_) then
3300          local top = _165_
3301          whitespace_since_dispatch = false
3302          return table.insert(top, v)
3303        else
3304          return nil
3305        end
3306      end
3307      local function badend()
3308        local accum = utils.map(stack, "closer")
3309        local _168_
3310        if (#stack == 1) then
3311          _168_ = ""
3312        else
3313          _168_ = "s"
3314        end
3315        return parse_error(string.format("expected closing delimiter%s %s", _168_, string.char(unpack(accum))))
3316      end
3317      local function skip_whitespace(b)
3318        if (b and whitespace_3f(b)) then
3319          whitespace_since_dispatch = true
3320          return skip_whitespace(getb())
3321        elseif (not b and (#stack > 0)) then
3322          return badend()
3323        else
3324          return b
3325        end
3326      end
3327      local function parse_comment(b, contents)
3328        if (b and (10 ~= b)) then
3329          local function _172_()
3330            local _171_ = contents
3331            table.insert(_171_, string.char(b))
3332            return _171_
3333          end
3334          return parse_comment(getb(), _172_())
3335        elseif (_3foptions and _3foptions.comments) then
3336          return dispatch(utils.comment(table.concat(contents), {line = (line - 1), filename = _3ffilename}))
3337        else
3338          return b
3339        end
3340      end
3341      local function open_table(b)
3342        if not whitespace_since_dispatch then
3343          parse_error(("expected whitespace before opening delimiter " .. string.char(b)))
3344        else
3345        end
3346        return table.insert(stack, {bytestart = byteindex, closer = delims[b], filename = _3ffilename, line = line})
3347      end
3348      local function close_list(list)
3349        return dispatch(setmetatable(list, getmetatable(utils.list())))
3350      end
3351      local function close_sequence(tbl)
3352        local val = utils.sequence(unpack(tbl))
3353        for k, v in pairs(tbl) do
3354          getmetatable(val)[k] = v
3355        end
3356        return dispatch(val)
3357      end
3358      local function add_comment_at(comments, index, node)
3359        local _175_ = comments[index]
3360        if (nil ~= _175_) then
3361          local existing = _175_
3362          return table.insert(existing, node)
3363        elseif true then
3364          local _ = _175_
3365          comments[index] = {node}
3366          return nil
3367        else
3368          return nil
3369        end
3370      end
3371      local function next_noncomment(tbl, i)
3372        if utils["comment?"](tbl[i]) then
3373          return next_noncomment(tbl, (i + 1))
3374        else
3375          return tbl[i]
3376        end
3377      end
3378      local function extract_comments(tbl)
3379        local comments = {keys = {}, values = {}, last = {}}
3380        while utils["comment?"](tbl[#tbl]) do
3381          table.insert(comments.last, 1, table.remove(tbl))
3382        end
3383        local last_key_3f = false
3384        for i, node in ipairs(tbl) do
3385          if not utils["comment?"](node) then
3386            last_key_3f = not last_key_3f
3387          elseif last_key_3f then
3388            add_comment_at(comments.values, next_noncomment(tbl, i), node)
3389          else
3390            add_comment_at(comments.keys, next_noncomment(tbl, i), node)
3391          end
3392        end
3393        for i = #tbl, 1, -1 do
3394          if utils["comment?"](tbl[i]) then
3395            table.remove(tbl, i)
3396          else
3397          end
3398        end
3399        return comments
3400      end
3401      local function close_curly_table(tbl)
3402        local comments = extract_comments(tbl)
3403        local keys = {}
3404        local val = {}
3405        if ((#tbl % 2) ~= 0) then
3406          byteindex = (byteindex - 1)
3407          parse_error("expected even number of values in table literal")
3408        else
3409        end
3410        setmetatable(val, tbl)
3411        for i = 1, #tbl, 2 do
3412          if ((tostring(tbl[i]) == ":") and utils["sym?"](tbl[(i + 1)]) and utils["sym?"](tbl[i])) then
3413            tbl[i] = tostring(tbl[(i + 1)])
3414          else
3415          end
3416          val[tbl[i]] = tbl[(i + 1)]
3417          table.insert(keys, tbl[i])
3418        end
3419        tbl.comments = comments
3420        tbl.keys = keys
3421        return dispatch(val)
3422      end
3423      local function close_table(b)
3424        local top = table.remove(stack)
3425        if (top == nil) then
3426          parse_error(("unexpected closing delimiter " .. string.char(b)))
3427        else
3428        end
3429        if (top.closer and (top.closer ~= b)) then
3430          parse_error(("mismatched closing delimiter " .. string.char(b) .. ", expected " .. string.char(top.closer)))
3431        else
3432        end
3433        top.byteend = byteindex
3434        if (b == 41) then
3435          return close_list(top)
3436        elseif (b == 93) then
3437          return close_sequence(top)
3438        else
3439          return close_curly_table(top)
3440        end
3441      end
3442      local function parse_string_loop(chars, b, state)
3443        table.insert(chars, b)
3444        local state0
3445        do
3446          local _185_ = {state, b}
3447          if ((_G.type(_185_) == "table") and ((_185_)[1] == "base") and ((_185_)[2] == 92)) then
3448            state0 = "backslash"
3449          elseif ((_G.type(_185_) == "table") and ((_185_)[1] == "base") and ((_185_)[2] == 34)) then
3450            state0 = "done"
3451          elseif ((_G.type(_185_) == "table") and ((_185_)[1] == "backslash") and ((_185_)[2] == 10)) then
3452            table.remove(chars, (#chars - 1))
3453            state0 = "base"
3454          elseif true then
3455            local _ = _185_
3456            state0 = "base"
3457          else
3458            state0 = nil
3459          end
3460        end
3461        if (b and (state0 ~= "done")) then
3462          return parse_string_loop(chars, getb(), state0)
3463        else
3464          return b
3465        end
3466      end
3467      local function escape_char(c)
3468        return ({[7] = "\\a", [8] = "\\b", [9] = "\\t", [10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r"})[c:byte()]
3469      end
3470      local function parse_string()
3471        table.insert(stack, {closer = 34})
3472        local chars = {34}
3473        if not parse_string_loop(chars, getb(), "base") then
3474          badend()
3475        else
3476        end
3477        table.remove(stack)
3478        local raw = string.char(unpack(chars))
3479        local formatted = raw:gsub("[\7-\13]", escape_char)
3480        local _189_ = (rawget(_G, "loadstring") or load)(("return " .. formatted))
3481        if (nil ~= _189_) then
3482          local load_fn = _189_
3483          return dispatch(load_fn())
3484        elseif (_189_ == nil) then
3485          return parse_error(("Invalid string: " .. raw))
3486        else
3487          return nil
3488        end
3489      end
3490      local function parse_prefix(b)
3491        table.insert(stack, {prefix = prefixes[b], filename = _3ffilename, line = line, bytestart = byteindex})
3492        local nextb = getb()
3493        if (whitespace_3f(nextb) or (true == delims[nextb])) then
3494          if (b ~= 35) then
3495            parse_error("invalid whitespace after quoting prefix")
3496          else
3497          end
3498          table.remove(stack)
3499          dispatch(utils.sym("#"))
3500        else
3501        end
3502        return ungetb(nextb)
3503      end
3504      local function parse_sym_loop(chars, b)
3505        if (b and sym_char_3f(b)) then
3506          table.insert(chars, b)
3507          return parse_sym_loop(chars, getb())
3508        else
3509          if b then
3510            ungetb(b)
3511          else
3512          end
3513          return chars
3514        end
3515      end
3516      local function parse_number(rawstr)
3517        local number_with_stripped_underscores = (not rawstr:find("^_") and rawstr:gsub("_", ""))
3518        if rawstr:match("^%d") then
3519          dispatch((tonumber(number_with_stripped_underscores) or parse_error(("could not read number \"" .. rawstr .. "\""))))
3520          return true
3521        else
3522          local _195_ = tonumber(number_with_stripped_underscores)
3523          if (nil ~= _195_) then
3524            local x = _195_
3525            dispatch(x)
3526            return true
3527          elseif true then
3528            local _ = _195_
3529            return false
3530          else
3531            return nil
3532          end
3533        end
3534      end
3535      local function check_malformed_sym(rawstr)
3536        if (rawstr:match("^~") and (rawstr ~= "~=")) then
3537          return parse_error("illegal character: ~")
3538        elseif rawstr:match("%.[0-9]") then
3539          return parse_error(("can't start multisym segment with a digit: " .. rawstr), (((byteindex - #rawstr) + rawstr:find("%.[0-9]")) + 1))
3540        elseif (rawstr:match("[%.:][%.:]") and (rawstr ~= "..") and (rawstr ~= "$...")) then
3541          return parse_error(("malformed multisym: " .. rawstr), ((byteindex - #rawstr) + 1 + rawstr:find("[%.:][%.:]")))
3542        elseif ((rawstr ~= ":") and rawstr:match(":$")) then
3543          return parse_error(("malformed multisym: " .. rawstr), ((byteindex - #rawstr) + 1 + rawstr:find(":$")))
3544        elseif rawstr:match(":.+[%.:]") then
3545          return parse_error(("method must be last component of multisym: " .. rawstr), ((byteindex - #rawstr) + rawstr:find(":.+[%.:]")))
3546        else
3547          return rawstr
3548        end
3549      end
3550      local function parse_sym(b)
3551        local bytestart = byteindex
3552        local rawstr = string.char(unpack(parse_sym_loop({b}, getb())))
3553        if (rawstr == "true") then
3554          return dispatch(true)
3555        elseif (rawstr == "false") then
3556          return dispatch(false)
3557        elseif (rawstr == "...") then
3558          return dispatch(utils.varg())
3559        elseif rawstr:match("^:.+$") then
3560          return dispatch(rawstr:sub(2))
3561        elseif not parse_number(rawstr) then
3562          return dispatch(utils.sym(check_malformed_sym(rawstr), {byteend = byteindex, bytestart = bytestart, filename = _3ffilename, line = line}))
3563        else
3564          return nil
3565        end
3566      end
3567      local function parse_loop(b)
3568        if not b then
3569        elseif (b == 59) then
3570          parse_comment(getb(), {";"})
3571        elseif (type(delims[b]) == "number") then
3572          open_table(b)
3573        elseif delims[b] then
3574          close_table(b)
3575        elseif (b == 34) then
3576          parse_string(b)
3577        elseif prefixes[b] then
3578          parse_prefix(b)
3579        elseif (sym_char_3f(b) or (b == string.byte("~"))) then
3580          parse_sym(b)
3581        elseif not utils.hook("illegal-char", b, getb, ungetb, dispatch) then
3582          parse_error(("illegal character: " .. string.char(b)))
3583        else
3584        end
3585        if not b then
3586          return nil
3587        elseif done_3f then
3588          return true, retval
3589        else
3590          return parse_loop(skip_whitespace(getb()))
3591        end
3592      end
3593      return parse_loop(skip_whitespace(getb()))
3594    end
3595    local function _202_()
3596      stack, line, byteindex, lastb = {}, 1, 0, nil
3597      return nil
3598    end
3599    return parse_stream, _202_
3600  end
3601  return {granulate = granulate, parser = parser, ["string-stream"] = string_stream, ["sym-char?"] = sym_char_3f}
3602end
3603local utils
3604package.preload["fennel.view"] = package.preload["fennel.view"] or function(...)
3605  local type_order = {number = 1, boolean = 2, string = 3, table = 4, ["function"] = 5, userdata = 6, thread = 7}
3606  local lua_pairs = pairs
3607  local lua_ipairs = ipairs
3608  local function pairs(t)
3609    local _1_ = getmetatable(t)
3610    if ((_G.type(_1_) == "table") and (nil ~= (_1_).__pairs)) then
3611      local p = (_1_).__pairs
3612      return p(t)
3613    elseif true then
3614      local _ = _1_
3615      return lua_pairs(t)
3616    else
3617      return nil
3618    end
3619  end
3620  local function ipairs(t)
3621    local _3_ = getmetatable(t)
3622    if ((_G.type(_3_) == "table") and (nil ~= (_3_).__ipairs)) then
3623      local i = (_3_).__ipairs
3624      return i(t)
3625    elseif true then
3626      local _ = _3_
3627      return lua_ipairs(t)
3628    else
3629      return nil
3630    end
3631  end
3632  local function length_2a(t)
3633    local _5_ = getmetatable(t)
3634    if ((_G.type(_5_) == "table") and (nil ~= (_5_).__len)) then
3635      local l = (_5_).__len
3636      return l(t)
3637    elseif true then
3638      local _ = _5_
3639      return #t
3640    else
3641      return nil
3642    end
3643  end
3644  local function sort_keys(_7_, _9_)
3645    local _arg_8_ = _7_
3646    local a = _arg_8_[1]
3647    local _arg_10_ = _9_
3648    local b = _arg_10_[1]
3649    local ta = type(a)
3650    local tb = type(b)
3651    if ((ta == tb) and ((ta == "string") or (ta == "number"))) then
3652      return (a < b)
3653    else
3654      local dta = type_order[ta]
3655      local dtb = type_order[tb]
3656      if (dta and dtb) then
3657        return (dta < dtb)
3658      elseif dta then
3659        return true
3660      elseif dtb then
3661        return false
3662      else
3663        return (ta < tb)
3664      end
3665    end
3666  end
3667  local function max_index_gap(kv)
3668    local gap = 0
3669    if (length_2a(kv) > 0) then
3670      local i = 0
3671      for _, _13_ in ipairs(kv) do
3672        local _each_14_ = _13_
3673        local k = _each_14_[1]
3674        if ((k - i) > gap) then
3675          gap = (k - i)
3676        else
3677        end
3678        i = k
3679      end
3680    else
3681    end
3682    return gap
3683  end
3684  local function fill_gaps(kv)
3685    local missing_indexes = {}
3686    local i = 0
3687    for _, _17_ in ipairs(kv) do
3688      local _each_18_ = _17_
3689      local j = _each_18_[1]
3690      i = (i + 1)
3691      while (i < j) do
3692        table.insert(missing_indexes, i)
3693        i = (i + 1)
3694      end
3695    end
3696    for _, k in ipairs(missing_indexes) do
3697      table.insert(kv, k, {k})
3698    end
3699    return nil
3700  end
3701  local function table_kv_pairs(t, options)
3702    local assoc_3f = false
3703    local kv = {}
3704    local insert = table.insert
3705    for k, v in pairs(t) do
3706      if ((type(k) ~= "number") or (k < 1)) then
3707        assoc_3f = true
3708      else
3709      end
3710      insert(kv, {k, v})
3711    end
3712    table.sort(kv, sort_keys)
3713    if not assoc_3f then
3714      if (max_index_gap(kv) > options["max-sparse-gap"]) then
3715        assoc_3f = true
3716      else
3717        fill_gaps(kv)
3718      end
3719    else
3720    end
3721    if (length_2a(kv) == 0) then
3722      return kv, "empty"
3723    else
3724      local function _22_()
3725        if assoc_3f then
3726          return "table"
3727        else
3728          return "seq"
3729        end
3730      end
3731      return kv, _22_()
3732    end
3733  end
3734  local function count_table_appearances(t, appearances)
3735    if (type(t) == "table") then
3736      if not appearances[t] then
3737        appearances[t] = 1
3738        for k, v in pairs(t) do
3739          count_table_appearances(k, appearances)
3740          count_table_appearances(v, appearances)
3741        end
3742      else
3743        appearances[t] = ((appearances[t] or 0) + 1)
3744      end
3745    else
3746    end
3747    return appearances
3748  end
3749  local function save_table(t, seen)
3750    local seen0 = (seen or {len = 0})
3751    local id = (seen0.len + 1)
3752    if not (seen0)[t] then
3753      seen0[t] = id
3754      seen0.len = id
3755    else
3756    end
3757    return seen0
3758  end
3759  local function detect_cycle(t, seen, _3fk)
3760    if ("table" == type(t)) then
3761      seen[t] = true
3762      local _27_, _28_ = next(t, _3fk)
3763      if ((nil ~= _27_) and (nil ~= _28_)) then
3764        local k = _27_
3765        local v = _28_
3766        return (seen[k] or detect_cycle(k, seen) or seen[v] or detect_cycle(v, seen) or detect_cycle(t, seen, k))
3767      else
3768        return nil
3769      end
3770    else
3771      return nil
3772    end
3773  end
3774  local function visible_cycle_3f(t, options)
3775    return (options["detect-cycles?"] and detect_cycle(t, {}) and save_table(t, options.seen) and (1 < (options.appearances[t] or 0)))
3776  end
3777  local function table_indent(indent, id)
3778    local opener_length
3779    if id then
3780      opener_length = (length_2a(tostring(id)) + 2)
3781    else
3782      opener_length = 1
3783    end
3784    return (indent + opener_length)
3785  end
3786  local pp = nil
3787  local function concat_table_lines(elements, options, multiline_3f, indent, table_type, prefix)
3788    local indent_str = ("\n" .. string.rep(" ", indent))
3789    local open
3790    local function _32_()
3791      if ("seq" == table_type) then
3792        return "["
3793      else
3794        return "{"
3795      end
3796    end
3797    open = ((prefix or "") .. _32_())
3798    local close
3799    if ("seq" == table_type) then
3800      close = "]"
3801    else
3802      close = "}"
3803    end
3804    local oneline = (open .. table.concat(elements, " ") .. close)
3805    if (not options["one-line?"] and (multiline_3f or ((indent + length_2a(oneline)) > options["line-length"]))) then
3806      return (open .. table.concat(elements, indent_str) .. close)
3807    else
3808      return oneline
3809    end
3810  end
3811  local function utf8_len(x)
3812    local n = 0
3813    for _ in string.gmatch(x, "[%z\1-\127\192-\247]") do
3814      n = (n + 1)
3815    end
3816    return n
3817  end
3818  local function pp_associative(t, kv, options, indent)
3819    local multiline_3f = false
3820    local id = options.seen[t]
3821    if (options.level >= options.depth) then
3822      return "{...}"
3823    elseif (id and options["detect-cycles?"]) then
3824      return ("@" .. id .. "{...}")
3825    else
3826      local visible_cycle_3f0 = visible_cycle_3f(t, options)
3827      local id0 = (visible_cycle_3f0 and options.seen[t])
3828      local indent0 = table_indent(indent, id0)
3829      local slength
3830      if options["utf8?"] then
3831        slength = utf8_len
3832      else
3833        local function _35_(_241)
3834          return #_241
3835        end
3836        slength = _35_
3837      end
3838      local prefix
3839      if visible_cycle_3f0 then
3840        prefix = ("@" .. id0)
3841      else
3842        prefix = ""
3843      end
3844      local items
3845      do
3846        local tbl_14_auto = {}
3847        local i_15_auto = #tbl_14_auto
3848        for _, _38_ in pairs(kv) do
3849          local _each_39_ = _38_
3850          local k = _each_39_[1]
3851          local v = _each_39_[2]
3852          local val_16_auto
3853          do
3854            local k0 = pp(k, options, (indent0 + 1), true)
3855            local v0 = pp(v, options, (indent0 + slength(k0) + 1))
3856            multiline_3f = (multiline_3f or k0:find("\n") or v0:find("\n"))
3857            val_16_auto = (k0 .. " " .. v0)
3858          end
3859          if (nil ~= val_16_auto) then
3860            i_15_auto = (i_15_auto + 1)
3861            do end (tbl_14_auto)[i_15_auto] = val_16_auto
3862          else
3863          end
3864        end
3865        items = tbl_14_auto
3866      end
3867      return concat_table_lines(items, options, multiline_3f, indent0, "table", prefix)
3868    end
3869  end
3870  local function pp_sequence(t, kv, options, indent)
3871    local multiline_3f = false
3872    local id = options.seen[t]
3873    if (options.level >= options.depth) then
3874      return "[...]"
3875    elseif (id and options["detect-cycles?"]) then
3876      return ("@" .. id .. "[...]")
3877    else
3878      local visible_cycle_3f0 = visible_cycle_3f(t, options)
3879      local id0 = (visible_cycle_3f0 and options.seen[t])
3880      local indent0 = table_indent(indent, id0)
3881      local prefix
3882      if visible_cycle_3f0 then
3883        prefix = ("@" .. id0)
3884      else
3885        prefix = ""
3886      end
3887      local items
3888      do
3889        local tbl_14_auto = {}
3890        local i_15_auto = #tbl_14_auto
3891        for _, _43_ in pairs(kv) do
3892          local _each_44_ = _43_
3893          local _0 = _each_44_[1]
3894          local v = _each_44_[2]
3895          local val_16_auto
3896          do
3897            local v0 = pp(v, options, indent0)
3898            multiline_3f = (multiline_3f or v0:find("\n"))
3899            val_16_auto = v0
3900          end
3901          if (nil ~= val_16_auto) then
3902            i_15_auto = (i_15_auto + 1)
3903            do end (tbl_14_auto)[i_15_auto] = val_16_auto
3904          else
3905          end
3906        end
3907        items = tbl_14_auto
3908      end
3909      return concat_table_lines(items, options, multiline_3f, indent0, "seq", prefix)
3910    end
3911  end
3912  local function concat_lines(lines, options, indent, force_multi_line_3f)
3913    if (length_2a(lines) == 0) then
3914      if options["empty-as-sequence?"] then
3915        return "[]"
3916      else
3917        return "{}"
3918      end
3919    else
3920      local oneline
3921      local _48_
3922      do
3923        local tbl_14_auto = {}
3924        local i_15_auto = #tbl_14_auto
3925        for _, line in ipairs(lines) do
3926          local val_16_auto = line:gsub("^%s+", "")
3927          if (nil ~= val_16_auto) then
3928            i_15_auto = (i_15_auto + 1)
3929            do end (tbl_14_auto)[i_15_auto] = val_16_auto
3930          else
3931          end
3932        end
3933        _48_ = tbl_14_auto
3934      end
3935      oneline = table.concat(_48_, " ")
3936      if (not options["one-line?"] and (force_multi_line_3f or oneline:find("\n") or ((indent + length_2a(oneline)) > options["line-length"]))) then
3937        return table.concat(lines, ("\n" .. string.rep(" ", indent)))
3938      else
3939        return oneline
3940      end
3941    end
3942  end
3943  local function pp_metamethod(t, metamethod, options, indent)
3944    if (options.level >= options.depth) then
3945      if options["empty-as-sequence?"] then
3946        return "[...]"
3947      else
3948        return "{...}"
3949      end
3950    else
3951      local _
3952      local function _53_(_241)
3953        return visible_cycle_3f(_241, options)
3954      end
3955      options["visible-cycle?"] = _53_
3956      _ = nil
3957      local lines, force_multi_line_3f = metamethod(t, pp, options, indent)
3958      options["visible-cycle?"] = nil
3959      local _54_ = type(lines)
3960      if (_54_ == "string") then
3961        return lines
3962      elseif (_54_ == "table") then
3963        return concat_lines(lines, options, indent, force_multi_line_3f)
3964      elseif true then
3965        local _0 = _54_
3966        return error("__fennelview metamethod must return a table of lines")
3967      else
3968        return nil
3969      end
3970    end
3971  end
3972  local function pp_table(x, options, indent)
3973    options.level = (options.level + 1)
3974    local x0
3975    do
3976      local _57_
3977      if options["metamethod?"] then
3978        local _58_ = x
3979        if (nil ~= _58_) then
3980          local _59_ = getmetatable(_58_)
3981          if (nil ~= _59_) then
3982            _57_ = (_59_).__fennelview
3983          else
3984            _57_ = _59_
3985          end
3986        else
3987          _57_ = _58_
3988        end
3989      else
3990        _57_ = nil
3991      end
3992      if (nil ~= _57_) then
3993        local metamethod = _57_
3994        x0 = pp_metamethod(x, metamethod, options, indent)
3995      elseif true then
3996        local _ = _57_
3997        local _63_, _64_ = table_kv_pairs(x, options)
3998        if (true and (_64_ == "empty")) then
3999          local _0 = _63_
4000          if options["empty-as-sequence?"] then
4001            x0 = "[]"
4002          else
4003            x0 = "{}"
4004          end
4005        elseif ((nil ~= _63_) and (_64_ == "table")) then
4006          local kv = _63_
4007          x0 = pp_associative(x, kv, options, indent)
4008        elseif ((nil ~= _63_) and (_64_ == "seq")) then
4009          local kv = _63_
4010          x0 = pp_sequence(x, kv, options, indent)
4011        else
4012          x0 = nil
4013        end
4014      else
4015        x0 = nil
4016      end
4017    end
4018    options.level = (options.level - 1)
4019    return x0
4020  end
4021  local function number__3estring(n)
4022    local _68_ = string.gsub(tostring(n), ",", ".")
4023    return _68_
4024  end
4025  local function colon_string_3f(s)
4026    return s:find("^[-%w?^_!$%&*+./@|<=>]+$")
4027  end
4028  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}}
4029  local function utf8_escape(str)
4030    local function validate_utf8(str0, index)
4031      local inits = utf8_inits
4032      local byte = string.byte(str0, index)
4033      local init
4034      do
4035        local ret = nil
4036        for _, init0 in ipairs(inits) do
4037          if ret then break end
4038          ret = (byte and (function(_69_,_70_,_71_) return (_69_ >= _70_) and (_70_ >= _71_) end)(init0["max-byte"],byte,init0["min-byte"]) and init0)
4039        end
4040        init = ret
4041      end
4042      local code
4043      local function _72_()
4044        local code0
4045        if init then
4046          code0 = (byte - init["min-byte"])
4047        else
4048          code0 = nil
4049        end
4050        for i = (index + 1), (index + init.len + -1) do
4051          local byte0 = string.byte(str0, i)
4052          code0 = (byte0 and code0 and (function(_74_,_75_,_76_) return (_74_ >= _75_) and (_75_ >= _76_) end)(191,byte0,128) and ((code0 * 64) + (byte0 - 128)))
4053        end
4054        return code0
4055      end
4056      code = (init and _72_())
4057      if (code and (function(_77_,_78_,_79_) return (_77_ >= _78_) and (_78_ >= _79_) end)(init["max-code"],code,init["min-code"]) and not (function(_80_,_81_,_82_) return (_80_ >= _81_) and (_81_ >= _82_) end)(57343,code,55296)) then
4058        return init.len
4059      else
4060        return nil
4061      end
4062    end
4063    local index = 1
4064    local output = {}
4065    while (index <= #str) do
4066      local nexti = (string.find(str, "[\128-\255]", index) or (#str + 1))
4067      local len = validate_utf8(str, nexti)
4068      table.insert(output, string.sub(str, index, (nexti + (len or 0) + -1)))
4069      if (not len and (nexti <= #str)) then
4070        table.insert(output, string.format("\\%03d", string.byte(str, nexti)))
4071      else
4072      end
4073      if len then
4074        index = (nexti + len)
4075      else
4076        index = (nexti + 1)
4077      end
4078    end
4079    return table.concat(output)
4080  end
4081  local function pp_string(str, options, indent)
4082    local escs
4083    local _86_
4084    if (options["escape-newlines?"] and (length_2a(str) < (options["line-length"] - indent))) then
4085      _86_ = "\\n"
4086    else
4087      _86_ = "\n"
4088    end
4089    local function _88_(_241, _242)
4090      return ("\\%03d"):format(_242:byte())
4091    end
4092    escs = setmetatable({["\7"] = "\\a", ["\8"] = "\\b", ["\12"] = "\\f", ["\11"] = "\\v", ["\13"] = "\\r", ["\9"] = "\\t", ["\\"] = "\\\\", ["\""] = "\\\"", ["\n"] = _86_}, {__index = _88_})
4093    local str0 = ("\"" .. str:gsub("[%c\\\"]", escs) .. "\"")
4094    if options["utf8?"] then
4095      return utf8_escape(str0)
4096    else
4097      return str0
4098    end
4099  end
4100  local function make_options(t, options)
4101    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}
4102    local overrides = {level = 0, appearances = count_table_appearances(t, {}), seen = {len = 0}}
4103    for k, v in pairs((options or {})) do
4104      defaults[k] = v
4105    end
4106    for k, v in pairs(overrides) do
4107      defaults[k] = v
4108    end
4109    return defaults
4110  end
4111  local function _90_(x, options, indent, colon_3f)
4112    local indent0 = (indent or 0)
4113    local options0 = (options or make_options(x))
4114    local x0
4115    if options0.preprocess then
4116      x0 = options0.preprocess(x, options0)
4117    else
4118      x0 = x
4119    end
4120    local tv = type(x0)
4121    local function _93_()
4122      local _92_ = getmetatable(x0)
4123      if (nil ~= _92_) then
4124        return (_92_).__fennelview
4125      else
4126        return _92_
4127      end
4128    end
4129    if ((tv == "table") or ((tv == "userdata") and _93_())) then
4130      return pp_table(x0, options0, indent0)
4131    elseif (tv == "number") then
4132      return number__3estring(x0)
4133    else
4134      local function _95_()
4135        if (colon_3f ~= nil) then
4136          return colon_3f
4137        elseif ("function" == type(options0["prefer-colon?"])) then
4138          return options0["prefer-colon?"](x0)
4139        else
4140          return options0["prefer-colon?"]
4141        end
4142      end
4143      if ((tv == "string") and colon_string_3f(x0) and _95_()) then
4144        return (":" .. x0)
4145      elseif (tv == "string") then
4146        return pp_string(x0, options0, indent0)
4147      elseif ((tv == "boolean") or (tv == "nil")) then
4148        return tostring(x0)
4149      else
4150        return ("#<" .. tostring(x0) .. ">")
4151      end
4152    end
4153  end
4154  pp = _90_
4155  local function view(x, _3foptions)
4156    return pp(x, make_options(x, _3foptions), 0)
4157  end
4158  return view
4159end
4160package.preload["fennel.utils"] = package.preload["fennel.utils"] or function(...)
4161  local view = require("fennel.view")
4162  local version = "1.0.0-dev"
4163  local function warn(message)
4164    if (_G.io and _G.io.stderr) then
4165      return (_G.io.stderr):write(("--WARNING: %s\n"):format(tostring(message)))
4166    else
4167      return nil
4168    end
4169  end
4170  local function stablepairs(t)
4171    local keys = {}
4172    local used_keys = {}
4173    local succ = {}
4174    if (getmetatable(t) and getmetatable(t).keys) then
4175      for _, k in ipairs(getmetatable(t).keys) do
4176        if used_keys[k] then
4177          for i = #keys, 1, -1 do
4178            if (keys[i] == k) then
4179              table.remove(keys, i)
4180            else
4181            end
4182          end
4183        else
4184        end
4185        used_keys[k] = true
4186        table.insert(keys, k)
4187      end
4188    else
4189      for k in pairs(t) do
4190        table.insert(keys, k)
4191      end
4192      local function _100_(_241, _242)
4193        return (tostring(_241) < tostring(_242))
4194      end
4195      table.sort(keys, _100_)
4196    end
4197    for i, k in ipairs(keys) do
4198      succ[k] = keys[(i + 1)]
4199    end
4200    local function stablenext(tbl, idx)
4201      local key
4202      if (idx == nil) then
4203        key = keys[1]
4204      else
4205        key = succ[idx]
4206      end
4207      local value
4208      if (key == nil) then
4209        value = nil
4210      else
4211        value = tbl[key]
4212      end
4213      return key, value
4214    end
4215    return stablenext, t, nil
4216  end
4217  local function map(t, f, _3fout)
4218    local out = (_3fout or {})
4219    local f0
4220    if (type(f) == "function") then
4221      f0 = f
4222    else
4223      local function _104_(_241)
4224        return (_241)[f]
4225      end
4226      f0 = _104_
4227    end
4228    for _, x in ipairs(t) do
4229      local _106_ = f0(x)
4230      if (nil ~= _106_) then
4231        local v = _106_
4232        table.insert(out, v)
4233      else
4234      end
4235    end
4236    return out
4237  end
4238  local function kvmap(t, f, _3fout)
4239    local out = (_3fout or {})
4240    local f0
4241    if (type(f) == "function") then
4242      f0 = f
4243    else
4244      local function _108_(_241)
4245        return (_241)[f]
4246      end
4247      f0 = _108_
4248    end
4249    for k, x in stablepairs(t) do
4250      local _110_, _111_ = f0(k, x)
4251      if ((nil ~= _110_) and (nil ~= _111_)) then
4252        local key = _110_
4253        local value = _111_
4254        out[key] = value
4255      elseif (nil ~= _110_) then
4256        local value = _110_
4257        table.insert(out, value)
4258      else
4259      end
4260    end
4261    return out
4262  end
4263  local function copy(from, _3fto)
4264    local to = (_3fto or {})
4265    for k, v in pairs((from or {})) do
4266      to[k] = v
4267    end
4268    return to
4269  end
4270  local function member_3f(x, tbl, _3fn)
4271    local _113_ = tbl[(_3fn or 1)]
4272    if (_113_ == x) then
4273      return true
4274    elseif (_113_ == nil) then
4275      return nil
4276    elseif true then
4277      local _ = _113_
4278      return member_3f(x, tbl, ((_3fn or 1) + 1))
4279    else
4280      return nil
4281    end
4282  end
4283  local function allpairs(tbl)
4284    assert((type(tbl) == "table"), "allpairs expects a table")
4285    local t = tbl
4286    local seen = {}
4287    local function allpairs_next(_, state)
4288      local next_state, value = next(t, state)
4289      if seen[next_state] then
4290        return allpairs_next(nil, next_state)
4291      elseif next_state then
4292        seen[next_state] = true
4293        return next_state, value
4294      else
4295        local _115_ = getmetatable(t)
4296        if ((_G.type(_115_) == "table") and true) then
4297          local __index = (_115_).__index
4298          if ("table" == type(__index)) then
4299            t = __index
4300            return allpairs_next(t)
4301          else
4302            return nil
4303          end
4304        else
4305          return nil
4306        end
4307      end
4308    end
4309    return allpairs_next
4310  end
4311  local function deref(self)
4312    return self[1]
4313  end
4314  local nil_sym = nil
4315  local function list__3estring(self, _3ftostring2)
4316    local safe, max = {}, 0
4317    for k in pairs(self) do
4318      if ((type(k) == "number") and (k > max)) then
4319        max = k
4320      else
4321      end
4322    end
4323    for i = 1, max do
4324      safe[i] = (((self[i] == nil) and nil_sym) or self[i])
4325    end
4326    return ("(" .. table.concat(map(safe, (_3ftostring2 or view)), " ", 1, max) .. ")")
4327  end
4328  local function comment_view(c)
4329    return c, true
4330  end
4331  local function sym_3d(a, b)
4332    return ((deref(a) == deref(b)) and (getmetatable(a) == getmetatable(b)))
4333  end
4334  local function sym_3c(a, b)
4335    return (a[1] < tostring(b))
4336  end
4337  local symbol_mt = {__fennelview = deref, __tostring = deref, __eq = sym_3d, __lt = sym_3c, "SYMBOL"}
4338  local expr_mt
4339  local function _120_(x)
4340    return tostring(deref(x))
4341  end
4342  expr_mt = {__tostring = _120_, "EXPR"}
4343  local list_mt = {__fennelview = list__3estring, __tostring = list__3estring, "LIST"}
4344  local comment_mt = {__fennelview = comment_view, __tostring = deref, __eq = sym_3d, __lt = sym_3c, "COMMENT"}
4345  local sequence_marker = {"SEQUENCE"}
4346  local vararg = setmetatable({"..."}, {__fennelview = deref, __tostring = deref, "VARARG"})
4347  local getenv
4348  local function _121_()
4349    return nil
4350  end
4351  getenv = ((os and os.getenv) or _121_)
4352  local function debug_on_3f(flag)
4353    local level = (getenv("FENNEL_DEBUG") or "")
4354    return ((level == "all") or level:find(flag))
4355  end
4356  local function list(...)
4357    return setmetatable({...}, list_mt)
4358  end
4359  local function sym(str, _3fsource, _3fscope)
4360    local s = {["?scope"] = _3fscope, str}
4361    for k, v in pairs((_3fsource or {})) do
4362      if (type(k) == "string") then
4363        s[k] = v
4364      else
4365      end
4366    end
4367    return setmetatable(s, symbol_mt)
4368  end
4369  nil_sym = sym("nil")
4370  local function sequence(...)
4371    return setmetatable({...}, {sequence = sequence_marker})
4372  end
4373  local function expr(strcode, etype)
4374    return setmetatable({type = etype, strcode}, expr_mt)
4375  end
4376  local function comment_2a(contents, _3fsource)
4377    local _let_123_ = (_3fsource or {})
4378    local filename = _let_123_["filename"]
4379    local line = _let_123_["line"]
4380    return setmetatable({filename = filename, line = line, contents}, comment_mt)
4381  end
4382  local function varg()
4383    return vararg
4384  end
4385  local function expr_3f(x)
4386    return ((type(x) == "table") and (getmetatable(x) == expr_mt) and x)
4387  end
4388  local function varg_3f(x)
4389    return ((x == vararg) and x)
4390  end
4391  local function list_3f(x)
4392    return ((type(x) == "table") and (getmetatable(x) == list_mt) and x)
4393  end
4394  local function sym_3f(x)
4395    return ((type(x) == "table") and (getmetatable(x) == symbol_mt) and x)
4396  end
4397  local function sequence_3f(x)
4398    local mt = ((type(x) == "table") and getmetatable(x))
4399    return (mt and (mt.sequence == sequence_marker) and x)
4400  end
4401  local function comment_3f(x)
4402    return ((type(x) == "table") and (getmetatable(x) == comment_mt) and x)
4403  end
4404  local function table_3f(x)
4405    return ((type(x) == "table") and (x ~= vararg) and (getmetatable(x) ~= list_mt) and (getmetatable(x) ~= symbol_mt) and not comment_3f(x) and x)
4406  end
4407  local function multi_sym_3f(str)
4408    if sym_3f(str) then
4409      return multi_sym_3f(tostring(str))
4410    elseif (type(str) ~= "string") then
4411      return false
4412    else
4413      local parts = {}
4414      for part in str:gmatch("[^%.%:]+[%.%:]?") do
4415        local last_char = part:sub(( - 1))
4416        if (last_char == ":") then
4417          parts["multi-sym-method-call"] = true
4418        else
4419        end
4420        if ((last_char == ":") or (last_char == ".")) then
4421          parts[(#parts + 1)] = part:sub(1, ( - 2))
4422        else
4423          parts[(#parts + 1)] = part
4424        end
4425      end
4426      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)
4427    end
4428  end
4429  local function quoted_3f(symbol)
4430    return symbol.quoted
4431  end
4432  local function ast_source(ast)
4433    if table_3f(ast) then
4434      return (getmetatable(ast) or {})
4435    elseif ("table" == type(ast)) then
4436      return ast
4437    else
4438      return {}
4439    end
4440  end
4441  local function walk_tree(root, f, _3fcustom_iterator)
4442    local function walk(iterfn, parent, idx, node)
4443      if f(idx, node, parent) then
4444        for k, v in iterfn(node) do
4445          walk(iterfn, node, k, v)
4446        end
4447        return nil
4448      else
4449        return nil
4450      end
4451    end
4452    walk((_3fcustom_iterator or pairs), nil, nil, root)
4453    return root
4454  end
4455  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"}
4456  for i, v in ipairs(lua_keywords) do
4457    lua_keywords[v] = i
4458  end
4459  local function valid_lua_identifier_3f(str)
4460    return (str:match("^[%a_][%w_]*$") and not lua_keywords[str])
4461  end
4462  local propagated_options = {"allowedGlobals", "indent", "correlate", "useMetadata", "env", "compiler-env", "compilerEnv"}
4463  local function propagate_options(options, subopts)
4464    for _, name in ipairs(propagated_options) do
4465      subopts[name] = options[name]
4466    end
4467    return subopts
4468  end
4469  local root
4470  local function _129_()
4471  end
4472  root = {chunk = nil, scope = nil, options = nil, reset = _129_}
4473  root["set-reset"] = function(_130_)
4474    local _arg_131_ = _130_
4475    local chunk = _arg_131_["chunk"]
4476    local scope = _arg_131_["scope"]
4477    local options = _arg_131_["options"]
4478    local reset = _arg_131_["reset"]
4479    root.reset = function()
4480      root.chunk, root.scope, root.options, root.reset = chunk, scope, options, reset
4481      return nil
4482    end
4483    return root.reset
4484  end
4485  local warned = {}
4486  local function check_plugin_version(_132_)
4487    local _arg_133_ = _132_
4488    local name = _arg_133_["name"]
4489    local versions = _arg_133_["versions"]
4490    local plugin = _arg_133_
4491    if (not member_3f(version:gsub("-dev", ""), (versions or {})) and not warned[plugin]) then
4492      warned[plugin] = true
4493      return warn(string.format("plugin %s does not support Fennel version %s", (name or "unknown"), version))
4494    else
4495      return nil
4496    end
4497  end
4498  local function hook(event, ...)
4499    local result = nil
4500    if (root.options and root.options.plugins) then
4501      for _, plugin in ipairs(root.options.plugins) do
4502        if result then break end
4503        check_plugin_version(plugin)
4504        local _135_ = plugin[event]
4505        if (nil ~= _135_) then
4506          local f = _135_
4507          result = f(...)
4508        else
4509        end
4510      end
4511    else
4512    end
4513    return result
4514  end
4515  return {warn = warn, allpairs = allpairs, stablepairs = stablepairs, copy = copy, 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, ["valid-lua-identifier?"] = valid_lua_identifier_3f, ["lua-keywords"] = lua_keywords, hook = hook, ["propagate-options"] = propagate_options, root = root, ["debug-on?"] = debug_on_3f, ["ast-source"] = ast_source, version = version, path = table.concat({"./?.fnl", "./?/init.fnl", getenv("FENNEL_PATH")}, ";"), ["macro-path"] = table.concat({"./?.fnl", "./?/init-macros.fnl", "./?/init.fnl", getenv("FENNEL_MACRO_PATH")}, ";")}
4516end
4517utils = require("fennel.utils")
4518local parser = require("fennel.parser")
4519local compiler = require("fennel.compiler")
4520local specials = require("fennel.specials")
4521local repl = require("fennel.repl")
4522local view = require("fennel.view")
4523local function eval_env(env, opts)
4524  if (env == "_COMPILER") then
4525    local env0 = specials["make-compiler-env"](nil, compiler.scopes.compiler, {}, opts)
4526    if (opts.allowedGlobals == nil) then
4527      opts.allowedGlobals = specials["current-global-names"](env0)
4528    else
4529    end
4530    return specials["wrap-env"](env0)
4531  else
4532    return (env and specials["wrap-env"](env))
4533  end
4534end
4535local function eval_opts(options, str)
4536  local opts = utils.copy(options)
4537  if (opts.allowedGlobals == nil) then
4538    opts.allowedGlobals = specials["current-global-names"](opts.env)
4539  else
4540  end
4541  if (not opts.filename and not opts.source) then
4542    opts.source = str
4543  else
4544  end
4545  if (opts.env == "_COMPILER") then
4546    opts.scope = compiler["make-scope"](compiler.scopes.compiler)
4547  else
4548  end
4549  return opts
4550end
4551local function eval(str, options, ...)
4552  local opts = eval_opts(options, str)
4553  local env = eval_env(opts.env, opts)
4554  local lua_source = compiler["compile-string"](str, opts)
4555  local loader
4556  local function _618_(...)
4557    if opts.filename then
4558      return ("@" .. opts.filename)
4559    else
4560      return str
4561    end
4562  end
4563  loader = specials["load-code"](lua_source, env, _618_(...))
4564  opts.filename = nil
4565  return loader(...)
4566end
4567local function dofile_2a(filename, options, ...)
4568  local opts = utils.copy(options)
4569  local f = assert(io.open(filename, "rb"))
4570  local source = assert(f:read("*all"), ("Could not read " .. filename))
4571  f:close()
4572  opts.filename = filename
4573  return eval(source, opts, ...)
4574end
4575local function syntax()
4576  local body_3f = {"when", "with-open", "collect", "icollect", "lambda", "\206\187", "macro", "match", "accumulate"}
4577  local binding_3f = {"collect", "icollect", "each", "for", "let", "with-open", "accumulate"}
4578  local define_3f = {"fn", "lambda", "\206\187", "var", "local", "macro", "macros", "global"}
4579  local out = {}
4580  for k, v in pairs(compiler.scopes.global.specials) do
4581    local metadata = (compiler.metadata[v] or {})
4582    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)}
4583  end
4584  for k, v in pairs(compiler.scopes.global.macros) do
4585    out[k] = {["macro?"] = true, ["body-form?"] = utils["member?"](k, body_3f), ["binding-form?"] = utils["member?"](k, binding_3f), ["define?"] = utils["member?"](k, define_3f)}
4586  end
4587  for k, v in pairs(_G) do
4588    local _619_ = type(v)
4589    if (_619_ == "function") then
4590      out[k] = {["global?"] = true, ["function?"] = true}
4591    elseif (_619_ == "table") then
4592      for k2, v2 in pairs(v) do
4593        if (("function" == type(v2)) and (k ~= "_G")) then
4594          out[(k .. "." .. k2)] = {["function?"] = true, ["global?"] = true}
4595        else
4596        end
4597      end
4598      out[k] = {["global?"] = true}
4599    else
4600    end
4601  end
4602  return out
4603end
4604local mod = {list = utils.list, ["list?"] = utils["list?"], sym = utils.sym, ["sym?"] = utils["sym?"], sequence = utils.sequence, ["sequence?"] = utils["sequence?"], comment = utils.comment, ["comment?"] = utils["comment?"], varg = utils.varg, path = utils.path, ["macro-path"] = utils["macro-path"], ["sym-char?"] = parser["sym-char?"], parser = parser.parser, granulate = parser.granulate, ["string-stream"] = parser["string-stream"], compile = compiler.compile, ["compile-string"] = compiler["compile-string"], ["compile-stream"] = compiler["compile-stream"], compile1 = compiler.compile1, traceback = compiler.traceback, mangle = compiler["global-mangling"], unmangle = compiler["global-unmangling"], metadata = compiler.metadata, scope = compiler["make-scope"], gensym = compiler.gensym, ["load-code"] = specials["load-code"], ["macro-loaded"] = specials["macro-loaded"], ["macro-searchers"] = specials["macro-searchers"], ["search-module"] = specials["search-module"], ["make-searcher"] = specials["make-searcher"], makeSearcher = specials["make-searcher"], searcher = specials["make-searcher"](), doc = specials.doc, view = view, eval = eval, dofile = dofile_2a, version = utils.version, repl = repl, syntax = syntax, loadCode = specials["load-code"], make_searcher = specials["make-searcher"], searchModule = specials["search-module"], macroLoaded = specials["macro-loaded"], compileStream = compiler["compile-stream"], compileString = compiler["compile-string"], stringStream = parser["string-stream"]}
4605utils["fennel-module"] = mod
4606do
4607  local builtin_macros = [===[;; This module contains all the built-in Fennel macros. Unlike all the other
4608  ;; modules that are loaded by the old bootstrap compiler, this runs in the
4609  ;; compiler scope of the version of the compiler being defined.
4610
4611  ;; The code for these macros is somewhat idiosyncratic because it cannot use any
4612  ;; macros which have not yet been defined.
4613
4614  ;; TODO: some of these macros modify their arguments; we should stop doing that,
4615  ;; but in a way that preserves file/line metadata.
4616
4617  (fn ->* [val ...]
4618    "Thread-first macro.
4619  Take the first value and splice it into the second form as its first argument.
4620  The value of the second form is spliced into the first arg of the third, etc."
4621    (var x val)
4622    (each [_ e (ipairs [...])]
4623      (let [elt (if (list? e) e (list e))]
4624        (table.insert elt 2 x)
4625        (set x elt)))
4626    x)
4627
4628  (fn ->>* [val ...]
4629    "Thread-last macro.
4630  Same as ->, except splices the value into the last position of each form
4631  rather than the first."
4632    (var x val)
4633    (each [_ e (ipairs [...])]
4634      (let [elt (if (list? e) e (list e))]
4635        (table.insert elt x)
4636        (set x elt)))
4637    x)
4638
4639  (fn -?>* [val ...]
4640    "Nil-safe thread-first macro.
4641  Same as -> except will short-circuit with nil when it encounters a nil value."
4642    (if (= 0 (select "#" ...))
4643        val
4644        (let [els [...]
4645              e (table.remove els 1)
4646              el (if (list? e) e (list e))
4647              tmp (gensym)]
4648          (table.insert el 2 tmp)
4649          `(let [,tmp ,val]
4650             (if (not= nil ,tmp)
4651                 (-?> ,el ,(unpack els))
4652                 ,tmp)))))
4653
4654  (fn -?>>* [val ...]
4655    "Nil-safe thread-last macro.
4656  Same as ->> except will short-circuit with nil when it encounters a nil value."
4657    (if (= 0 (select "#" ...))
4658        val
4659        (let [els [...]
4660              e (table.remove els 1)
4661              el (if (list? e) e (list e))
4662              tmp (gensym)]
4663          (table.insert el tmp)
4664          `(let [,tmp ,val]
4665             (if (not= ,tmp nil)
4666                 (-?>> ,el ,(unpack els))
4667                 ,tmp)))))
4668
4669  (fn ?dot [tbl ...]
4670    "Nil-safe table look up.
4671  Same as . (dot), except will short-circuit with nil when it encounters
4672  a nil value in any of subsequent keys."
4673    (let [head (gensym :t)
4674          lookups `(do (var ,head ,tbl) ,head)]
4675      (each [_ k (ipairs [...])]
4676        ;; Kinda gnarly to reassign in place like this, but it emits the best lua.
4677        ;; With this impl, it emits a flat, concise, and readable set of if blocks.
4678        (table.insert lookups (# lookups) `(if (not= nil ,head)
4679                                             (set ,head (. ,head ,k)))))
4680      lookups))
4681
4682  (fn doto* [val ...]
4683    "Evaluates val and splices it into the first argument of subsequent forms."
4684    (let [name (gensym)
4685          form `(let [,name ,val])]
4686      (each [_ elt (ipairs [...])]
4687        (let [elt (if (list? elt) elt (list elt))]
4688          (table.insert elt 2 name)
4689          (table.insert form elt)))
4690      (table.insert form name)
4691      form))
4692
4693  (fn when* [condition body1 ...]
4694    "Evaluate body for side-effects only when condition is truthy."
4695    (assert body1 "expected body")
4696    `(if ,condition
4697         (do
4698           ,body1
4699           ,...)))
4700
4701  (fn with-open* [closable-bindings ...]
4702    "Like `let`, but invokes (v:close) on each binding after evaluating the body.
4703  The body is evaluated inside `xpcall` so that bound values will be closed upon
4704  encountering an error before propagating it."
4705    (let [bodyfn `(fn []
4706                    ,...)
4707          closer `(fn close-handlers# [ok# ...]
4708                    (if ok# ... (error ... 0)))
4709          traceback `(. (or package.loaded.fennel debug) :traceback)]
4710      (for [i 1 (length closable-bindings) 2]
4711        (assert (sym? (. closable-bindings i))
4712                "with-open only allows symbols in bindings")
4713        (table.insert closer 4 `(: ,(. closable-bindings i) :close)))
4714      `(let ,closable-bindings
4715         ,closer
4716         (close-handlers# (_G.xpcall ,bodyfn ,traceback)))))
4717
4718  (fn into-val [iter-tbl]
4719    (var into nil)
4720    (for [i (length iter-tbl) 2 -1]
4721      (if (= :into (. iter-tbl i))
4722          (do (assert (not into) "expected only one :into clause")
4723              (set into (table.remove iter-tbl (+ i 1)))
4724              (table.remove iter-tbl i))))
4725    (assert (or (not into)
4726                (sym? into)
4727                (table? into)
4728                (list? into))
4729            "expected table, function call, or symbol in :into clause")
4730    (or into []))
4731
4732  (fn collect* [iter-tbl key-value-expr ...]
4733    "Returns a table made by running an iterator and evaluating an expression
4734  that returns key-value pairs to be inserted sequentially into the table.
4735  This can be thought of as a \"table comprehension\". The provided key-value
4736  expression must return either 2 values, or nil.
4737
4738  For example,
4739    (collect [k v (pairs {:apple \"red\" :orange \"orange\"})]
4740      (values v k))
4741  returns
4742    {:red \"apple\" :orange \"orange\"}
4743
4744  Supports an :into clause after the iterator to put results in an existing table.
4745  Supports early termination with an :until clause."
4746    (assert (and (sequence? iter-tbl) (>= (length iter-tbl) 2))
4747            "expected iterator binding table")
4748    (assert (not= nil key-value-expr) "expected key-value expression")
4749    (assert (= nil ...)
4750            "expected exactly one body expression. Wrap multiple expressions with do")
4751    `(let [tbl# ,(into-val iter-tbl)]
4752       (each ,iter-tbl
4753         (match ,key-value-expr
4754           (k# v#) (tset tbl# k# v#)))
4755       tbl#))
4756
4757  (fn icollect* [iter-tbl value-expr ...]
4758    "Returns a sequential table made by running an iterator and evaluating an
4759  expression that returns values to be inserted sequentially into the table.
4760  This can be thought of as a \"list comprehension\".
4761
4762  For example,
4763    (icollect [_ v (ipairs [1 2 3 4 5])] (when (> v 2) (* v v)))
4764  returns
4765    [9 16 25]
4766
4767  Supports an :into clause after the iterator to put results in an existing table.
4768  Supports early termination with an :until clause."
4769    (assert (and (sequence? iter-tbl) (>= (length iter-tbl) 2))
4770            "expected iterator binding table")
4771    (assert (not= nil value-expr) "expected table value expression")
4772    (assert (= nil ...)
4773            "expected exactly one body expression. Wrap multiple expressions with do")
4774    `(let [tbl# ,(into-val iter-tbl)]
4775       ;; believe it or not, using a var here has a pretty good performance boost:
4776       ;; https://p.hagelb.org/icollect-performance.html
4777       (var i# (length tbl#))
4778       (each ,iter-tbl
4779         (let [val# ,value-expr]
4780           (when (not= nil val#)
4781             (set i# (+ i# 1))
4782             (tset tbl# i# val#))))
4783       tbl#))
4784
4785  (fn accumulate* [iter-tbl accum-expr ...]
4786    "Accumulation macro.
4787  It takes a binding table and an expression as its arguments.
4788  In the binding table, the first symbol is bound to the second value, being an
4789  initial accumulator variable. The rest are an iterator binding table in the
4790  format `each` takes.
4791  It runs through the iterator in each step of which the given expression is
4792  evaluated, and its returned value updates the accumulator variable.
4793  It eventually returns the final value of the accumulator variable.
4794
4795  For example,
4796    (accumulate [total 0
4797                 _ n (pairs {:apple 2 :orange 3})]
4798      (+ total n))
4799  returns
4800    5"
4801    (assert (and (sequence? iter-tbl) (>= (length iter-tbl) 4))
4802            "expected initial value and iterator binding table")
4803    (assert (not= nil accum-expr) "expected accumulating expression")
4804    (assert (= nil ...)
4805            "expected exactly one body expression. Wrap multiple expressions with do")
4806    (let [accum-var (table.remove iter-tbl 1)
4807          accum-init (table.remove iter-tbl 1)]
4808      `(do (var ,accum-var ,accum-init)
4809           (each ,iter-tbl
4810             (set ,accum-var ,accum-expr))
4811           ,accum-var)))
4812
4813  (fn partial* [f ...]
4814    "Returns a function with all arguments partially applied to f."
4815    (assert f "expected a function to partially apply")
4816    (let [bindings []
4817          args []]
4818      (each [_ arg (ipairs [...])]
4819        (if (or (= :number (type arg))
4820                (= :string (type arg))
4821                (= :boolean (type arg))
4822                (= `nil arg))
4823          (table.insert args arg)
4824          (let [name (gensym)]
4825            (table.insert bindings name)
4826            (table.insert bindings arg)
4827            (table.insert args name))))
4828      (let [body (list f (unpack args))]
4829        (table.insert body _VARARG)
4830        `(let ,bindings
4831           (fn [,_VARARG]
4832             ,body)))))
4833
4834  (fn pick-args* [n f]
4835    "Creates a function of arity n that applies its arguments to f.
4836
4837  For example,
4838    (pick-args 2 func)
4839  expands to
4840    (fn [_0_ _1_] (func _0_ _1_))"
4841    (if (and _G.io _G.io.stderr)
4842        (_G.io.stderr:write
4843         "-- WARNING: pick-args is deprecated and will be removed in the future.\n"))
4844    (assert (and (= (type n) :number) (= n (math.floor n)) (>= n 0))
4845            (.. "Expected n to be an integer literal >= 0, got " (tostring n)))
4846    (let [bindings []]
4847      (for [i 1 n]
4848        (tset bindings i (gensym)))
4849      `(fn ,bindings
4850         (,f ,(unpack bindings)))))
4851
4852  (fn pick-values* [n ...]
4853    "Like the `values` special, but emits exactly n values.
4854
4855  For example,
4856    (pick-values 2 ...)
4857  expands to
4858    (let [(_0_ _1_) ...]
4859      (values _0_ _1_))"
4860    (assert (and (= :number (type n)) (>= n 0) (= n (math.floor n)))
4861            (.. "Expected n to be an integer >= 0, got " (tostring n)))
4862    (let [let-syms (list)
4863          let-values (if (= 1 (select "#" ...)) ... `(values ,...))]
4864      (for [i 1 n]
4865        (table.insert let-syms (gensym)))
4866      (if (= n 0) `(values)
4867          `(let [,let-syms ,let-values]
4868             (values ,(unpack let-syms))))))
4869
4870  (fn lambda* [...]
4871    "Function literal with nil-checked arguments.
4872  Like `fn`, but will throw an exception if a declared argument is passed in as
4873  nil, unless that argument's name begins with a question mark."
4874    (let [args [...]
4875          has-internal-name? (sym? (. args 1))
4876          arglist (if has-internal-name? (. args 2) (. args 1))
4877          docstring-position (if has-internal-name? 3 2)
4878          has-docstring? (and (> (length args) docstring-position)
4879                              (= :string (type (. args docstring-position))))
4880          arity-check-position (- 4 (if has-internal-name? 0 1)
4881                                  (if has-docstring? 0 1))
4882          empty-body? (< (length args) arity-check-position)]
4883      (fn check! [a]
4884        (if (table? a)
4885            (each [_ a (pairs a)]
4886              (check! a))
4887            (let [as (tostring a)]
4888              (and (not (as:match "^?")) (not= as "&") (not= as "_")
4889                   (not= as "...") (not= as "&as")))
4890            (table.insert args arity-check-position
4891                          `(_G.assert (not= nil ,a)
4892                                      ,(: "Missing argument %s on %s:%s" :format
4893                                          (tostring a)
4894                                          (or a.filename :unknown)
4895                                          (or a.line "?"))))))
4896
4897      (assert (= :table (type arglist)) "expected arg list")
4898      (each [_ a (ipairs arglist)]
4899        (check! a))
4900      (if empty-body?
4901          (table.insert args (sym :nil)))
4902      `(fn ,(unpack args))))
4903
4904  (fn macro* [name ...]
4905    "Define a single macro."
4906    (assert (sym? name) "expected symbol for macro name")
4907    (local args [...])
4908    `(macros {,(tostring name) (fn ,(unpack args))}))
4909
4910  (fn macrodebug* [form return?]
4911    "Print the resulting form after performing macroexpansion.
4912  With a second argument, returns expanded form as a string instead of printing."
4913    (let [handle (if return? `do `print)]
4914      `(,handle ,(view (macroexpand form _SCOPE)))))
4915
4916  (fn import-macros* [binding1 module-name1 ...]
4917    "Binds a table of macros from each macro module according to a binding form.
4918  Each binding form can be either a symbol or a k/v destructuring table.
4919  Example:
4920    (import-macros mymacros                 :my-macros    ; bind to symbol
4921                   {:macro1 alias : macro2} :proj.macros) ; import by name"
4922    (assert (and binding1 module-name1 (= 0 (% (select "#" ...) 2)))
4923            "expected even number of binding/modulename pairs")
4924    (for [i 1 (select "#" binding1 module-name1 ...) 2]
4925      (let [(binding modname) (select i binding1 module-name1 ...)
4926            ;; generate a subscope of current scope, use require-macros
4927            ;; to bring in macro module. after that, we just copy the
4928            ;; macros from subscope to scope.
4929            scope (get-scope)
4930            macros* (_SPECIALS.require-macros `(import-macros ,modname)
4931                                              (fennel.scope scope) {} ast)]
4932        (if (sym? binding)
4933            ;; bind whole table of macros to table bound to symbol
4934            (tset scope.macros (. binding 1) macros*)
4935            ;; 1-level table destructuring for importing individual macros
4936            (table? binding)
4937            (each [macro-name [import-key] (pairs binding)]
4938              (assert (= :function (type (. macros* macro-name)))
4939                      (.. "macro " macro-name " not found in module "
4940                          (tostring modname)))
4941              (tset scope.macros import-key (. macros* macro-name))))))
4942    nil)
4943
4944  ;;; Pattern matching
4945
4946  (fn match-values [vals pattern unifications match-pattern]
4947    (let [condition `(and)
4948          bindings []]
4949      (each [i pat (ipairs pattern)]
4950        (let [(subcondition subbindings) (match-pattern [(. vals i)] pat
4951                                                        unifications)]
4952          (table.insert condition subcondition)
4953          (each [_ b (ipairs subbindings)]
4954            (table.insert bindings b))))
4955      (values condition bindings)))
4956
4957  (fn match-table [val pattern unifications match-pattern]
4958    (let [condition `(and (= (_G.type ,val) :table))
4959          bindings []]
4960      (each [k pat (pairs pattern)]
4961        (if (= pat `&)
4962            (do
4963              (assert (= nil (. pattern (+ k 2)))
4964                      "expected & rest argument before last parameter")
4965              (table.insert bindings (. pattern (+ k 1)))
4966              (table.insert bindings
4967                            [`(select ,k ((or table.unpack _G.unpack) ,val))]))
4968            (= k `&as)
4969            (do
4970              (table.insert bindings pat)
4971              (table.insert bindings val))
4972            (and (= :number (type k)) (= `&as pat))
4973            (do
4974              (assert (= nil (. pattern (+ k 2)))
4975                      "expected &as argument before last parameter")
4976              (table.insert bindings (. pattern (+ k 1)))
4977              (table.insert bindings val))
4978            ;; don't process the pattern right after &/&as; already got it
4979            (or (not= :number (type k)) (and (not= `&as (. pattern (- k 1)))
4980                                             (not= `& (. pattern (- k 1)))))
4981            (let [subval `(. ,val ,k)
4982                  (subcondition subbindings) (match-pattern [subval] pat
4983                                                            unifications)]
4984              (table.insert condition subcondition)
4985              (each [_ b (ipairs subbindings)]
4986                (table.insert bindings b)))))
4987      (values condition bindings)))
4988
4989  (fn match-pattern [vals pattern unifications]
4990    "Takes the AST of values and a single pattern and returns a condition
4991  to determine if it matches as well as a list of bindings to
4992  introduce for the duration of the body if it does match."
4993    ;; we have to assume we're matching against multiple values here until we
4994    ;; know we're either in a multi-valued clause (in which case we know the #
4995    ;; of vals) or we're not, in which case we only care about the first one.
4996    (let [[val] vals]
4997      (if (or (and (sym? pattern) ; unification with outer locals (or nil)
4998                   (not= "_" (tostring pattern)) ; never unify _
4999                   (or (in-scope? pattern) (= :nil (tostring pattern))))
5000              (and (multi-sym? pattern) (in-scope? (. (multi-sym? pattern) 1))))
5001          (values `(= ,val ,pattern) [])
5002          ;; unify a local we've seen already
5003          (and (sym? pattern) (. unifications (tostring pattern)))
5004          (values `(= ,(. unifications (tostring pattern)) ,val) [])
5005          ;; bind a fresh local
5006          (sym? pattern)
5007          (let [wildcard? (: (tostring pattern) :find "^_")]
5008            (if (not wildcard?) (tset unifications (tostring pattern) val))
5009            (values (if (or wildcard? (string.find (tostring pattern) "^?")) true
5010                        `(not= ,(sym :nil) ,val)) [pattern val]))
5011          ;; guard clause
5012          (and (list? pattern) (= (. pattern 2) `?))
5013          (let [(pcondition bindings) (match-pattern vals (. pattern 1)
5014                                                     unifications)
5015                condition `(and ,(unpack pattern 3))]
5016            (values `(and ,pcondition
5017                          (let ,bindings
5018                            ,condition)) bindings))
5019          ;; multi-valued patterns (represented as lists)
5020          (list? pattern)
5021          (match-values vals pattern unifications match-pattern)
5022          ;; table patterns
5023          (= (type pattern) :table)
5024          (match-table val pattern unifications match-pattern)
5025          ;; literal value
5026          (values `(= ,val ,pattern) []))))
5027
5028  (fn match-condition [vals clauses]
5029    "Construct the actual `if` AST for the given match values and clauses."
5030    (if (not= 0 (% (length clauses) 2)) ; treat odd final clause as default
5031        (table.insert clauses (length clauses) (sym "_")))
5032    (let [out `(if)]
5033      (for [i 1 (length clauses) 2]
5034        (let [pattern (. clauses i)
5035              body (. clauses (+ i 1))
5036              (condition bindings) (match-pattern vals pattern {})]
5037          (table.insert out condition)
5038          (table.insert out `(let ,bindings
5039                               ,body))))
5040      out))
5041
5042  (fn match-val-syms [clauses]
5043    "How many multi-valued clauses are there? return a list of that many gensyms."
5044    (let [syms (list (gensym))]
5045      (for [i 1 (length clauses) 2]
5046        (let [clause (if (and (list? (. clauses i)) (= `? (. clauses i 2)))
5047                         (. clauses i 1)
5048                         (. clauses i))]
5049          (if (list? clause)
5050              (each [valnum (ipairs clause)]
5051                (if (not (. syms valnum))
5052                    (tset syms valnum (gensym)))))))
5053      syms))
5054
5055  (fn match* [val ...]
5056    ;; Old implementation of match macro, which doesn't directly support
5057    ;; `where' and `or'. New syntax is implemented in `match-where',
5058    ;; which simply generates old syntax and feeds it to `match*'.
5059    (let [clauses [...]
5060          vals (match-val-syms clauses)]
5061      (assert (= 0 (math.fmod (length clauses) 2))
5062              "expected even number of pattern/body pairs")
5063      ;; protect against multiple evaluation of the value, bind against as
5064      ;; many values as we ever match against in the clauses.
5065      (list `let [vals val] (match-condition vals clauses))))
5066
5067  ;; Construction of old match syntax from new syntax
5068
5069  (fn partition-2 [seq]
5070    ;; Partition `seq` by 2.
5071    ;; If `seq` has odd amount of elements, the last one is dropped.
5072    ;;
5073    ;; Input: [1 2 3 4 5]
5074    ;; Output: [[1 2] [3 4]]
5075    (let [firsts []
5076          seconds []
5077          res []]
5078      (for [i 1 (length seq) 2]
5079        (let [first (. seq i)
5080              second (. seq (+ i 1))]
5081          (table.insert firsts (if (not= nil first) first `nil))
5082          (table.insert seconds (if (not= nil second) second `nil))))
5083      (each [i v1 (ipairs firsts)]
5084        (let [v2 (. seconds i)]
5085          (if (not= nil v2)
5086              (table.insert res [v1 v2]))))
5087      res))
5088
5089  (fn transform-or [[_ & pats] guards]
5090    ;; Transforms `(or pat pats*)` lists into match `guard` patterns.
5091    ;;
5092    ;; (or pat1 pat2), guard => [(pat1 ? guard) (pat2 ? guard)]
5093    (let [res []]
5094      (each [_ pat (ipairs pats)]
5095        (table.insert res (list pat `? (unpack guards))))
5096      res))
5097
5098  (fn transform-cond [cond]
5099    ;; Transforms `where` cond into sequence of `match` guards.
5100    ;;
5101    ;; pat => [pat]
5102    ;; (where pat guard) => [(pat ? guard)]
5103    ;; (where (or pat1 pat2) guard) => [(pat1 ? guard) (pat2 ? guard)]
5104    (if (and (list? cond) (= (. cond 1) `where))
5105        (let [second (. cond 2)]
5106          (if (and (list? second) (= (. second 1) `or))
5107              (transform-or second [(unpack cond 3)])
5108              :else
5109              [(list second `? (unpack cond 3))]))
5110        :else
5111        [cond]))
5112
5113  (fn match-where [val ...]
5114    "Perform pattern matching on val. See reference for details.
5115
5116  Syntax:
5117
5118  (match data-expression
5119    pattern body
5120    (where pattern guard guards*) body
5121    (where (or pattern patterns*) guard guards*) body)"
5122    (let [conds-bodies (partition-2 [...])
5123          else-branch (if (not= 0 (% (select "#" ...) 2))
5124                          (select (select "#" ...) ...))
5125          match-body []]
5126      (each [_ [cond body] (ipairs conds-bodies)]
5127        (each [_ cond (ipairs (transform-cond cond))]
5128          (table.insert match-body cond)
5129          (table.insert match-body body)))
5130      (if else-branch
5131          (table.insert match-body else-branch))
5132      (match* val (unpack match-body))))
5133
5134  {:-> ->*
5135   :->> ->>*
5136   :-?> -?>*
5137   :-?>> -?>>*
5138   :?. ?dot
5139   :doto doto*
5140   :when when*
5141   :with-open with-open*
5142   :collect collect*
5143   :icollect icollect*
5144   :accumulate accumulate*
5145   :partial partial*
5146   :lambda lambda*
5147   :pick-args pick-args*
5148   :pick-values pick-values*
5149   :macro macro*
5150   :macrodebug macrodebug*
5151   :import-macros import-macros*
5152   :match match-where}
5153  ]===]
5154  local module_name = "fennel.macros"
5155  local _
5156  local function _622_()
5157    return mod
5158  end
5159  package.preload[module_name] = _622_
5160  _ = nil
5161  local env
5162  do
5163    local _623_ = specials["make-compiler-env"](nil, compiler.scopes.compiler, {})
5164    do end (_623_)["utils"] = utils
5165    _623_["fennel"] = mod
5166    env = _623_
5167  end
5168  local built_ins = eval(builtin_macros, {env = env, scope = compiler.scopes.compiler, allowedGlobals = false, useMetadata = true, filename = "src/fennel/macros.fnl", moduleName = module_name})
5169  for k, v in pairs(built_ins) do
5170    compiler.scopes.global.macros[k] = v
5171  end
5172  compiler.scopes.global.macros["\206\187"] = compiler.scopes.global.macros.lambda
5173  package.preload[module_name] = nil
5174end
5175return mod
5176