Commit | Line | Data |
---|---|---|
53c2ea70 JFI |
1 | package mal |
2 | ||
3 | import java.util.* | |
4 | ||
5 | class Env(val outer: Env?, binds: Sequence<MalSymbol>?, exprs: Sequence<MalType>?) { | |
6 | val data = HashMap<String, MalType>() | |
7 | ||
8 | init { | |
53c2ea70 JFI |
9 | if (binds != null && exprs != null) { |
10 | val itb = binds.iterator() | |
11 | val ite = exprs.iterator() | |
12 | while (itb.hasNext()) { | |
13 | val b = itb.next() | |
14 | if (b.value != "&") { | |
15 | set(b, if (ite.hasNext()) ite.next() else NIL) | |
16 | } else { | |
17 | if (!itb.hasNext()) throw MalException("expected a symbol name for varargs") | |
18 | set(itb.next(), MalList(ite.asSequence().toLinkedList())) | |
19 | break | |
20 | } | |
21 | } | |
22 | } | |
23 | } | |
24 | ||
25 | constructor() : this(null, null, null) | |
26 | constructor(outer: Env?) : this(outer, null, null) | |
27 | ||
28 | fun set(key: MalSymbol, value: MalType): MalType { | |
29 | data.put(key.value, value) | |
30 | return value | |
31 | } | |
32 | ||
33 | fun find(key: MalSymbol): MalType? = data.getOrElse(key.value) { outer?.find(key) } | |
34 | ||
35 | fun get(key: MalSymbol): MalType = find(key) ?: throw MalException("'${key.value}' not found") | |
36 | } |