Commit | Line | Data |
---|---|---|
a7081401 HÖS |
1 | unit module types; |
2 | ||
3 | class X::MalException is Exception is export {} | |
4 | class X::MalNoTokens is X::MalException is export { | |
5 | method message() { "got no tokens" } | |
6 | } | |
7 | class X::MalIncomplete is X::MalException is export { | |
8 | has $.end; | |
9 | method message() { "expected '$.end', got EOF" } | |
10 | } | |
11 | class X::MalUnexpected is X::MalException is export { | |
12 | has $.token; | |
13 | method message() { "unexpected '$.token'" } | |
14 | } | |
15 | class X::MalNotFound is X::MalException is export { | |
16 | has $.name; | |
17 | method message() { "'$.name' not found" } | |
18 | } | |
19 | class X::MalOutOfRange is X::MalException is export { | |
20 | method message() { "nth: index out of range" } | |
21 | } | |
22 | class X::MalThrow is X::MalException is export { | |
23 | has $.value; | |
24 | } | |
25 | ||
26 | role MalValue is export { | |
27 | has $.val is rw; | |
28 | method CALL-ME ($val) { self.new(:$val) } | |
29 | } | |
30 | role MalSequence is export { | |
31 | has $.val handles <cache AT-POS EXISTS-POS elems end iterator>; | |
32 | has $.meta is rw; | |
33 | method CALL-ME ($val) { self.new(:$val) } | |
34 | } | |
35 | role MalCallable is export { | |
36 | has &.fn; | |
37 | method apply (*@_) { &!fn(|@_) } | |
38 | } | |
39 | role MalMeta is export { | |
40 | has $.meta is rw; | |
41 | } | |
42 | ||
43 | class MalNil does MalValue is export { | |
44 | method seq { self } | |
45 | } | |
46 | class MalTrue does MalValue is export {} | |
47 | class MalFalse does MalValue is export {} | |
48 | ||
49 | our $NIL is export = MalNil('nil'); | |
50 | our $TRUE is export = MalTrue('true'); | |
51 | our $FALSE is export = MalFalse('false'); | |
52 | ||
53 | class MalSymbol does MalValue does MalMeta is export {} | |
54 | ||
55 | class MalList does MalSequence is export { | |
56 | method conj (@args) { return self.new(val => [|@args.reverse, |$.val]) } | |
57 | method seq { return self.elems ?? self !! $NIL } | |
58 | } | |
59 | ||
60 | class MalVector does MalSequence is export { | |
61 | method conj (@args) { return self.new(val => [|$.val, |@args]) } | |
62 | method seq { return self.elems ?? MalList(self.val) !! $NIL } | |
63 | } | |
64 | ||
65 | class MalHashMap does MalMeta is export { | |
66 | has $.val handles <cache AT-KEY EXISTS-KEY elems pairs keys values kv>; | |
67 | method CALL-ME ($val) { self.new(:$val) } | |
68 | } | |
69 | ||
70 | class MalNumber does MalValue is export {} | |
71 | ||
72 | class MalString does MalValue is export { | |
73 | method seq { | |
74 | return self.val.chars | |
75 | ?? MalList(self.val.comb.map({MalString($_)})) | |
76 | !! $NIL; | |
77 | } | |
78 | } | |
79 | ||
80 | class MalCode does MalCallable does MalMeta is export { | |
81 | method CALL-ME (&fn) { self.new(:&fn) } | |
82 | } | |
83 | ||
84 | class MalFunction does MalCallable does MalMeta is export { | |
85 | has $.ast; | |
86 | has @.params; | |
87 | has $.env; | |
88 | has $.is_macro is rw = False; | |
89 | method CALL-ME ($ast, $env, @params, &fn) { | |
90 | self.bless(:$ast, :$env, :@params, :&fn); | |
91 | } | |
92 | } | |
93 | ||
94 | class MalAtom does MalValue does MalMeta is export {} |