-
Notifications
You must be signed in to change notification settings - Fork 0
/
sexpr.c
118 lines (96 loc) · 2.47 KB
/
sexpr.c
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <stdio.h>
#include <stdlib.h>
#include "lexer.h"
#include "sexpr.h"
#include "helper.h"
#include "list.h"
sexpr_t* NIL = 0;
list_sexpr_t* LNIL = 0;
const char* sexpr_type_names[] = {
"sexpr_sym", "sexpr_num", "sexpr_list", "sexpr_quote"
};
sexpr_t* read_symbol(value_t value)
{
atom_sexpr_t* atom = (atom_sexpr_t*)malloc(sizeof(atom_sexpr_t));
atom->type = SEXPR_SYM;
atom->value = value;
return (sexpr_t*)atom;
}
sexpr_t* read_number(value_t value)
{
atom_sexpr_t* atom = (atom_sexpr_t*)malloc(sizeof(atom_sexpr_t));
atom->type = SEXPR_NUM;
atom->value = value;
return as_sexpr(atom);
}
sexpr_t* read_sexpr(lexer_t* lexer);
sexpr_t* read_list(lexer_t* lexer)
{
list_sexpr_t* list;
sexpr_t* expr;
int token;
list = list_create();
token_stream_next(lexer); /* skip '(' */
token = token_stream_peek(lexer);
while(token > 0 && token != TOK_CLOSE) {
expr = read_sexpr(lexer);
list_append(list, expr);
token = token_stream_peek(lexer);
if(token == TOK_DOT) {
token_stream_next(lexer); /* skip '.' */
expr = read_sexpr(lexer);
list_set_foot(list, expr);
token = token_stream_peek(lexer);
break;
}
}
if(token == TOK_CLOSE) {
token_stream_next(lexer); /* skip ')' */
}
if(token < 0) {
lerror("error: unexpected end of buffer\n");
}
return (sexpr_t*)list;
}
sexpr_t* read_quote(lexer_t* lexer)
{
sexpr_t* expr;
expr = read_sexpr(lexer);
if(expr->type != SEXPR_NUM && expr->type != SEXPR_QUOTE) {
quote_sexpr_t* quote;
quote = (quote_sexpr_t*)malloc(sizeof(quote_sexpr_t));
quote->type = SEXPR_QUOTE;
quote->expr = expr;
expr = as_sexpr(quote);
}
return expr;
}
sexpr_t* read_sexpr(lexer_t* lexer)
{
sexpr_t* expr = NIL;
// printf("<%s>", token_names[token_stream_peek(lexer)]);
switch(token_stream_peek(lexer)) {
case TOK_CLOSE:
token_stream_next(lexer);
lerror("error: unexpected ')'\n");
case TOK_DOT:
token_stream_next(lexer);
lerror("error: unexpected '.'\n");
case TOK_SYM:
token_stream_next(lexer);
expr =read_symbol(lexer->value);
break;
case TOK_NUM:
token_stream_next(lexer);
expr = read_number(lexer->value);
break;
case TOK_QUOTE:
token_stream_next(lexer);
expr = read_quote(lexer);
break;
case TOK_OPEN:
expr = read_list(lexer);
break;
}
return expr;
}