forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core.mal
87 lines (74 loc) · 1.9 KB
/
core.mal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
(def! inc (fn* (a) (+ a 1)))
(def! dec (fn* (a) (- a 1)))
(def! zero? (fn* (n) (= 0 n)))
(def! reduce
(fn* (f init xs)
(if (> (count xs) 0)
(reduce f (f init (first xs)) (rest xs))
init)))
(def! identity (fn* (x) x))
(def! every?
(fn* (pred xs)
(if (> (count xs) 0)
(if (pred (first xs))
(every? pred (rest xs))
false)
true)))
(def! not (fn* (x) (if x false true)))
(def! some
(fn* (pred xs)
(if (> (count xs) 0)
(let* (res (pred (first xs)))
(if (pred (first xs))
res
(some pred (rest xs))))
nil)))
(defmacro! and
(fn* (& xs)
(if (empty? xs)
true
(if (= 1 (count xs))
(first xs)
(let* (condvar (gensym))
`(let* (~condvar ~(first xs))
(if ~condvar (and ~@(rest xs)) ~condvar)))))))
(defmacro! or
(fn* (& xs)
(if (empty? xs)
nil
(if (= 1 (count xs))
(first xs)
(let* (condvar (gensym))
`(let* (~condvar ~(first xs))
(if ~condvar ~condvar (or ~@(rest xs)))))))))
(defmacro! cond
(fn* (& clauses)
(if (> (count clauses) 0)
(list 'if (first clauses)
(if (> (count clauses) 1)
(nth clauses 1)
(throw "cond requires an even number of forms"))
(cons 'cond (rest (rest clauses)))))))
(defmacro! ->
(fn* (x & xs)
(if (empty? xs)
x
(let* (form (first xs)
more (rest xs))
(if (empty? more)
(if (list? form)
`(~(first form) ~x ~@(rest form))
(list form x))
`(-> (-> ~x ~form) ~@more))))))
(defmacro! ->>
(fn* (x & xs)
(if (empty? xs)
x
(let* (form (first xs)
more (rest xs))
(if (empty? more)
(if (list? form)
`(~(first form) ~@(rest form) ~x)
(list form x))
`(->> (->> ~x ~form) ~@more))))))
nil