2018-01-31 22:39:18 +00:00
|
|
|
(def defmacro macro
|
|
|
|
(fn [name & more] (tuple 'def name 'macro (tuple-prepend (tuple-prepend more name) 'fn))))
|
|
|
|
|
|
|
|
(defmacro defn
|
|
|
|
[name & more]
|
|
|
|
(tuple 'def name (tuple-prepend (tuple-prepend more name) 'fn)))
|
|
|
|
|
|
|
|
(defmacro when
|
|
|
|
[cond & body]
|
|
|
|
(tuple 'if cond (tuple-prepend body 'do)))
|
|
|
|
|
|
|
|
(def seq (do
|
|
|
|
(defn array-seq [x]
|
|
|
|
(def len (length x))
|
|
|
|
(var i 0)
|
|
|
|
{
|
|
|
|
:more (fn [] (< i len))
|
|
|
|
:next (fn []
|
|
|
|
(def ret (get x i))
|
|
|
|
(varset! i (+ i 1))
|
|
|
|
ret)
|
|
|
|
})
|
|
|
|
(def seqs {
|
|
|
|
:array array-seq
|
|
|
|
:tuple array-seq
|
|
|
|
:struct (fn [x] x)})
|
|
|
|
(fn [x]
|
|
|
|
(def makeseq (get seqs (type x)))
|
|
|
|
(if makeseq (makeseq x) (error "expected sequence")))))
|
|
|
|
|
|
|
|
(defn range [top]
|
|
|
|
(var i 0)
|
|
|
|
{
|
|
|
|
:more (fn [] (< i top))
|
|
|
|
:next (fn []
|
|
|
|
(def ret i)
|
|
|
|
(varset! i (+ i 1))
|
|
|
|
ret)
|
|
|
|
})
|
|
|
|
|
|
|
|
(defn doseq [s]
|
|
|
|
(def s (seq s))
|
|
|
|
(def more? (get s :more))
|
|
|
|
(def getnext (get s :next))
|
|
|
|
(while (more?)
|
|
|
|
(getnext)))
|
|
|
|
|
|
|
|
(defn map [f s]
|
|
|
|
(def s (seq s))
|
|
|
|
(def more (get s :more))
|
|
|
|
(def getnext (get s :next))
|
|
|
|
{
|
|
|
|
:more more
|
|
|
|
:next (fn [] (f (getnext)))
|
|
|
|
})
|
|
|
|
|
|
|
|
(defn reduce [f start s]
|
|
|
|
(def s (seq s))
|
|
|
|
(def more? (get s :more))
|
|
|
|
(def getnext (get s :next))
|
|
|
|
(var ret start)
|
|
|
|
(while (more?)
|
|
|
|
(varset! ret (f ret (getnext))))
|
|
|
|
ret)
|
|
|
|
|
|
|
|
(defmacro for [head & body]
|
2018-02-03 22:22:04 +00:00
|
|
|
(def head (ast-unwrap1 head))
|
2018-01-31 22:39:18 +00:00
|
|
|
(def sym (get head 0))
|
|
|
|
(def start (get head 1))
|
|
|
|
(def end (get head 2))
|
|
|
|
(def _inc (get head 3))
|
|
|
|
(def inc (if _inc _inc 1))
|
|
|
|
(tuple 'do
|
|
|
|
(tuple 'var sym start)
|
|
|
|
(tuple 'while (tuple '< sym end)
|
|
|
|
(tuple-prepend body 'do)
|
|
|
|
(tuple 'varset! sym (tuple '+ sym 1))
|
|
|
|
)))
|
2018-02-03 22:22:04 +00:00
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(def pp (do
|
2018-02-03 22:22:04 +00:00
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(defn pp-seq [pp seen buf a start end]
|
|
|
|
(if (get seen a)
|
|
|
|
(buffer-push-string buf "<cycle>")
|
|
|
|
(do
|
|
|
|
(put seen a true)
|
|
|
|
(def len (length a))
|
|
|
|
(buffer-push-string buf start)
|
|
|
|
(for [i 0 len]
|
|
|
|
(when (not= i 0) (buffer-push-string buf " "))
|
|
|
|
(pp seen buf (get a i)))
|
|
|
|
(buffer-push-string buf end)
|
|
|
|
))
|
|
|
|
buf)
|
2018-02-03 22:22:04 +00:00
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(defn pp-dict [pp seen buf a start end]
|
|
|
|
(if (get seen a)
|
|
|
|
(buffer-push-string buf "<cycle>")
|
|
|
|
(do
|
|
|
|
(put seen a true)
|
|
|
|
(var k (next a nil))
|
|
|
|
(buffer-push-string buf start)
|
|
|
|
(while k
|
|
|
|
(def v (get a k))
|
|
|
|
(pp seen buf k)
|
|
|
|
(buffer-push-string buf " ")
|
|
|
|
(pp seen buf v)
|
|
|
|
(varset! k (next a k))
|
|
|
|
(when k (buffer-push-string buf " "))
|
|
|
|
)
|
|
|
|
(buffer-push-string buf end)
|
|
|
|
))
|
2018-02-03 22:22:04 +00:00
|
|
|
buf)
|
|
|
|
|
|
|
|
(def _printers {
|
2018-02-03 23:12:07 +00:00
|
|
|
:array (fn [pp seen buf x] (pp-seq pp seen buf x "[" "]"))
|
|
|
|
:tuple (fn [pp seen buf x] (pp-seq pp seen buf x "(" ")"))
|
|
|
|
:table (fn [pp seen buf x] (pp-dict pp seen buf x "@{" "}"))
|
|
|
|
:struct (fn [pp seen buf x] (pp-dict pp seen buf x "{" "}"))
|
2018-02-03 22:22:04 +00:00
|
|
|
})
|
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(defn _default_printer [pp seen buf x]
|
|
|
|
(buffer-push-string buf (string x))
|
|
|
|
buf)
|
2018-02-03 22:22:04 +00:00
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(defn pp1 [seen buf x]
|
2018-02-03 22:22:04 +00:00
|
|
|
(def pmaybe (get _printers (type x)))
|
|
|
|
(def p (if pmaybe pmaybe _default_printer))
|
2018-02-03 23:12:07 +00:00
|
|
|
(p pp1 seen buf x))
|
2018-02-03 22:22:04 +00:00
|
|
|
|
2018-02-03 23:12:07 +00:00
|
|
|
(fn [x] (print (pp1 @{} @"" x)))
|
|
|
|
))
|