Update from master
[jackhill/mal.git] / io / MalCore.io
1 MalCore := Object clone do(
2 slurp := block(a,
3 f := File with(a at(0))
4 res := f contents
5 f close
6 res
7 )
8
9 dissoc := block(a,
10 res := MalMap withMap(a at(0))
11 a rest foreach(k, res removeKey(k))
12 res
13 )
14
15 nth := block(a,
16 if(a at(1) < a at(0) size,
17 a at(0) at(a at(1)),
18 Exception raise("nth: index out of range")
19 )
20 )
21
22 conj := block(a,
23 coll := a at(0)
24 coll type switch(
25 "MalList",
26 MalList with(a rest reverse appendSeq(coll)),
27 "MalVector",
28 MalVector with(coll appendSeq(a rest))
29 )
30 )
31
32 seq := block(a,
33 obj := a at(0)
34 (obj isNil) ifTrue(return(nil))
35 (obj type == "MalList") ifTrue(return(if(obj isEmpty, nil, obj)))
36 (obj type == "MalVector") ifTrue(return(if(obj isEmpty, nil, MalList with(obj))))
37 (obj type == "Sequence") ifTrue(
38 if(obj isEmpty, return(nil))
39 lst := list()
40 obj foreach(i, c, lst append(obj inclusiveSlice(i, i)))
41 return(MalList with(lst))
42 )
43 nil
44 )
45
46 swapBang := block(a,
47 atom := a at(0)
48 newVal := a at(1) call(MalList with(list(atom val)) appendSeq(a slice(2)))
49 atom setVal(newVal) val
50 )
51
52 NS := Map with(
53 "=", block(a, a at(0) == a at(1)),
54 "throw", block(a, MalException with(a at(0)) raise),
55
56 "nil?", block(a, a at(0) isNil),
57 "true?", block(a, a at(0) == true),
58 "false?", block(a, a at(0) == false),
59 "string?", block(a, a at(0) type == "Sequence"),
60 "symbol", block(a, MalSymbol with(a at(0))),
61 "symbol?", block(a, a at(0) type == "MalSymbol"),
62 "keyword", block(a, MalKeyword with(a at(0))),
63 "keyword?", block(a, a at(0) type == "MalKeyword"),
64
65 "pr-str", block(a, a map(s, s malPrint(true)) join(" ")),
66 "str", block(a, a map(s, s malPrint(false)) join("")),
67 "prn", block(a, a map(s, s malPrint(true)) join(" ") println ; nil),
68 "println", block(a, a map(s, s malPrint(false)) join(" ") println ; nil),
69 "read-string", block(a, MalReader read_str(a at(0))),
70 "readline", block(a, MalReadline readLine(a at(0))),
71 "slurp", slurp,
72
73 "<", block(a, a at(0) < a at(1)),
74 "<=", block(a, a at(0) <= a at(1)),
75 ">", block(a, a at(0) > a at(1)),
76 ">=", block(a, a at(0) >= a at(1)),
77 "+", block(a, a at(0) + a at(1)),
78 "-", block(a, a at(0) - a at(1)),
79 "*", block(a, a at(0) * a at(1)),
80 "/", block(a, a at(0) / a at(1)),
81 "time-ms", block(a, (Date now asNumber * 1000.0) round),
82
83 "list", block(a, a),
84 "list?", block(a, a at(0) type == "MalList"),
85 "vector", block(a, MalVector with(a)),
86 "vector?", block(a, a at(0) type == "MalVector"),
87 "hash-map", block(a, MalMap withList(a)),
88 "map?", block(a, a at(0) type == "MalMap"),
89 "assoc", block(a, MalMap withMap(a at(0) merge(MalMap withList(a rest)))),
90 "dissoc", dissoc,
91 "get", block(a, a at(0) ifNil(return nil) get(a at(1))),
92 "contains?", block(a, a at(0) ifNil(return nil) contains(a at(1))),
93 "keys", block(a, a at(0) malKeys),
94 "vals", block(a, a at(0) malVals),
95
96 "sequential?", block(a, if(a at(0) ?isSequential, true, false)),
97 "cons", block(a, MalList with(list(a at(0)) appendSeq(a at(1)))),
98 "concat", block(a, MalList with(a reduce(appendSeq, list()))),
99 "nth", nth,
100 "first", block(a, a at(0) ifNil(return nil) first),
101 "rest", block(a, a at(0) ifNil(return MalList with(list())) rest),
102 "empty?", block(a, a at(0) ifNil(true) isEmpty),
103 "count", block(a, a at(0) ifNil(return(0)) size),
104 "apply", block(a, a at(0) call(MalList with(a slice(1, -1) appendSeq(a last)))),
105 "map", block(a, MalList with(a at(1) map(e, a at(0) call(MalList with(list(e)))))),
106
107 "conj", conj,
108 "seq", seq,
109
110 "meta", block(a, a at(0) ?meta),
111 "with-meta", block(a, a at(0) clone setMeta(a at(1))),
112 "atom", block(a, MalAtom with(a at(0))),
113 "atom?", block(a, a at(0) type == "MalAtom"),
114 "deref", block(a, a at(0) val),
115 "reset!", block(a, a at(0) setVal(a at(1)) ; a at(1)),
116 "swap!", swapBang
117 )
118 )