aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-12 17:25:08 +0200
committerBad Diode <bd@badd10de.dev>2021-10-12 17:25:08 +0200
commitab7d5d484b911f454f35567ed2f1a1a2dac167f7 (patch)
tree315733c643b7d9bce50e25f91ed59ce39272a1f6
parentd90018ed10267dbf1f4c6f746b9f70460e1424a6 (diff)
downloadbdl-ab7d5d484b911f454f35567ed2f1a1a2dac167f7.tar.gz
bdl-ab7d5d484b911f454f35567ed2f1a1a2dac167f7.zip
Add new error values
-rw-r--r--src/bootstrap/errors.c8
-rw-r--r--src/bootstrap/parser.c149
2 files changed, 157 insertions, 0 deletions
diff --git a/src/bootstrap/errors.c b/src/bootstrap/errors.c
index fcb629a..87752e6 100644
--- a/src/bootstrap/errors.c
+++ b/src/bootstrap/errors.c
@@ -7,6 +7,10 @@ typedef enum ErrorType {
7typedef enum ErrorValue { 7typedef enum ErrorValue {
8 ERR_UNKNOWN = 0, 8 ERR_UNKNOWN = 0,
9 ERR_UNMATCHED_STRING, 9 ERR_UNMATCHED_STRING,
10 ERR_UNBALANCED_PAREN,
11 ERR_NOT_IMPLEMENTED,
12 ERR_EOF_REACHED,
13 ERR_UNKNOWN_TOKEN,
10} ErrorValue; 14} ErrorValue;
11 15
12typedef struct Error { 16typedef struct Error {
@@ -19,6 +23,10 @@ typedef struct Error {
19static const char* error_msgs[] = { 23static const char* error_msgs[] = {
20 [ERR_UNKNOWN] = "error: something unexpected happened", 24 [ERR_UNKNOWN] = "error: something unexpected happened",
21 [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter", 25 [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter",
26 [ERR_UNBALANCED_PAREN] = "error: unbalanced parentheses",
27 [ERR_NOT_IMPLEMENTED] = "error: not implemented",
28 [ERR_EOF_REACHED] = "error: EOF reached",
29 [ERR_UNKNOWN_TOKEN] = "error: unknown token",
22}; 30};
23 31
24#define ERR_MAX_NUMBER 16 32#define ERR_MAX_NUMBER 16
diff --git a/src/bootstrap/parser.c b/src/bootstrap/parser.c
new file mode 100644
index 0000000..c84c6c6
--- /dev/null
+++ b/src/bootstrap/parser.c
@@ -0,0 +1,149 @@
1typedef struct Visitor {
2 Tokens tokens;
3 size_t current;
4} Visitor;
5
6Token
7peek_token(const Visitor *visitor) {
8 return visitor->tokens.buf[visitor->current];
9}
10
11Token
12next_token(Visitor *visitor) {
13 return visitor->tokens.buf[visitor->current++];
14}
15
16bool
17has_next_token(const Visitor *visitor) {
18 return visitor->current < visitor->tokens.size;
19}
20
21Object *
22parse_fixnum(Token tok) {
23 ssize_t num = 0;
24 int sign = 1;
25 for (size_t i = 0; i < tok.value.n; i++) {
26 char c = tok.value.start[i];
27 if (c == '-') {
28 sign = -1;
29 continue;
30 }
31 num = num * 10 + (c - '0');
32 }
33 return make_fixnum(num * sign);
34}
35
36Object * parse_tree(Visitor *vs);
37
38Object *
39parse_list(Visitor *vs) {
40 Token tok = peek_token(vs);
41 if (tok.type == TOKEN_EOF) {
42 error_push((Error){
43 .type = ERR_TYPE_PARSER,
44 .value = ERR_UNBALANCED_PAREN,
45 .line = tok.line,
46 .col = tok.column,
47 });
48 return obj_err;
49 }
50 Object *next_obj = parse_tree(vs);
51 if (next_obj == obj_err) {
52 return obj_err;
53 }
54 Object *root = make_pair(next_obj, obj_nil);
55 Object *list = root;
56 while (has_next_token(vs)) {
57 Token tok = peek_token(vs);
58 if (tok.type == TOKEN_RPAREN) {
59 next_token(vs);
60 break;
61 }
62 if (tok.type == TOKEN_EOF) {
63 error_push((Error){
64 .type = ERR_TYPE_PARSER,
65 .value = ERR_UNBALANCED_PAREN,
66 .line = tok.line,
67 .col = tok.column,
68 });
69 free_objects(root);
70 return obj_err;
71 }
72 next_obj = parse_tree(vs);
73 if (next_obj == obj_err) {
74 free_objects(root);
75 return obj_err;
76 }
77 list->cdr = make_pair(next_obj, obj_nil);
78 list = list->cdr;
79 }
80 return root;
81}
82
83Object *
84parse_tree(Visitor *vs) {
85 Token tok = next_token(vs);
86 switch (tok.type) {
87 case TOKEN_FIXNUM: {
88 return parse_fixnum(tok);
89 } break;
90 case TOKEN_TRUE: {
91 return obj_true;
92 } break;
93 case TOKEN_FALSE: {
94 return obj_false;
95 } break;
96 case TOKEN_RPAREN: {
97 error_push((Error){
98 .type = ERR_TYPE_PARSER,
99 .value = ERR_UNBALANCED_PAREN,
100 .line = tok.line,
101 .col = tok.column,
102 });
103 return obj_err;
104 } break;
105 case TOKEN_QUOTE: {
106 // TODO: Implement.
107 error_push((Error){
108 .type = ERR_TYPE_PARSER,
109 .value = ERR_NOT_IMPLEMENTED,
110 .line = tok.line,
111 .col = tok.column,
112 });
113 return obj_err;
114 } break;
115 case TOKEN_LPAREN: {
116 return parse_list(vs);
117 } break;
118 case TOKEN_STRING: {
119 Object *obj = make_string();
120 append_string(obj, tok.value);
121 return obj;
122 } break;
123 case TOKEN_SYMBOL: {
124 return make_symbol(tok.value);
125 } break;
126 case TOKEN_EOF: {
127 error_push((Error){
128 .type = ERR_TYPE_PARSER,
129 .value = ERR_EOF_REACHED,
130 .line = tok.line,
131 .col = tok.column,
132 });
133 return obj_err;
134 } break;
135 case TOKEN_NIL: {
136 return obj_nil;
137 } break;
138 default: {
139 break;
140 } break;
141 }
142 error_push((Error){
143 .type = ERR_TYPE_PARSER,
144 .value = ERR_EOF_REACHED,
145 .line = tok.line,
146 .col = tok.column,
147 });
148 return obj_err;
149}