diff options
author | Bad Diode <bd@badd10de.dev> | 2022-04-06 07:30:43 -0300 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-04-06 07:30:43 -0300 |
commit | 77b309ba82d090094f5f753342c3aa401cbf657d (patch) | |
tree | 2ead2ad4a87b6ba14c766a62b2a82e7005fb03c1 /src/parser.c | |
parent | c8b53cb4590d8d6cbfc5cbf891809ddd99e33fe5 (diff) | |
download | bdl-77b309ba82d090094f5f753342c3aa401cbf657d.tar.gz bdl-77b309ba82d090094f5f753342c3aa401cbf657d.zip |
Add NODE_BLOCK for scoped expressions
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 42 |
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 | 326 | Node * | |
335 | // TODO: Parse if: (def ...) shouldn't be allowed for now on if statements. In | 327 | parse_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 | ||
339 | Node * | 346 | Node * |
340 | parse_next(Parser *parser) { | 347 | parse_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; |