Change quasiquote algorithm
[jackhill/mal.git] / impls / fantom / src / mallib / fan / core.fan
CommitLineData
92708e34
DM
1class Core
2{
3 static private MalVal prn(MalVal[] a)
4 {
5 echo(a.join(" ") { it.toString(true) })
6 return MalNil.INSTANCE
7 }
8
9 static private MalVal println(MalVal[] a)
10 {
11 echo(a.join(" ") { it.toString(false) })
12 return MalNil.INSTANCE
13 }
14
15 static private MalVal readline(MalVal[] a)
16 {
17 line := Env.cur.prompt((a[0] as MalString).value)
18 return line == null ? MalNil.INSTANCE : MalString.make(line)
19 }
20
21 static private MalVal concat(MalVal[] a)
22 {
23 return MalList(a.reduce(MalVal[,]) |MalVal[] r, MalSeq v -> MalVal[]| { return r.addAll(v.value) })
24 }
25
26 static private MalVal apply(MalVal[] a)
27 {
28 f := a[0] as MalFunc
29 args := a[1..-2]
30 args.addAll(((MalSeq)a[-1]).value)
31 return f.call(args)
32 }
33
34 static private MalVal swap_bang(MalVal[] a)
35 {
36 atom := a[0] as MalAtom
37 MalVal[] args := [atom.value]
38 args.addAll(a[2..-1])
39 f := a[1] as MalFunc
40 return atom.set(f.call(args))
41 }
42
43 static Str:MalFunc ns()
44 {
45 return [
46 "=": MalFunc { MalTypes.toMalBool(it[0] == it[1]) },
47 "throw": MalFunc { throw MalException(it[0]) },
48
49 "nil?": MalFunc { MalTypes.toMalBool(it[0] is MalNil) },
50 "true?": MalFunc { MalTypes.toMalBool(it[0] is MalTrue) },
51 "false?": MalFunc { MalTypes.toMalBool(it[0] is MalFalse) },
52 "string?": MalFunc { MalTypes.toMalBool(it[0] is MalString && !((MalString)it[0]).isKeyword) },
53 "symbol": MalFunc { MalSymbol.makeFromVal(it[0]) },
54 "symbol?": MalFunc { MalTypes.toMalBool(it[0] is MalSymbol) },
55 "keyword": MalFunc { MalString.makeKeyword((it[0] as MalString).value) },
56 "keyword?": MalFunc { MalTypes.toMalBool(it[0] is MalString && ((MalString)it[0]).isKeyword) },
57 "number?": MalFunc { MalTypes.toMalBool(it[0] is MalInteger) },
58 "fn?": MalFunc { MalTypes.toMalBool(it[0] is MalFunc && !((it[0] as MalUserFunc)?->isMacro ?: false)) },
59 "macro?": MalFunc { MalTypes.toMalBool(it[0] is MalUserFunc && ((MalUserFunc)it[0]).isMacro) },
60
61 "pr-str": MalFunc { MalString.make(it.join(" ") |MalVal e -> Str| { e.toString(true) }) },
62 "str": MalFunc { MalString.make(it.join("") |MalVal e -> Str| { e.toString(false) }) },
63 "prn": MalFunc(#prn.func),
64 "println": MalFunc(#println.func),
65 "read-string": MalFunc { Reader.read_str((it[0] as MalString).value) },
66 "readline": MalFunc(#readline.func),
67 "slurp": MalFunc { MalString.make(File((it[0] as MalString).value.toUri).readAllStr) },
68
69 "<": MalFunc { MalTypes.toMalBool((it[0] as MalInteger).value < (it[1] as MalInteger).value) },
70 "<=": MalFunc { MalTypes.toMalBool((it[0] as MalInteger).value <= (it[1] as MalInteger).value) },
71 ">": MalFunc { MalTypes.toMalBool((it[0] as MalInteger).value > (it[1] as MalInteger).value) },
72 ">=": MalFunc { MalTypes.toMalBool((it[0] as MalInteger).value >= (it[1] as MalInteger).value) },
73 "+": MalFunc { MalInteger((it[0] as MalInteger).value + (it[1] as MalInteger).value) },
74 "-": MalFunc { MalInteger((it[0] as MalInteger).value - (it[1] as MalInteger).value) },
75 "*": MalFunc { MalInteger((it[0] as MalInteger).value * (it[1] as MalInteger).value) },
76 "/": MalFunc { MalInteger((it[0] as MalInteger).value / (it[1] as MalInteger).value) },
77 "time-ms": MalFunc { MalInteger(DateTime.nowTicks / 1000000) },
78
79 "list": MalFunc { MalList(it) },
80 "list?": MalFunc { MalTypes.toMalBool(it[0] is MalList) },
81 "vector": MalFunc { MalVector(it) },
82 "vector?": MalFunc { MalTypes.toMalBool(it[0] is MalVector) },
83 "hash-map": MalFunc { MalHashMap.fromList(it) },
84 "map?": MalFunc { MalTypes.toMalBool(it[0] is MalHashMap) },
85 "assoc": MalFunc { (it[0] as MalHashMap).assoc(it[1..-1]) },
86 "dissoc": MalFunc { (it[0] as MalHashMap).dissoc(it[1..-1]) },
87 "get": MalFunc { it[0] is MalNil ? MalNil.INSTANCE : (it[0] as MalHashMap).get2((MalString)it[1], MalNil.INSTANCE) },
88 "contains?": MalFunc { MalTypes.toMalBool((it[0] as MalHashMap).containsKey((MalString)it[1])) },
89 "keys": MalFunc { MalList((it[0] as MalHashMap).keys) },
90 "vals": MalFunc { MalList((it[0] as MalHashMap).vals) },
91
92 "sequential?": MalFunc { MalTypes.toMalBool(it[0] is MalSeq) },
93 "cons": MalFunc { MalList([it[0]].addAll((it[1] as MalSeq).value)) },
94 "concat": MalFunc(#concat.func),
fbfe6784 95 "vec": MalFunc { MalVector((it[0] as MalSeq).value) },
92708e34
DM
96 "nth": MalFunc { (it[0] as MalSeq).nth((it[1] as MalInteger).value) },
97 "first": MalFunc { (it[0] as MalSeq)?.first ?: MalNil.INSTANCE },
98 "rest": MalFunc { (it[0] as MalSeq)?.rest ?: MalList([,]) },
99 "empty?": MalFunc { MalTypes.toMalBool((it[0] as MalSeq).isEmpty) },
100 "count": MalFunc { MalInteger(it[0].count) },
101 "apply": MalFunc(#apply.func),
102 "map": MalFunc { (it[1] as MalSeq).map(it[0]) },
103
104 "conj": MalFunc { (it[0] as MalSeq).conj(it[1..-1]) },
105 "seq": MalFunc { it[0].seq },
106
107 "meta": MalFunc { it[0].meta() },
108 "with-meta": MalFunc { it[0].with_meta(it[1]) },
109 "atom": MalFunc { MalAtom(it[0]) },
110 "atom?": MalFunc { MalTypes.toMalBool(it[0] is MalAtom) },
111 "deref": MalFunc { (it[0] as MalAtom).value },
112 "reset!": MalFunc { (it[0] as MalAtom).set(it[1]) },
113 "swap!": MalFunc(#swap_bang.func),
114
115 "fantom-eval": MalFunc { Interop.fantomEvaluate((it[0] as MalString).value) }
116 ]
117 }
118}