aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-06 08:02:52 -0300
committerBad Diode <bd@badd10de.dev>2022-04-06 08:02:52 -0300
commit11df0f4556f526189234be216fa16a2fcb8c308b (patch)
treed9459ebf0b99ef1ecadf4101da147d60935e916f /src/parser.c
parent77b309ba82d090094f5f753342c3aa401cbf657d (diff)
downloadbdl-11df0f4556f526189234be216fa16a2fcb8c308b.tar.gz
bdl-11df0f4556f526189234be216fa16a2fcb8c308b.zip
Add parsing of if statements
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/parser.c b/src/parser.c
index 58ad722..b76e32f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -291,7 +291,46 @@ parse_fun(Parser *parser) {
291 return NULL; 291 return NULL;
292 } 292 }
293 node->fun.body = body; 293 node->fun.body = body;
294 consume_rparen(parser); 294 if (!consume_rparen(parser)) {
295 return NULL;
296 }
297
298 return node;
299}
300
301Node *
302parse_if(Parser *parser) {
303 next_token(parser); // Skip keyword.
304
305 Node *node = alloc_node(NODE_IF);
306 node->ifexpr.cond = NULL;
307 node->ifexpr.expr_true = NULL;
308 node->ifexpr.expr_false = NULL;
309
310 Node *cond = parse_next(parser);
311 if (cond == NULL) {
312 return NULL;
313 }
314 Node *expr_true = parse_next(parser);
315 if (expr_true == NULL) {
316 return NULL;
317 }
318 node->ifexpr.cond = cond;
319 node->ifexpr.expr_true = expr_true;
320 Token tok = peek_token(parser);
321
322 // Optional else statement.
323 if (tok.type != TOKEN_RPAREN) {
324 Node *expr_false = parse_next(parser);
325 if (expr_false == NULL) {
326 return NULL;
327 }
328 node->ifexpr.expr_false = expr_false;
329 }
330
331 if (!consume_rparen(parser)) {
332 return NULL;
333 }
295 334
296 return node; 335 return node;
297} 336}
@@ -299,6 +338,7 @@ parse_fun(Parser *parser) {
299Node * 338Node *
300parse_paren(Parser *parser) { 339parse_paren(Parser *parser) {
301 next_token(parser); // Skip paren. 340 next_token(parser); // Skip paren.
341
302 Token tok = peek_token(parser); 342 Token tok = peek_token(parser);
303 343
304 switch (tok.type) { 344 switch (tok.type) {
@@ -310,11 +350,17 @@ parse_paren(Parser *parser) {
310 case TOKEN_MOD: 350 case TOKEN_MOD:
311 case TOKEN_NOT: 351 case TOKEN_NOT:
312 case TOKEN_AND: 352 case TOKEN_AND:
313 case TOKEN_OR: { return parse_builtin(parser); } break; 353 case TOKEN_OR:
354 case TOKEN_EQ:
355 case TOKEN_LT:
356 case TOKEN_GT:
357 case TOKEN_LE:
358 case TOKEN_GE: { return parse_builtin(parser); } break;
314 // Special functions. 359 // Special functions.
315 case TOKEN_DEF: { return parse_def(parser); } break; 360 case TOKEN_DEF: { return parse_def(parser); } break;
316 case TOKEN_SET: { return parse_set(parser); } break; 361 case TOKEN_SET: { return parse_set(parser); } break;
317 case TOKEN_FUN: { return parse_fun(parser); } break; 362 case TOKEN_FUN: { return parse_fun(parser); } break;
363 case TOKEN_IF: { return parse_if(parser); } break;
318 default: break; 364 default: break;
319 } 365 }
320 366
@@ -326,6 +372,7 @@ parse_paren(Parser *parser) {
326Node * 372Node *
327parse_block(Parser *parser) { 373parse_block(Parser *parser) {
328 next_token(parser); // Skip paren. 374 next_token(parser); // Skip paren.
375
329 Node *node = alloc_node(NODE_BLOCK); 376 Node *node = alloc_node(NODE_BLOCK);
330 array_init(node->block.expr, 0); 377 array_init(node->block.expr, 0);
331 while (true) { 378 while (true) {