-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlisp.aat
99 lines (83 loc) · 2.04 KB
/
lisp.aat
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
88
89
90
91
92
93
94
95
96
97
98
99
extern fn printf str, ... -> i32
extern fn malloc i32 -> u8*
extern fn strlen str -> i32
rec Parser(pos: i32, text: str, len: i32)
fn peek parser: &Parser -> char = parser.text[parser.pos]
fn consume parser: &Parser = parser.pos = parser.pos + 1
fn eof parser: &Parser -> bool =
if ret parser.pos >= parser.len then true
else false
fn isDigit c: char -> bool =
if ret c >= '0' && c <= '9' then true
else false
fn isChar parser: &Parser, c: char -> bool =
if ret (peek &parser) == c then true
else false
fn print b: bool = {
if b == true then printf "true"
else printf "false"
}
fn parseNumber parser: &Parser -> i32 = {
var accum = 0
val zero = '0' as i32
while (isDigit peek &parser) {
accum = accum * 10
accum = accum + (peek &parser) as i32 - zero
consume &parser
}
accum
}
type lispType = Int i32 | Bool bool | Error | Nil | Cons lispType*, lispType* | Char char
fn parse parser: &Parser -> lispType = {
if isDigit peek &parser
ret Int parseNumber &parser
if isChar &parser, '(' {
consume &parser
if isChar &parser, ')' {
consume &parser
ret Nil ()
}
ret Error ()
}
if isChar &parser, '#' {
consume &parser
if isChar &parser, 't' {
consume &parser
ret Bool true
}
if isChar &parser, 'f' {
consume &parser
ret Bool false
}
if isChar &parser, '\\' {
consume &parser
val c = peek &parser
ret Char c
}
ret Error ()
}
Error ()
}
fn print ty: lispType = {
if ty is Int
printf "%i", ty.0
if ty is Nil
printf "()"
if ty is Bool
if ty.0 == true
printf "#t"
else
printf "#f"
if ty is Char
printf "#\\%c", ty.0
}
@entry
fn main() -> () = {
val text = "#\\a"
var parser = Parser {
pos: 0,
text: text,
len: strlen text,
}
print parse &parser
}