(namespace core)
(docs "registers variables in `pairs` inside of the current scope using the javascript var keyword.
destructuring from arrays and objects is also supported, as shown in the examples. Note: `:` and `,` are always ignored."
      tags [ variables language ]
      examples: [ (var a)
                  (var a: 1, b: 2)
(var a [ 1 2 3 ]
     [ b c d ] a)
                  (var {attribute} { attribute: 'hi })
                  (var {log dir} console)
(var {a}: {a 1 b 2},
     {c d}: {c 3 d 4})
])

(macro var (...pairs)
       (as-statement
        ["var " (|> pairs
                    destructure
                    (map (#(pair) [(first pair) " = " (second pair)]))
                    (interleave ",\n    ")) ]))

(docs "registers constants in `pairs` inside of the current scope using the javascript const keyword.
destructuring from arrays and objects is also supported, as shown in the examples. Note: `:` and `,` are always ignored."
      tags [ variables language ]
      examples: [ (const a)
                  (const a: 1, b: 2)
(const a [ 1 2 3 ]
     [ b c d ] a)
                  (const {attribute} { attribute: 'hi })
                  (const {log dir} console)
(const {a}: {a 1 b 2},
     {c d}: {c 3 d 4})
])

(macro const (...pairs)
      (as-statement
        ["const " (|> pairs
                    destructure
                    (map (#(pair) [(first pair) " = " (second pair)]))
                    (interleave ",\n    ")) ]))


(docs "assigns alternating keys and values in `args`.  This works much
like `var`, but without the var keyword.  It is important to
understand variable scope in javascript in order to use this macro safely.
This macro supports destructuring, as shown in examples"
      tags [language variables]
      examples [ (assign a 1)
(assign a: 1, b: 2)
(assign [ right left ] [ left right ])
(assign {log} console)
(assign [ a b ] c)
(assign { a b } c
        [ x y ] a)])

(macro assign (...pairs)
        (|> pairs
            destructure
            (map (#(pair) (as-statement [(first pair) " = " (second pair)])))
            (interleave "\n")))


(docs "sets default values for variables in current scope. `pairs` are
alternating variable names and default values"
      tags [variables language]
      example (default a 10 b 20))
(macro default (...pairs)
       (interleave "\n" (bulk-map pairs (#(name value)
                                  '(assign @name (ternary (defined? @name) @name @value))))))
