aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c151
1 files changed, 126 insertions, 25 deletions
diff --git a/src/parser.c b/src/parser.c
index b36ddc9..cfbefaf 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -16,9 +16,33 @@ has_next(Parser *parser) {
16 return parser->current < array_size(parser->tokens); 16 return parser->current < array_size(parser->tokens);
17} 17}
18 18
19bool
20consume_rparen(Parser *parser) {
21 Token tok = next_token(parser);
22 if (tok.type != TOKEN_RPAREN) {
23 push_error(ERR_TYPE_PARSER, ERR_NOT_A_RPAREN, tok.line, tok.col);
24 return false;
25 }
26 return true;
27}
28
29bool
30consume_lparen(Parser *parser) {
31 Token tok = next_token(parser);
32 if (tok.type != TOKEN_LPAREN) {
33 push_error(ERR_TYPE_PARSER, ERR_NOT_A_LPAREN, tok.line, tok.col);
34 return false;
35 }
36 return true;
37}
38
19Node * 39Node *
20parse_number(Parser *parser) { 40parse_number(Parser *parser) {
21 Token tok = next_token(parser); 41 Token tok = next_token(parser);
42 if (tok.type != TOKEN_NUMBER) {
43 push_error(ERR_TYPE_PARSER, ERR_NOT_A_NUMBER, tok.line, tok.col);
44 return NULL;
45 }
22 46
23 bool negative = false; 47 bool negative = false;
24 int base = 10; 48 int base = 10;
@@ -93,6 +117,10 @@ parse_number(Parser *parser) {
93Node * 117Node *
94parse_string(Parser *parser) { 118parse_string(Parser *parser) {
95 Token tok = next_token(parser); 119 Token tok = next_token(parser);
120 if (tok.type != TOKEN_STRING) {
121 push_error(ERR_TYPE_PARSER, ERR_NOT_A_STRING, tok.line, tok.col);
122 return NULL;
123 }
96 Node *node = alloc_node(NODE_STRING); 124 Node *node = alloc_node(NODE_STRING);
97 node->string = tok.value; 125 node->string = tok.value;
98 return node; 126 return node;
@@ -101,14 +129,39 @@ parse_string(Parser *parser) {
101Node * 129Node *
102parse_symbol(Parser *parser) { 130parse_symbol(Parser *parser) {
103 Token tok = next_token(parser); 131 Token tok = next_token(parser);
132 if (tok.type != TOKEN_SYMBOL) {
133 push_error(ERR_TYPE_PARSER, ERR_NOT_A_SYMBOL, tok.line, tok.col);
134 return NULL;
135 }
104 Node *node = alloc_node(NODE_SYMBOL); 136 Node *node = alloc_node(NODE_SYMBOL);
105 node->string = tok.value; 137 node->string = tok.value;
106 return node; 138 return node;
107} 139}
108 140
109Node * 141Node *
142parse_type(Parser *parser) {
143 Token tok = next_token(parser);
144 if (tok.type != TOKEN_COLON) {
145 push_error(ERR_TYPE_PARSER, ERR_NOT_A_TYPE, tok.line, tok.col);
146 return NULL;
147 }
148 tok = next_token(parser);
149 if (tok.type != TOKEN_SYMBOL) {
150 push_error(ERR_TYPE_PARSER, ERR_NOT_A_TYPE, tok.line, tok.col);
151 return NULL;
152 }
153 Node *node = alloc_node(NODE_TYPE);
154 node->string = tok.value;
155 return node;
156}
157
158Node *
110parse_bool(Parser *parser) { 159parse_bool(Parser *parser) {
111 Token tok = next_token(parser); 160 Token tok = next_token(parser);
161 if (!(tok.type == TOKEN_TRUE || tok.type == TOKEN_FALSE)) {
162 push_error(ERR_TYPE_PARSER, ERR_NOT_A_BOOL, tok.line, tok.col);
163 return NULL;
164 }
112 Node *node = alloc_node(NODE_BOOL); 165 Node *node = alloc_node(NODE_BOOL);
113 node->boolean = tok.type == TOKEN_TRUE; 166 node->boolean = tok.type == TOKEN_TRUE;
114 return node; 167 return node;
@@ -138,63 +191,51 @@ parse_builtin(Parser *parser) {
138 191
139Node * 192Node *
140parse_def(Parser *parser) { 193parse_def(Parser *parser) {
141 Token op = next_token(parser); 194 next_token(parser); // Skip keyword.
142 Node *symbol = parse_next(parser); 195
143 if (symbol == NULL || symbol->type != NODE_SYMBOL) { 196 Node *symbol = parse_symbol(parser);
144 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); 197 if (symbol == NULL) {
145 return NULL; 198 return NULL;
146 } 199 }
147 200
148 // TODO: Making type checking mandatory for now until we introduce 201 // TODO: Making type checking mandatory for now until we introduce
149 // type inference. 202 // type inference.
150 Token next = next_token(parser); 203 Node *type = parse_type(parser);
151 if (next.type != TOKEN_COLON) { 204 if (type == NULL) {
152 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
153 return NULL;
154 }
155 Token type_name = next_token(parser);
156 if (type_name.type != TOKEN_SYMBOL) {
157 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
158 return NULL; 205 return NULL;
159 } 206 }
160 207
161 Node *value = parse_next(parser); 208 Node *value = parse_next(parser);
162 if (value == NULL) { 209 if (value == NULL) {
163 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
164 return NULL; 210 return NULL;
165 } 211 }
166 212
167 Token end = next_token(parser); 213 if (!consume_rparen(parser)) {
168 if (end.type != TOKEN_RPAREN) {
169 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
170 return NULL; 214 return NULL;
171 } 215 }
172 216
173 Node *node = alloc_node(NODE_DEF); 217 Node *node = alloc_node(NODE_DEF);
174 node->def.symbol = symbol; 218 node->def.symbol = symbol;
175 node->def.value = value; 219 node->def.value = value;
176 node->def.type = type_name.value; 220 node->def.type = type;
177 return node; 221 return node;
178} 222}
179 223
180Node * 224Node *
181parse_set(Parser *parser) { 225parse_set(Parser *parser) {
182 Token op = next_token(parser); 226 next_token(parser); // Skip keyword.
183 Node *symbol = parse_next(parser); 227
184 if (symbol == NULL || symbol->type != NODE_SYMBOL) { 228 Node *symbol = parse_symbol(parser);
185 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); 229 if (symbol == NULL) {
186 return NULL; 230 return NULL;
187 } 231 }
188 232
189 Node *value = parse_next(parser); 233 Node *value = parse_next(parser);
190 if (value == NULL) { 234 if (value == NULL) {
191 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
192 return NULL; 235 return NULL;
193 } 236 }
194 237
195 Token end = next_token(parser); 238 if (!consume_rparen(parser)) {
196 if (end.type != TOKEN_RPAREN) {
197 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
198 return NULL; 239 return NULL;
199 } 240 }
200 241
@@ -205,6 +246,65 @@ parse_set(Parser *parser) {
205} 246}
206 247
207Node * 248Node *
249parse_fun(Parser *parser) {
250 next_token(parser); // Skip keyword.
251
252 Node *name = parse_symbol(parser);
253 if (name == NULL) {
254 return NULL;
255 }
256
257 Node *node = alloc_node(NODE_FUN);
258 node->fun.name = name;
259 array_init(node->fun.param_names, 0);
260 array_init(node->fun.param_types, 0);
261 array_init(node->fun.body, 0);
262
263 // Parse parameter list and return type.
264 if (!consume_lparen(parser)) {
265 return NULL;
266 }
267 while (true) {
268 Token next = peek_token(parser);
269 if (next.type == TOKEN_RPAREN) {
270 next_token(parser);
271 break;
272 }
273 Node *name = parse_symbol(parser);
274 if (name == NULL) {
275 return NULL;
276 }
277 Node *type = parse_type(parser);
278 if (type == NULL) {
279 return NULL;
280 }
281 array_push(node->fun.param_names, name);
282 array_push(node->fun.param_types, type);
283 }
284 Node *ret_type = parse_type(parser);
285 if (ret_type == NULL) {
286 return NULL;
287 }
288 node->fun.return_type = ret_type;
289
290 // Parse body.
291 while (true) {
292 Token next = peek_token(parser);
293 if (next.type == TOKEN_RPAREN) {
294 next_token(parser);
295 break;
296 }
297 Node *expr = parse_next(parser);
298 if (expr == NULL) {
299 return NULL;
300 }
301 array_push(node->fun.body, expr);
302 }
303
304 return node;
305}
306
307Node *
208parse_paren(Parser *parser) { 308parse_paren(Parser *parser) {
209 next_token(parser); // Skip paren. 309 next_token(parser); // Skip paren.
210 Token tok = peek_token(parser); 310 Token tok = peek_token(parser);
@@ -222,6 +322,7 @@ parse_paren(Parser *parser) {
222 // Special functions. 322 // Special functions.
223 case TOKEN_DEF: { return parse_def(parser); } break; 323 case TOKEN_DEF: { return parse_def(parser); } break;
224 case TOKEN_SET: { return parse_set(parser); } break; 324 case TOKEN_SET: { return parse_set(parser); } break;
325 case TOKEN_FUN: { return parse_fun(parser); } break;
225 default: break; 326 default: break;
226 } 327 }
227 328