aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-06 07:30:43 -0300
committerBad Diode <bd@badd10de.dev>2022-04-06 07:30:43 -0300
commit77b309ba82d090094f5f753342c3aa401cbf657d (patch)
tree2ead2ad4a87b6ba14c766a62b2a82e7005fb03c1 /src/parser.c
parentc8b53cb4590d8d6cbfc5cbf891809ddd99e33fe5 (diff)
downloadbdl-77b309ba82d090094f5f753342c3aa401cbf657d.tar.gz
bdl-77b309ba82d090094f5f753342c3aa401cbf657d.zip
Add NODE_BLOCK for scoped expressions
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/parser.c b/src/parser.c
index cfbefaf..58ad722 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -258,7 +258,6 @@ parse_fun(Parser *parser) {
258 node->fun.name = name; 258 node->fun.name = name;
259 array_init(node->fun.param_names, 0); 259 array_init(node->fun.param_names, 0);
260 array_init(node->fun.param_types, 0); 260 array_init(node->fun.param_types, 0);
261 array_init(node->fun.body, 0);
262 261
263 // Parse parameter list and return type. 262 // Parse parameter list and return type.
264 if (!consume_lparen(parser)) { 263 if (!consume_lparen(parser)) {
@@ -287,19 +286,12 @@ parse_fun(Parser *parser) {
287 } 286 }
288 node->fun.return_type = ret_type; 287 node->fun.return_type = ret_type;
289 288
290 // Parse body. 289 Node *body = parse_next(parser);
291 while (true) { 290 if (body == NULL) {
292 Token next = peek_token(parser); 291 return NULL;
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 } 292 }
293 node->fun.body = body;
294 consume_rparen(parser);
303 295
304 return node; 296 return node;
305} 297}
@@ -331,10 +323,25 @@ parse_paren(Parser *parser) {
331 return NULL; 323 return NULL;
332} 324}
333 325
334 326Node *
335// TODO: Parse if: (def ...) shouldn't be allowed for now on if statements. In 327parse_block(Parser *parser) {
336// the future, an if can create a new block and thus a fresh scope which would 328 next_token(parser); // Skip paren.
337// make the decision of what variables are active trivial. 329 Node *node = alloc_node(NODE_BLOCK);
330 array_init(node->block.expr, 0);
331 while (true) {
332 Token next = peek_token(parser);
333 if (next.type == TOKEN_RCURLY) {
334 next_token(parser);
335 break;
336 }
337 Node *expr = parse_next(parser);
338 if (expr == NULL) {
339 return NULL;
340 }
341 array_push(node->block.expr, expr);
342 }
343 return node;
344}
338 345
339Node * 346Node *
340parse_next(Parser *parser) { 347parse_next(Parser *parser) {
@@ -347,6 +354,7 @@ parse_next(Parser *parser) {
347 case TOKEN_FALSE: { return parse_bool(parser); } break; 354 case TOKEN_FALSE: { return parse_bool(parser); } break;
348 case TOKEN_LPAREN: { return parse_paren(parser); } break; 355 case TOKEN_LPAREN: { return parse_paren(parser); } break;
349 case TOKEN_EOF: { return NULL; } break; 356 case TOKEN_EOF: { return NULL; } break;
357 case TOKEN_LCURLY: { return parse_block(parser); } break;
350 default: { 358 default: {
351 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_TOK_TYPE, tok.line, tok.col); 359 push_error(ERR_TYPE_PARSER, ERR_UNKNOWN_TOK_TYPE, tok.line, tok.col);
352 return NULL; 360 return NULL;