{"version":3,"sources":["src/repl.sibilant","src/macros/pipe.sibilant","src/macros/misc.sibilant","src/macros/flow-control.sibilant","src/macros/math.sibilant","src/macros/hash.sibilant","src/macros/lambda.sibilant","src/macros/regex.sibilant","src/macros/loops.sibilant","src/macros/predicates.sibilant","src/helpers.sibilant","src/macros/lists.sibilant"],"names":[],"mappings":"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","sourcesContent":["(|> \"source-map-support\" require .install)\n(source-mapping-url \"../maps/repl.map\")\n\n(require! sibilant: \"./sibilant\",\n          'cardinal, 'util, 'vm 'fs)\n\n(var input      (process.open-stdin)\n     output     process.stdout\n     readline   (|> 'readline require (.create-interface input output))\n     context    undefined\n     cmd-buffer \"\"\n     HISTORY-FILE (|> process.env.SIBILANT-REPL-HISTORY-FILE\n                      (or (\"\"process.env.HOME\"/.sibilant.history\")))\n     fd undefined)\n\n\n(.access fs HISTORY-FILE fs.R-OK\n         (#(err)\n           (unless err\n                   (|> fs.read-file-sync(HISTORY-FILE \"utf-8\")\n                       .split(\"\\n\\n\")\n                       .reverse\n                       .filter((#-> as-boolean))\n                       set(readline 'history #)))))\n\n(assign fd fs.open-sync(HISTORY-FILE 'a))\n\n\n\n(def create-context ()\n     (var context (vm.create-context))\n     (set module 'filename (|> (process.cwd) (concat \"/exec\")))\n     (set context\n          '*sibilant sibilant\n          'module  module\n          'require require)\n     (each-key key global (set context key (get global key)))\n     context)\n\n(assign context (create-context))\n\n(def display-prompt ()\n     (var open (|> cmd-buffer (.split (regex \"[\\\\{\\\\[\\\\(]\" 'g)) length)\n          closed (|> cmd-buffer (.split (regex \"[\\\\}\\\\]\\\\)]\" 'g)) length)\n          indentation \"\")\n\n     (while (> open closed)\n            (assign indentation (\"  \" indentation))\n            (decr open))\n\n     (readline.set-prompt (if (empty? cmd-buffer)\n                              \"sibilant> \"\n                              (\"          \" indentation)))\n     ;;                              \"            \"))\n     (readline.prompt))\n\n(def handle-line (cmd)\n     (var js-line \"\")\n\n     (try\n      (do\n       (assign cmd-buffer (concat cmd-buffer cmd)\n               {js} (sibilant cmd-buffer))\n\n       (var safe-js (if (= (first js) \"{\")\n                        (pipe js\n                              ((sibilant.resolve-macro 'scoped))\n                              sibilant.transpile\n                              sibilant.output-formatter)\n                        js))\n\n       (try\n        (|> js cardinal.highlight console.log)\n        (console.dir js))\n\n       (var result (vm.run-in-context safe-js context \"sibilant-repl\"))\n       (set readline.history 0 cmd-buffer)\n       (.write-sync fs fd (\"\"cmd-buffer\"\\n\\n\"))\n       (when (defined? result)\n             (output.write (\"result: \"\n                                 (util.inspect result { colors true }) \"\\n\")))\n       (set context \"_\" result)\n       (assign cmd-buffer \"\"))\n      (do\n       (if (match-regex? e.message \"unclosed node\")\n           (do\n            (assign cmd-buffer (concat cmd-buffer \"\\n\"))\n            (readline.history.shift))\n           (do\n            (set readline.history 0 cmd-buffer)\n            (.write-sync fs fd (\"\"cmd-buffer\"\\n\\n\"))\n            (.write output (concat e.stack \"\\n\"))\n            (assign  cmd-buffer \"\")))))\n     (display-prompt))\n\n(readline.on 'line handle-line)\n\n(readline.on 'close (#>\n                     fs.close-sync(fd)\n                     (output.write \"\\nexiting\")\n                     (input.destroy)))\n\n(display-prompt)\n","(namespace core)\n(docs \"inserts the result of each subsequent call in `calls` as the\nsecond argument to the next macro. This is very much akin to clojure's\nthread-first arrow or elixir's pipe operator.  Advanced: in order to\nthread the preceding topic into a position other than the second\nposition, use the character `#` to specify topic position\"\n      tags [language flow-control]\n      examples: [\n(pipe \"a b c d\"\n      .to-upper-case\n      (.replace \"A\" \"X\")\n      (.split \" \")\n      first\n      (concat \" marks the spot\"))\n\n(pipe \"{\\\"a\\\": {\\\"b\\\": [ 1, 2, 3 ]}}\"\n      JSON.parse\n      (get 'a)\n      JSON.stringify)\n\n(pipe 3 (+ 1) (var a #))\n]\n     references: [ \"https://clojuredocs.org/clojure.core/-%3E\"\n                   \"http://elixir-lang.org/docs/v1.0/elixir/Kernel.html#|>/2\" ])\n(macro pipe (...calls)\n       (inject undefined calls\n               (#(value item)\n                 (if (undefined? value) item\n                     (scoped\n                      (var cloned (if (node? item 'literal 'dots)\n                                      `(@item)\n                                      (clone item)))\n\n                      (var placeholder (detect cloned.contents\n                                               (#(node)\n                                                 (and (node? node 'other-char)\n                                                      (= \"#\" node.token))))\n                           placeholder-index (cloned.contents.index-of placeholder)\n\n                           placeholder-boundaries (if placeholder\n                                                      [ placeholder-index (+ 1 placeholder-index) ]\n                                                      [ 1 1 ]))\n\n                      (merge-into cloned\n                                  { contents [ ...(cloned.contents.slice 0 (first placeholder-boundaries))\n                                               value\n                                               ...(cloned.contents.slice (second placeholder-boundaries)) ] }))))))\n\n(alias-macro pipe |>)\n\n\n(docs \"most often called as its alias, `#->`, pipe-thunk applies a pipe chain to the argument of a function and returns the result\"\n      tags [functions language]\n      examples [ (.map `[ a b c ] (#-> (.to-upper-case) (concat \" is a letter\"))) ])\n(macro pipe-thunk (...calls) `(thunk @{ node this } (pipe #0 ...@calls)))\n(alias-macro pipe-thunk #->)\n\n\n(docs \"generates a function intended to be used in conjunction with\n`pipe` or `pipe-thunk` that does not interrupt the main flow of the\n`pipe`\"\n      tags [ language flow-control ]\n      examples [ (|> 2 (tap (+ 5) console.log) (* 10))\n                 (#-> .to-upper-case (tap console.log) (.split \" \")) ])\n(macro tap (thing ...body)\n       `((#> (|> #0 ...@body) #0) @thing))\n\n\n(macro distribute (thing macro ...alternatives)\n       `(@macro ...@(map alternatives (#(alt)\n                                        (if (node? alt 'expression)\n                                            `(|> @thing @alt)\n                                            `(|> @thing ...@alt))))))\n","(namespace core)\n\n(macro statement! (node)\n     (if (empty-node? transpiled) undefined\n         [ node \";\" ]))\n\n\n(docs \"uses the javascript new keyword to construct an object using\n      `constructor`, with `args` passed as arguments to the constructor.\"\n      tags [functions]\n      example (new RegExp \"hello\" 'g))\n\n(macro new (constructor ...args)\n       [\"(new \" '(call @constructor ...@args) \")\"])\n\n(docs \"exposes the javascript typeof operator. most often, predicates\nsuch as `string?`, `function?`, `number?`, etc are preferred.\"\n      tags [type]\n      example: (typeof 5))\n(macro typeof (thing) [\"typeof \" (transpile thing)])\n\n(docs \"inserts `contents` transpiled to javascript as a comment in the\noutput file, removing it from execution.\"\n      tags [language]\n      example (comment (scoped 1)))\n(macro comment (...contents)\n       (map contents (#(content)\n                       [\"// \"(recurse-map (transpile content)\n                                    (#(item)\n                                      (ternary item\n                                               (pipe item transpile output-formatter\n                                                     (.replace (regex \"\\n\" 'g) \"\\n// \"))\n                                               null)))])))\n\n\n(docs \"outputs debug information about `arg`.  If `label` is\nomitted (only one argument is provided), the name of the variable or\nexpression of that first expression will be logged. Aliased as `pretty-log`\"\n      tags [language]\n      examples: [ (log-pretty 'my-label value)\n                  (log-pretty (+ 1 2)) ])\n(macro log-pretty (label arg)\n       (var node this)\n       (when (undefined? arg)\n             (assign arg label\n                     label [\"\\\"\" (prettify label false) \"\\\"\"]))\n       `(console.log (concat @[\"\\\"\" node.file \":\" node.line \"\\\"\"] \" \" @label \" = \" (prettify @arg))))\n(alias-macro log-pretty pretty-log)\n\n\n(docs \"throws a new javascript error with arguments as the string\"\n      tags [language]\n      example (throw (new Error \"could not find matching socks\")))\n\n(macro throw (error)\n       [\"throw \" (transpile error)])\n\n;;nodoc because this needs attention\n;;todo\n(macro try (tryblock catchblock)\n       [\"(function() {\"\n        (indent [\"try {\"\n                 (indent '(do @tryblock))\n                 \"} catch (e) {\"\n                 (indent '(do @catchblock))\n                 \"}\"])\n         \"}).call(this)\"])\n\n(macro with-state (k v ...body)\n       (var {state} sibilant\n            [key value] (|> [ k v ] (map (#-> transpile output-formatter)))\n            before (get state key))\n       (set state key value)\n       (var return-value (interleave \"\\n\" (map body transpile)))\n       (set state key before)\n       return-value)\n\n(docs \"combines elements of array `arr` into a string, inserting\n`glue` string between each element.  if `glue` is omitted (only one\nargument provided), the elements of `arr` are joined with an empty\nstring\"\n\n      tags [arrays collections strings]\n      examples [ (join `[ a few words ]  \", \" )\n                 (join `[ several more words ]) ])\n\n(macro join (arr glue)\n       (if (and (defined? glue) (undefined? arr))\n           (assign arr glue glue undefined))\n       `(.join @arr @(or glue \"\\\"\\\"\")))\n\n(macro parens (...contents)\n       [\"(\" ...contents \")\"])\n\n(docs \"inserts a pragma for source-mapping-url\"\n      tags []\n      example (source-mapping-url \"/example.map\"))\n\n(macro source-mapping-url (url)\n       [ \"//# sourceMappingURL=\" (|> url transpile output-formatter eval) \"\\n\" ])\n\n(macro require! (...requires)\n       `(var ...@(inject [] requires\n                         (#(pairs node)\n                            (pairs.concat\n                             (if\n\n                              (and (even? pairs.length)\n                                   (node? node 'tick 'string))\n                              \n                              [ (merge-into (clone node)\n                                            { token (|> node transpile output-formatter (.slice 1 -1))\n                                              contents []\n                                              type 'literal })\n                                `(require @node) ]\n\n                                 (odd? pairs.length)\n                                 [ `(require @node) ]\n\n                                 [ node ]))))))\n\n\n(macro export (...local-vars)\n       (var pairs (local-vars.reduce\n                   (#(acc value) (acc.concat [(^core/quote value) value]))\n                   []))\n       `(set exports ...@pairs))\n\n(macro empty-list () 'null)\n\n\n(macro debug (val)\n     (set sibilant 'debug (eval (output-formatter (transpile val)))) null)\n\n\n(macro dots (...contents)\n       (transpile contents))\n\n(docs \"loads and transpiles content from another file or `files` as if\nit were written in-line.  This is distinct from node's `require`\nfunction, as `include` will drop the output javascript directly in\nplace of the include statement.  Namespaced macros defined in the\nincluded file will not by default be imported into the current macro\nnamespace.  Include will append \\\".sibilant\\\" to the end of files, and\nwill also use node's module system to resolve sibilant files from\nother packages.  As a noncompiling example, it is possible to `npm\ninstall sibilant-react` and `(include \\\"sibilant-react/macros\\\")`,\nwhich introduces the `react` macro namespace.\"\n      tags [language])\n\n(macro include (...files)\n     (pipe files\n           (.map (#(file)\n                   (sibilant.with-default-search-path\n                    (#>\n                     (pipe file\n                           transpile\n                           output-formatter\n                           eval\n                           sibilant.include)))))\n           (interleave \"\\n\")))\n\n","(namespace core)\n\n(docs \"the simplest way to conditionally execute code.\"\n      tags [ conditional flow-control ]\n      example (ternary (< 50 100)\n         \"fifty is less than 100\"\n         \"fifty is more than 100\"))\n\n(macro ternary (cond if-true if-false)\n       [\"(\" (transpile cond) \") ? \"\n            (transpile if-true) \" : \"\n            (transpile if-false)])\n\n\n(docs \"evaluates statements in `body` if `condition` is true. `body`\n      is `scoped` in a self-evaluating function to support having a\n      return value from the if statement.\"\n      tags [ conditional flow-control language ]\n      example: (when (< 3 i) (console.log i) (get arr i)))\n\n(macro when (condition ...body)\n       (^*scoped-without-return\n         \"if (\" @condition \") {\"\n         (indent `(do ...@body))\n         \"}\"))\n\n(docs \"evaluates statements in `body` if `condition` is falsy. `body`\n      is `scoped` in a self-evaluating function to support having a\n      return value from the if statement.\"\n      tags [conditional flow-control]\n      example: (unless (< 3 i) (console.log i) (get arr i)))\n\n(macro unless (condition ...body)\n       [\"(function() {\"\n        (indent [\"if (\" '(not @condition) \") {\"\n                        (indent '(do ...@body))\n                        \"}\"])\n        \"}).call(this)\"])\n\n(docs \"tests any number of `alternating-conditions-and-branches`.  If\n      an odd number of branches are supplied, the final branch is a\n      default else clause.  To evaluate more than one expression as a\n      branch, use the `do` macro, as shown in the examples:\"\n      tags [conditional flow-control]\n      examples [ (if true (console.log 'here))\n                 (if (= 1 arguments.length) (console.log \"one argument\")\n                     (= 'blue favorite-color) (console.log \"blue\")\n                     (assign examples 'difficult))\n                 (if (foo?) (do (a b)\n                                (c))\n                     (bar?) (do (baz)\n                                (wibble))\n                     (do (d e)\n                         (console.log 'default))) ])\n\n\n\n(macro if (...alternating-conditions-and-branches)\n       [\"(function() {\"\n        (indent\n         (interleave \" else \"\n               (bulk-map alternating-conditions-and-branches\n                         (#(cond val)\n                           (if (!= (typeof val) 'undefined)\n                                 [\"if (\" (transpile cond) \") {\"\n                                   (indent '(do @val))\n                                   \"}\"]\n                                 [\"{\" (indent '(do @cond)) \"}\"])))))\n        \"}).call(this)\"])\n","(namespace core)\n\n(docs \"adds `args` using the javascript `+` operator. Since javascript\noverloads this for string concatenation, this macro can be used for\nthis as well.\"\n      tags [ strings numbers ]\n      examples [ (+ 1 2 3) (+ 'hello 'world) ])\n(macro +   (...args)\n       [\"(\" (interleave \" + \" (map args transpile)) \")\"])\n(alias-macro + concat)\n\n\n(docs \"subtracts each subsequent element of `args`\"\n      tags [numbers]\n      examples [ (- 2 1) (- 10 5 1) ])\n(macro -   (...args)\n       [\"(\" (interleave \" - \" (map args transpile)) \")\"])\n\n(docs \"multiplies elements of `args`\"\n      tags [numbers]\n      example (* 3 4 5))\n(macro *   (...args)\n       [\"(\" (interleave \" * \" (map args transpile)) \")\"])\n\n(docs \"divides each subsequent element of `args`\"\n      tags [numbers]\n      examples [ (/ 1 2)\n                 (/ 1 2 3) ])\n(macro /   (...args)\n           [\"(\" (interleave \" / \" (map args transpile)) \")\"])\n\n(docs \"modulus operator\"\n      tags [numbers]\n      example (mod 10 2))\n(macro mod (...args)\n       [\"(\" (interleave \" % \" (map args transpile)) \")\"])\n\n\n(docs \"increments `item` by `increment`\"\n      tags [numbers]\n      example (incr-by n 5))\n(macro incr-by (item increment)\n       [ (transpile item) \" += \" (transpile increment)])\n\n(docs \"increments item by 1\",\n      tags [numbers],\n      example (incr i))\n(macro incr (item)\n       [\"((\" (transpile item) \")++)\"])\n\n\n(docs \"decrements item by 1\",\n      tags [numbers],\n      example (decr i))\n(macro decr (item) [\"((\" (transpile item) \")--)\"])\n\n\n(docs \"short circuiting operator returns the first element of `args` that evaluates to be truthy\"\n      tags [ conditional flow-control booleans ]\n      example (or (= 1 2) (string? []) \"one is not two and an array is not a string\"))\n(macro or  (...args)\n       [\"(\" (interleave \" || \" (map args transpile)) \")\"])\n\n\n(docs \"returns the last element if all elements of `args` are truthy, or the\nfirst non-truthy element if it exists\"\n      tags [ booleans ]\n      example (and (string? \"string\") (number? 10) (= 1 1)))\n(macro and (...args)\n       (if (= 1 (length args))\n           (transpile (first args))\n           `(parens ...@(interleave \" && \" (map args transpile)))))\n\n(docs \"boolean negation, as determined by javascript truthiness\"\n      tags [booleans]\n      example: (not (string? 1))\n      references: [ \"https://developer.mozilla.org/en-US/docs/Glossary/Truthy\"\n                    \"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\" ])\n(macro not (exp)\n       [\"!\" `(parens @exp) ])\n\n\n\n(docs \"double-negates `expr`, converting it to a boolean\"\n      tags [type booleans]\n      examples: [ (as-boolean 0)\n                  (as-boolean true) ])\n(macro as-boolean (expr)\n       `(parens @\"!!\" (parens @expr)))\n\n(docs \"coerces `expr` to a number.  Currently implemented through the use of Number()\"\n      tags [type numbers]\n      examples: [ (as-number \"0.1\")\n                  (as-number 0.1) ]\n      references: [ \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number\" ])\n(macro as-number (expr) `(Number @expr))\n","(namespace core)\n\n(macro quoted-hash (...pairs)\n     (var cached-quote-value sibilant.quote-hash-keys)\n     (set sibilant 'quote-hash-keys true)\n     (var value (^hash ...pairs))\n     (set sibilant 'quote-hash-keys cached-quote-value)\n     value)\n\n(docs \"this is the macro that is called by braces (`{}`). Produces a\njavascript object out of alternating key value pairs. To repeat an\nentry as both key and value, use the & character, as shown in examples.  To use the value of a variable as a key, use the backtick character before the key. These can be combined\"\n      tags [ collections objects ]\n      examples [ (hash k1 v1 k2 v2)\n                 (hash 'key 'value)\n                 { 'key { 'nested 'value } }\n                 { kv1& kv2& } { `variable 1 } { `variable & } ])\n      \n(macro hash (...pairs)\n       (assign pairs (pairs.map (#(p i)\n                                  (if (and (= p.token \"&\") (node? p 'special))\n                                      (do\n                                       (var double (get pairs (if (even? i) (+ 1 i) (- i 1))))\n                                       (if (and (node? double 'tick) (= double.token \"`\"))\n                                           (first double.contents)\n                                           double))\n                                      p))))\n                                                                                       \n       (when (odd? pairs.length)\n             (error (\"odd number of key-value pairs in hash: \"\n                     (call inspect pairs))))\n\n       (var {dynamic-keys static-keys}\n            (pairs.reduce (#(o item i)\n                            (if (and (even? i) (node? item 'tick) (= item.token \"`\"))\n                                (Object.assign {} o { dynamic-keys: [ ...o.dynamic-keys (first item.contents) ] })\n\n                                (and (odd? o.dynamic-keys.length) (odd? i))\n                                (Object.assign {} o { dynamic-keys: [ ...o.dynamic-keys item ] })\n\n                                (Object.assign {} o { static-keys: [ ...o.static-keys item ] })))\n                          { dynamic-keys: [], static-keys: [] }))\n\n       (var quote-keys sibilant.quote-hash-keys\n            pair-strings (bulk-map static-keys (#(key value)\n                                           [ (if (and quote-keys (not (node? key 'string)))\n                                                 [\"\\\"\" (transpile key) \"\\\"\"]\n                                                 (transpile key))\n                                             \": \"\n                                             (transpile value)])))\n\n       (if dynamic-keys.length\n           (do\n            (var symbol (generate-symbol 'hash))\n            `(*scoped-without-source\n              (var @symbol (hash ...@static-keys))\n              (set @symbol ...@dynamic-keys)\n              @symbol))\n\n        (>= 1 pair-strings.length)\n           [\"{ \" (interleave \", \" pair-strings) \" }\"]\n           [\"{\" (indent (interleave \",\\n\" pair-strings)) \"}\"]))\n\n\n(docs \"retreives object properties, potentially deeply. If more than one `keys` are provided,\n`get` fetches deeply into nested objects or arrays.\nWhen javascript dot notation can be used (`a.b = 3`), it is.\nOtherwise, bracket notation is used.\"\n      tags [collections objects]\n      examples [ (get an-object 'static-attribute-name)\n                 (get object dynamic-attribute-name)\n                 (get object \"these attributes\" \"can't be dotted\")\n                 (get array 0)\n                 (get object 'a 'b c)\n                 (get array 0 1 2) ])\n\n\n(macro get (obj ...keys)\n       [(transpile obj)\n         (map keys (#(key)\n                     (var transpiled (transpile key)\n                          output (output-formatter transpiled))\n\n                     (if (match-regex? output \"^\\\"[a-zA-Z0-9_]+\\\"$\")\n                         [\".\" (replace-all output \"\\\"\" \"\") ]\n                         [\"[\" transpiled \"]\"])))])\n\n(docs \"assigns object properties to `arr` in pairs, alternating between keys and values.\nWhen javascript dot notation can be used (`a.b = 3`), it is.  Otherwise, bracket notation is used\"\n      tags [collections objects]\n      examples [ (set an-object 'static-attribute-name 'value)\n                 (set object dynamic-attribute-name \"key name determined at runtime\")\n                 (set array 0 \"first element of array\")\n                 (set object \"can't be dotted\" 'value)\n                 (set object 'first-attribute 'first-value\n                      'second-attribute 'second-value) ])\n\n(macro set (arr ...kv-pairs)\n       (interleave \"\\n\" (bulk-map kv-pairs (#(k v) `(assign (get @arr @k) @v)))))\n\n\n\n(docs \"returns the property names of `obj`.\"\n      tags [objects collections]\n      references: [ \"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys\" ]\n      example (keys { a 1 b 2 }))\n(macro keys (obj)\n       '(Object.keys @obj))\n\n\n(docs \"uses the javascript delete keyword on any number of `objects`.\n      Use in conjunction with `get` or dotted literal notation (a.b).\"\n      tags [objects collections]\n      examples [ (delete object.a object.b)\n                 (delete (get object attribute) (get object \"other attribute\")) ])\n(macro delete (...objects)\n       (interleave \"\\n\" (map objects (#(obj)\n                                 (as-statement [\"delete \" (transpile obj)])))))\n\n\n(docs \"iterates over each attribute in `obj`\"\n      tags [objects collections]\n      example (each-key key { a 1 b 2 } (console.log key)))\n(macro each-key (as obj ...body)\n       `(pipe @obj (keys)\n              (.for-each (lambda @{ args: (if (node? as 'expression) as [as])\n                                    node: this }\n                                 ...@body))))\n","(namespace core)\n\n(docs \"Defines a lambda/function/closure in Sibilant. Equivalent to\nthe `function` keyword in JavaScript. Most of the time `args` is a\nparen-wrapped list of arguments, which can include one triple-dotted\nsplat in the terminal position.  The last expression of `body` will be\nreturned. Aliased as `#`, as shown in examples.\"\n      tags [ functions language ]\n      examples [ (lambda (a b c) (|> a (+ b) (/ c)))\n(lambda (a b ...numbers)\n        (console.log (\"a: \"a\", b: \"b\"\"))\n        (numbers.map (#-> (+ 10))))\n(#({ destructured-object }) (destructured-object))\n(#([ one two three ]) { one& two& three& })\n(|> document.body\n    (.add-event-listener\n     (#(event)\n       (console.log (\"click at point (\"event.x\",\"event.y\")\"))\n       (event.prevent-default)))) ])\n\n      \n\n(macro lambda (args-or-options ...body)\n       (debug! 3 args-or-options)\n       (var args (or args-or-options.args args-or-options)\n            body (or args-or-options.body body)\n            node (or args-or-options.node this)\n            args (if (node? args 'expression 'bracket) args.contents\n                     (and (node? args) (empty? body)) (do (assign body [ args ]) [])\n                     (node? args 'brace) [ args ]\n                     args)\n            name (when args-or-options.name\n                       (|> args-or-options.name\n                           transpile\n                           output-formatter\n                           (replace-all \"\\\\W+\" \"$\")\n                           (.concat \"$\")))\n            rest (detect args (#-> (node? 'dots)))\n\n            destructured-args (map args (#(arg)\n                                          (if (node? arg 'bracket 'brace)\n                                              (do (var arg-name (generate-symbol (make-symbol-clue arg)))\n                                                  { arg-name &\n                                                    destructured-pair [ arg arg-name ] })\n                                              { arg-name arg })))\n\n            destructured-statements (|> [ (when (exists? rest) [ rest `(Array.prototype.slice.call arguments @(- args.length 1)) ])\n                                          ...(map destructured-args (#-> (get 'destructured-pair))) ]\n                                        flat-compact))\n\n       (assign node (detect\n                     [ node args-or-options.name args (first body) ]\n                     (#(n) (and (node? n) (get n 'file)))))\n\n\n       [\"(function\" (if name (\" \" name) \"\") \"(\"\n         (interleave \", \" (map destructured-args (#-> (get 'arg-name)))) \") {\"\n         (when (and sibilant.state.function-comments (or name node))\n               (indent [\"/*\"\n                         (when name (\" \" (sibilant.pretty-print args-or-options.name false)))\n                         (when node (\" \" node.file \":\" node.line \":\" node.col))\n                         \" */\"]))\n         (when destructured-statements.length (indent `(var ...@destructured-statements)))\n         (indent (apply ^do body))\n         \"})\"])\n\n(alias-macro lambda #)\n(docs \"most often called as its alias, `#>`, thunk creates a function\nwith no named arguments. To refer to arguments anonymously, use #n,\nsuch as #0 for the first argument.\"\n      tags [functions language]\n      examples: [ (.map [ 1 2 3 ] (#> (+ 1 #0)))\n                  (window.set-timeout (#> (console.log 'here)) 10) ])\n(macro thunk (...body)\n       (var node this\n            lambda-options { node node args [] })\n\n       (when (not (node? (first body)))\n             (merge-into lambda-options (first body))\n             (assign body (rest body)))\n\n       '(lambda @lambda-options\n       ...@(map-node body\n                 (#(node)\n                   (if (node? node 'arg-placeholder)\n                       '(argument @(replace node.token \"^#\" \"\"))\n                       node)))))\n(alias-macro thunk #>)\n\n(macro return (token)\n     (when sibilant.debug (console.log \"returning \" (prettify token)))\n     (var default-return (as-statement [\"return \" (transpile token)]))\n     (if (and token token.contents token.contents.length)\n         (switch (get (first token.contents) 'token)\n                 (('return 'throw 'do) (transpile token))\n\n                 ('delete\n                  (var delete-macro (get macros 'delete))\n                  (if (< token.contents.length 3) default-return\n                      [ (as-statement (apply delete-macro (token.contents.slice 1 -1)))\n                        \"\\nreturn \"\n                        (as-statement (call delete-macro (last token.contents)))]))\n\n                 ('def\n                  [ (transpile token) \"\\n\" (^return (second token.contents)) ])\n\n                 ('assign\n                  (if (< token.contents.length 4) default-return\n                      (do\n                       (var result (clone (transpile token)))\n                       (set result 'contents [ ...(result.contents.slice 0 -4)\n                                               \"return \"\n                                               ...(result.contents.slice -4) ])\n                       result)))\n\n                 ('var\n                  [ (transpile token) \"\\n\" (^return (if (even? token.contents.length)\n                                                                 (last token.contents)\n                                                                 (first (token.contents.slice -2))))])\n\n                 ('set\n                  (if (< token.contents.length 5) default-return\n                      (do\n                       (var obj (second token.contents)\n                            non-return-part (token.contents.slice 2 (- token.contents.length 2))\n                            return-part (token.contents.slice -2))\n                       (non-return-part.unshift obj)\n                       (return-part.unshift obj)\n                       [ (^set ...non-return-part)\n                         \"\\nreturn \"\n                         (^set ...return-part)])))\n\n                 (default default-return))\n         default-return))\n\n\n(macro do (...body)\n     (if (= 1 body.length)\n         (^return (first body))\n\n         body.length\n         [\n          (|> body\n              (.slice 0 -1)\n              (map (#-> as-statement))\n              (interleave \"\\n\"))\n           \"\\n\"\n           (^return (last body))\n           ]\n         \n         \"\"))\n\n\n(docs \"defines a function in the local scope. `name` is the\nvariable name that the function will be stored as.  Note that sibilant\ndoes *not* support hoisting. `args` is a paren-wrapped list of\narguments, as shown in the examples.  `body` can be any number of\nstatements, the last of which will be the return value of the\nfunction.\"\n      examples [ (def square (x) (* x x)) ]\n      tags [ language functions ])\n\n(macro def (name args ...body)\n       (var node this)\n       (when (node? name 'expression)\n             (assign body [ args ...body ]\n                     args (merge-with name { contents (rest name.contents)})\n                     name (first name.contents)))\n\n                     \n     (if (undefined? name) (error \"invalid function definition. missing name.\")\n         (undefined? args) (error \"invalid function definition. missing arguments or return value.\"))\n\n     (sibilant.docs.record 'function (first sibilant.macros.search-path) name node)\n\n     (if (match? (regex \"\\\\.\") (|> name transpile output-formatter))\n         `(assign @name (lambda @{ name& args& node& body& }))\n         `(var @name (lambda @{ name& args& node& body& }))))\n\n\n\n(docs \"This is the macro that is executed when a function is the first\nelement in an expression. Assuming that there is no macro named\n`a`, `(a b c)` internatlly compiles to `(call a b c)`. splats (`...`)\ncan be used in function calls.\"\n      examples [ (call a b c) (call a b ...c) (call a ...args) ]\n      tags [ functions language ])\n\n(macro call (fn-name ...args)\n     (if (any? args (#> (node? #0 'dots)))\n           (macros.apply fn-name (macros.list ...args))\n           [ (transpile fn-name)\n                   \"(\" (interleave \", \" (map args transpile)) \")\" ]))\n(docs \"calls the `method` on `object` as a function with `args` as the arguments\"\n      tags [ functions ]\n      example (send object method first-argument second-argument third-argument))\n\n(macro send (object method ...args)\n       [(transpile object) \".\" (transpile method)\n               \"(\" (interleave \", \" (map args transpile)) \")\"])\n\n\n\n\n\n(docs \"calls the function `fn` with arguments passed as an array in `arglist`\"\n      tags [functions]\n      example (apply my-function [ first-arg second-arg third-arg ]))\n\n(macro apply (fn arglist)\n       '(.apply @fn this @arglist))\n\n(docs \"executes the `body` inside of a self-executing function. The\nlast statement/expression of the body is returned.\"\n      tags [functions]\n      examples [(scoped true) (scoped (var a 1) (+ a 2))])\n(macro scoped (...body)\n       '(.call (lambda @{node this args []} ...@body) this))\n\n\n(macro *scoped-without-return (...body)\n       [\"(function() {\" (indent ...body) \"}).call(this)\"])\n\n\n(macro *scoped-without-source (...body)\n       `(*scoped-without-return (do ...@body)))\n\n(docs \"transforms function arguments into an array, using the Array prototype's slice\"\n      tags [functions]\n      example (arguments))\n(macro arguments (...args)\n       `(Array.prototype.slice.call arguments ...@args))\n\n\n(docs \"`get`s the argument at `index` in the current function context. Inside of a `thunk` (`#>`), this can be abbreviated with `#n`, where `n` is the argument index.\"\n      tags [functions]\n      example (argument 3))\n(macro argument (index)\n       '(get arguments @index))\n","(namespace core)\n(docs \"returns true if the `string` matches `regexp`.  Deprecated in\n      preference to `.match` (`send` dot-invocation).\"\n      tags [regex strings]\n      example: (match? (regex \"^[a-z]+$\" 'i) 'word))\n(macro match? (regexp string)\n       '(.match @string @regexp))\n\n(docs \"similar to `match?` but builds a regex out of the `pattern` and `flags`.\"\n      tags [regex strings]\n      example (match-regex? 'word \"^[a-z]+$\" 'i))\n(macro match-regex? (string pattern flags)\n       '(match? (regex @pattern @flags) @string))\n\n\n(docs \"replaces the first occurance of `pattern` (as a regex) with `replacement`\"\n      tags [regex strings]\n      example: (replace \"hello world\" \"l+o\" \"y there,\"))\n(macro replace (string pattern replacement)\n       '(.replace @string\n              (regex @pattern)\n              @replacement))\n\n(docs \"replaces all occurrances of `pattern` (as a regex) with `replacement`\"\n      tags [regex strings]\n      example: (replace-all \"503-555-1212\" \"[0-9]\" \"#\"))\n(macro replace-all (string pattern replacement)\n       '(.replace @string (regex @pattern 'g) @replacement))\n\n(docs \"builds a regex using `pattern` and `flags` as arguments to the RegExp constructor\"\n      tags [regex]\n      examples [ (regex \"[0-9]+\") (regex \"0x[0-9a-f]+\" 'i)])\n(macro regex (pattern flags)\n       '(new RegExp @pattern @(or flags 'undefined)))\n\n","(namespace core)\n\n(docs \"evaluates the `body` as long as `condition` is truthy,\nreturning the value of the last expression in `block` when `condition`\nceases to be truthy. See also `until`\"\n      tags [loops flow-control]\n      example: (while (> 5 i) (console.log i) (decr i)))\n(macro while (condition ...body)\n       (var symbol (generate-symbol 'while))\n       '(*scoped-without-source\n         (var @symbol)\n         @{ type 'output\n               contents [\"while (\" (transpile condition) \") {\"\n                          (indent '(assign @symbol (*scoped-without-source ...@body)))\n                          \"}\"] }\n         @symbol))\n\n\n\n\n(docs \"evaluates the `body` as long as `condition` is falsy,\nreturning the value of the last expression in `block` when `condition`\nceases to be falsy. See also `while`\"\n      tags [loops flow-control]\n      example: (until (< 5 i) (console.log i) (incr i)))\n\n(macro until (condition ...body)\n       '(while (not @condition) ...@body))\n\n\n","(namespace core)\n(docs \"predicate to test for equality with zero\"\n      tags [numbers]\n      example: (zero? n))\n(macro zero? (item) '(= @item 0))\n\n\n(docs \"returns true if the array `arr` has a length of zero\"\n      tags [arrays collections]\n      example: (empty? []))\n(macro empty? (arr)\n       `(= 0 (length @arr)))\n\n\n(docs \"returns true if `number` is not divisible by 2\"\n      tags [numbers]\n      example (odd? 5))\n(macro odd? (number)\n       '(= 1 (mod @number 2)))\n\n\n(docs \"returns true if `number` is divisible by 2 with no remainder\"\n      tags [numbers]\n      example (even? 10))\n(macro even? (number)\n       '(= 0 (mod @number 2)))\n(docs \"returns true if all of the `things` are javascript strings\"\n      tags [strings type]\n      examples: [ (string? test-object) (string? 'yes 'yes 'yes) ])\n(macro string? (...things)\n       '(and ...@(map things (#(thing) '(= (typeof @thing) 'string)))))\n\n\n(docs \"returns true if all of the `things` are functions\"\n      tags [functions type]\n      examples: [ (function? fn) (function? err cb) ])\n(macro function? (...things)\n       '(and ...@(map things (#(thing) '(= (typeof @thing) 'function)))))\n(docs \"returns true if all of the `things` are undefined, as tested\nwith `typeof`, not equality with literal undefined. This is the\ninverse of `defined?`\"\n      tags [type]\n      examples: [ (undefined? argument)\n                  (undefined? 1 2 undefined) ])\n(macro undefined? (...things)\n       '(and ...@(map things (#(thing) '(= (typeof @thing) 'undefined)))))\n\n(docs \"returns true if none of the `things` are undefined, as tested\nwith `typeof`. This is the inverse of `undefined?`\"\n      tags [type]\n      examples: [ (defined? variable)\n                  (defined? var1 var2 var3) ])\n(macro defined? (...things)\n       '(and ...@(map things (#(thing) '(!= (typeof @thing) 'undefined)))))\n\n\n(docs \"returns true if all of the `things` are numbers, as tested\nwith `typeof`\"\n      tags [numbers type]\n      examples: [ (number? 1) (number? 1 2 3) ])\n(macro number? (...things)\n       '(and ...@(map things (#(thing) '(= (typeof @thing) 'number)))))\n\n\n(docs \"returns true if `thing` is an array in javascript. aliased as\n`list?`.\"\n      tags [type arrays]\n      example: (array? arr))\n\n(macro array? (thing)\n       `(and\n         @thing\n         (= 'object (typeof @thing))\n         (= 'Array (get @thing 'constructor 'name))))\n(alias-macro array? list?)\n\n\n(docs \"returns true if `thing` is an object that is not an array in javascript. aliased as\n`object?`.\"\n      tags [type objects]\n      example: (object? arr))\n\n(macro hash? (thing)\n       `(and (= 'object (typeof @thing))\n             (!= @thing null)\n             (!= (get @thing 'constructor 'name) 'Array)))\n(alias-macro hash? object?)\n\n\n(docs \"uses the javascript `instanceof` operator to check if `item` is of `type`.\"\n      tags [language type]\n      example (instance-of? (new Date) Date))\n(macro instance-of? (item type)\n       `(parens (transpile item) \" instanceof \" (transpile type)))\n\n\n\n(docs \"similar to the javascript truthiness predicate `as-boolean`, returns true unless the `thing` is undefined or null\"\n      tags [type]\n      example (exists? window))\n(macro exists? (thing)\n       `(and (defined? @thing) (!= @thing null)))\n\n\n(docs \"checks if `object` has property `key`.  returns true or false.\"\n      tags [objects collections]\n      example (has-key? object 'a))\n\n(macro has-key? (object key)\n       `(.has-own-property @object @key))\n\n(docs \"checks if a string is identical to the lower-cased version of itself\"\n      tags [strings]\n      example (lower-case? \"abc\"))\n(macro lower-case? (str)\n       `(and\n         (!= (.to-upper-case @str) @str)\n         (= (.to-lower-case @str) @str)))\n\n\n\n(docs \"checks if a string is identical to the upper-cased version of itself\"\n      tags [strings]\n      example (lower-case? \"abc\"))\n(macro upper-case? (str)\n       `(and\n         (!= (.to-lower-case @str) @str)\n         (= (.to-upper-case @str) @str)))\n","(def debug! (level ...message)\n     (var {debug} sibilant)\n     (when (and debug (<= level debug))\n           (message.for-each (#-> console.log))))\n\n(def recurse-indent (arg)\n     (case arg\n           node? (merge-into arg { contents (|> arg.contents flat-compact recurse-indent) })\n           list? (map arg recurse-indent)\n           number? (arg.to-string)\n           string? (|> arg\n                       (replace-all \"\\\\n\" \"\\n  \")\n                       (replace-all \"\\\\n\\\\s+\\\\n\" \"\\n\\n\"))\n           arg))\n\n(def indent (...args)\n     [\"\\n  \" (recurse-indent (map args transpile)) \"\\n\"])\n\n(def escape-regex (string)\n     (string.replace (regex \"[\\\\-\\\\[\\\\]\\\\/\\\\{\\\\}\\\\(\\\\)\\\\*\\\\+\\\\?\\\\.\\\\\\\\\\^\\\\$\\\\|]\" 'g) \"\\\\$&\"))\n\n(def qescape (content)\n     (case content\n           (|> exists? not) \"\"\n           string? (|> content\n                       (.split (first \"\\\\\\\\ \"))\n                       (.join (.slice \"\\\\\\\\ \" 0 -1))\n                       (replace-all \"\\\"\" \"\\\\\\\"\")\n                       (replace-all \"\\\\n\" \"\\\\n\\\" +\\n\\\"\"))\n           content))\n\n(def map-node (node fn)\n     (case node\n           node? (do\n                  (var mapped-node (fn node))\n                  (when (node? mapped-node)\n                        (set mapped-node 'contents (map-node mapped-node.contents fn)))\n\n                  mapped-node)\n\n           list? (map node (#> (map-node #0 fn)))\n\n           (fn node)))\n\n(def each-node (node fn)\n     (case node\n           node? (when (fn node) (each-node node.contents fn))\n           list? (each (c) node (each-node c fn))\n           (fn node)))\n\n(def statement? (transpiled)\n     (case transpiled\n           node? (statement? transpiled.contents)\n           list? (statement? (last transpiled))\n           string? (= \";\" (last transpiled))\n           false))\n\n(def as-statement (node)\n     (var transpiled (transpile node))\n     (case transpiled\n           empty-node? undefined\n           statement? transpiled\n           [ transpiled \";\" ]))\n\n(def unquote? (node) (node? node 'at))\n\n(def find-unquotes (node)\n     (var unquotes {})\n     (each-node node (#(n)\n                       (when (unquote? n)\n                             (set unquotes n.node-id (transpile n)))\n                       (not (node? n 'tick))))\n     unquotes)\n\n(def splice-dots (node)\n     (when (and node (list? node.contents))\n           (var contents [])\n           (each (content) node.contents\n                 (if (and (node? content 'dots)\n                          (list? content.contents)\n                          (= content.contents.length 1)\n                          (list? (first content.contents)))\n                     (contents.push.apply contents (first content.contents))\n                     (contents.push content)))\n\n           (set node 'contents contents))\n     node)\n\n\n(def alternating-keys-and-values (hash)\n     (|> hash keys\n         (map (#(key) [key (get hash key)]))\n         flatten))\n\n(def map-node-for-quote-expansion (node expansions)\n     (case node\n           node? (do\n                  (var mapped-node (if (expansions.has-own-property node.node-id) (get expansions node.node-id) (clone node)))\n                  (when (node? mapped-node)\n                        (set mapped-node 'contents (map-node-for-quote-expansion mapped-node.contents expansions)))\n\n                  (assign mapped-node (splice-dots mapped-node))\n                  mapped-node)\n\n           list? (map node (#> (map-node-for-quote-expansion #0 expansions)))\n\n           node))\n\n(def dots-and-at (content)\n     (and (node? content 'dots)\n          (= 3 content.token.length)\n          (node? (first content.contents) 'at)))\n\n(def replace! (content)\n     (case content\n           dots-and-at (merge-with content\n                                   { contents (|> content.contents first transpile list) })\n\n           (node? 'at) (|> content.contents first transpile)\n           (node? 'tick) (JSON.stringify content)\n           object? (^hash ...(|> content keys\n                                 (.reduce\n                                  (#-> (.concat [ #1 (replace! (get content #1)) ]))\n                                  [])))\n           list? (^list ...(map content replace!))\n           undefined? 'undefined\n           number? (content.to-string)\n           (JSON.stringify content)))\n\n\n\n(def node? (thing type type2 type3 type4 test-arg)\n     (var a arguments)\n     (and thing thing.type thing.contents\n     (if test-arg\n         (includes? (Array.prototype.slice.call a 1) thing.type)\n\n         type (distribute thing.type or\n                          (= type)\n                          (= type2)\n                          (= type3)\n                          (= type4))\n\n         true)))\n\n\n\n(def empty-node? (item)\n     (case item\n           (= null) true\n           undefined? true\n           (= false) true\n           string? (match-regex? item \"^\\\\s*$\")\n           list? (all? item empty-node?)\n           node? (empty-node? item.contents)\n           false))\n\n(def compact-node (item)\n     (case item\n           node? (do\n                  (set item 'contents (compact-node item.contents))\n                  (if (and item.contents item.contents.length) item null))\n           list? (do\n                  (var compacted (compact (map item compact-node)))\n                  (if (and compacted compacted.length) compacted null))\n\n           (distribute or (= \"\") (= false)) null\n\n           item))\n\n(def generate-symbol (clue)\n     (var {state} sibilant)\n     (default clue 'temp\n              state.symbol-counts {})\n     (var count (|> state.symbol-counts\n         (get clue)\n         (or 0)\n         (+ 1)))\n     (set state.symbol-counts clue count)\n     [(\"\"clue\"$\"count)])\n\n(def make-symbol-clue (node)\n     (var target-node (if (and (node? node 'expression) (|> node.contents first (get 'token) (= 'require)))\n             (|> node.contents second)\n             (node? node 'expression) (first node.contents)\n             node))\n     (|> (try (|> target-node transpile output-formatter)\n              (sibilant.pretty-print node false))\n         (replace-all \"[^a-zA-Z]+\" \"_\")\n         (replace-all \"^_|_$\" \"\")\n         (.slice 0 15)))\n\n(def destructure (pairs)\n     (var destructured [])\n     (bulk-map pairs (#(lhs rhs)\n                       (var transpiled-rhs (transpile rhs))\n                       (switch lhs.type\n                               ('bracket\n                                (var literal-rhs? (|> transpiled-rhs (output-formatter) (match-regex? \"^[\\._a-zA-Z0-9$]+$\"))\n                                     source (if literal-rhs?\n                                                transpiled-rhs\n                                                (do                             \n                                                 (var symbol (generate-symbol (make-symbol-clue rhs)))\n                                                 (destructured.push [symbol transpiled-rhs])\n                                                 symbol)))\n                                (each (item index) lhs.contents\n                                      (destructured.push [(transpile item) '(get @source @index)]))\n                                (unless literal-rhs?\n                                        (destructured.push [source 'undefined])))\n                               ('brace\n                                (var literal-rhs? (|> transpiled-rhs (output-formatter) (match-regex? \"^[\\._a-zA-Z0-9$]+$\"))\n                                     source (if literal-rhs?\n                                                transpiled-rhs\n\n                                                (= 1 (length lhs.contents)) [\"(\" rhs \")\"]\n                                                \n                                                (do                             \n                                                 (var symbol (generate-symbol (make-symbol-clue rhs)))\n                                                 (destructured.push [symbol transpiled-rhs])\n                                                 symbol)))\n                                (each (item index) lhs.contents\n                                      (var tr-item (transpile item))\n                                      (destructured.push [tr-item '(get @source @[\"\\\"\" tr-item \"\\\"\"])]))\n                                (unless (or literal-rhs? (= 1 (length lhs.contents)))\n                                        (destructured.push [source 'undefined])))\n\n                               (default\n                                (destructured.push [ (transpile lhs)\n                                                     (if rhs transpiled-rhs 'undefined)])))))\n     destructured)\n","(namespace core)\n\n\n(docs \"This is the macro that is called when brackets (`[]`) are\nused. Emits a javascript array literal. Splats (`...`) can be used to\nin-line other arrays.\"\n      tags [arrays collections]\n      examples [ (list 1 2 3 4 5)\n                 [ 'a 'b 'c 'd 'e ]\n                 [ a b ...c d ...e ] ])\n      \n(macro list (...args)\n       (var arg-segments [])\n       (if (empty? args) \"[]\"\n           (do\n            (def simple-list (args)\n                 [\"[ \" (interleave \", \" (map args (#(arg) arg.transpiled))) \" ]\"])\n\n            (args.for-each (#(arg)\n                  (if (node? arg 'dots) (arg-segments.push {transpiled (transpile arg)})\n                   (list? (last arg-segments)) (.push (last arg-segments) { transpiled (transpile arg)})\n                   (arg-segments.push [{transpiled (transpile arg)}]))))\n\n            (assign arg-segments (map arg-segments\n                                      (#(segment)\n                                        (if (list? segment)\n                                            (simple-list segment)\n                                            segment.transpiled))))\n\n            (if (= 1 (length arg-segments))\n                (first arg-segments)\n                [(first arg-segments) \".concat(\" (interleave \", \" (rest arg-segments))\")\"]))))\n\n(docs \"fetches length attribute from `arr`\"\n      tags [ arrays collections ]\n      example (length [ 1 2 3 ]))\n(macro length (arr)\n       '(get @arr 'length))\n\n\n(docs \"`get`s the first element of `arr`\"\n      tags [ arrays collections ]\n      example (first `[ a b c d e ]))\n(macro first (arr) `(get @arr 0))\n\n(docs \"`get`s the second element of `arr`\"\n      tags [ arrays collections ]\n      example (second `[ a b c d e ]))\n(macro second (arr) `(get @arr 1))\n\n(docs \"`get`s the third element of `arr`\"\n      tags [ arrays collections ]\n      example (third `[ a b c d e ]))\n(macro third (arr) `(get @arr 2))\n\n\n(docs \"fetches all but the first item of `arr`\"\n      tags [arrays collections]\n      example (rest [ 1 2 3 ]))\n(macro rest (arr) '(.slice @arr 1))\n\n(docs \"fetches just the last element of `arr` by slicing.\"\n      tags [arrays collections]\n      example (last [ 1 2 3 ]))\n(macro last (arr) '(first (.slice @arr -1)))\n\n\n\n(docs \"builds an array with `first` as the zeroth index and the\nelements provided by array `rest` as the subsequent elements, as\nsiblings with `first`.\"\n      tags [arrays collections deprecated]\n      example (cons 1 [ 2 3 4 ]))\n\n(macro cons (first rest)\n       `(pipe\n         (list @first)\n         (.concat @rest)))\n\n\n(docs \"adds `additional` elements onto the right-side (tail) of `list`. deprecated\"\n      tags [ arrays collections deprecated ]\n      example (append [ 1 2 3 ] 4 5 6))\n(macro append (list ...additional)\n       `(.concat @list (list ...@additional)))\n\n(docs \"iterates over `array`, evaluating `body` once for each value in\n`array`.  If `item` is a literal name, that will be the variable into\nwhich the `array` element is yielded (current value).  If `item` is an expression, it\ncan contain the current value, the index, and the `array`.\"\n      tags [ arrays language collections ]\n      references [\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach\"]\n      examples [ (each number [ 1 2 3 ] (console.log number))\n                 (each (letter index) `[ a b c d ]\n                       (set letters letter index)\n                       (pipe letter (.to-upper-case) (console.log))) ])\n\n(macro each (item array ...body)\n       (var node this\n            args (if (node? item 'expression) item [item]))\n       `(|> @array\n            (.for-each (lambda @{ node& args& body& }))))\n\n\n(docs \"returns true if `haystack` includes `needle`.  `haystack` can be a string or array/list.\"\n      tags [arrays collections]\n      examples [ (includes? 'hello 'h) (includes? `[ Veni vidi vici] 'vidi) ])\n(macro includes? (haystack needle)\n       `(pipe @haystack (.index-of @needle) (!= -1)))\n\n(docs \"returns true if `haystack` does NOT include `needle`.\n`haystack` can be a string or array/list\"\n      tags [arrays collections]\n      examples [ (excludes? 'hello 10) (excludes? `[ Veni vidi vici] 'attenti) ])\n(macro excludes? (haystack needle)\n       `(pipe @haystack (.index-of @needle) (= -1)))\n\n"]}