blob: 7a5b5164c7db7f18fc82c119b951ce30defd7dbe (
plain)
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
|
Token *
consume_token(Tokens *tokens) {
if (tokens->n == 0) {
return NULL;
}
Token *ret = tokens->start;
tokens->start = &tokens->start[1];
tokens->n--;
return ret;
}
Object *
parse(Tokens *tokens) {
while (tokens->n > 0) {
Token *token = consume_token(tokens);
if (token == NULL) {
return NULL;
}
switch (token->type) {
case TOKEN_FIXNUM: {
ssize_t num = 0;
int sign = 1;
for (size_t i = 0; i < token->value.n; i++) {
char c = token->value.start[i];
if (c == '-') {
sign = -1;
continue;
}
num = num * 10 + (c - '0');
}
return make_fixnum(num * sign);
} break;
case TOKEN_BOOL: {
if (sv_equal(token->value, TRUE_TOKEN)) {
return obj_true;
}
if (sv_equal(token->value, FALSE_TOKEN)) {
return obj_false;
}
} break;
case TOKEN_RPAREN: {
return NULL;
} break;
case TOKEN_LPAREN: {
if (tokens->n > 0 && tokens->start[0].type == TOKEN_RPAREN) {
return obj_nil;
}
Object *next_obj = parse(tokens);
if (next_obj == NULL) {
return NULL;
}
Object *root = make_pair(next_obj, obj_nil);
Object *list = root;
while (tokens->n > 0 && (next_obj = parse(tokens)) != NULL) {
list->cdr = make_pair(next_obj, obj_nil);
list = list->cdr;
}
return root;
} break;
case TOKEN_STRING: {
Object *obj = make_empty_string();
append_string(obj, token->value);
return obj;
} break;
case TOKEN_SYMBOL: {
return make_symbol(token->value.start, token->value.n);
} break;
default: {
fprintf(stderr, "error: unknown token\n");
} break;
}
}
return NULL;
}
|