From f17b11003fe384b49a7bf844824f23167b6095e0 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 30 Oct 2021 08:36:14 +0200 Subject: Add parsing of if expressions --- src/parser.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 8 deletions(-) (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c index 8a6c4ce..5551dd2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -103,6 +103,7 @@ parse_lambda(Parser *parser, Errors *errors) { .line = tok.line, .col = tok.col, }); + return NULL; } // Parse body. @@ -119,23 +120,81 @@ parse_lambda(Parser *parser, Errors *errors) { } Object * -parse_list(Parser *parser, Errors *errors) { - if (errors->n != 0) { +parse_if(Parser *parser, Errors *errors) { + Token start = next_token(parser); + Object *obj_if = object_alloc(start, OBJ_TYPE_IF); + + Token tok = peek_token(parser); + if (tok.type == TOKEN_RPAREN) { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_NOT_ENOUGH_ARGS, + .line = tok.line, + .col = tok.col, + }); return NULL; } + obj_if->condition = parse_tree(parser, errors); - Token tok = peek_token(parser); + tok = peek_token(parser); if (tok.type == TOKEN_RPAREN) { error_push(errors, (Error){ .type = ERR_TYPE_PARSER, - .value = ERR_UNBALANCED_PAREN, + .value = ERR_NOT_ENOUGH_ARGS, .line = tok.line, .col = tok.col, }); return NULL; } - if (tok.type == TOKEN_LAMBDA) { - return parse_lambda(parser, errors); + obj_if->expr_true = parse_tree(parser, errors); + + // Optional else expression. + tok = peek_token(parser); + if (tok.type == TOKEN_RPAREN) { + next_token(parser); + obj_if->expr_false = NULL; + return obj_if; + } + obj_if->expr_false = parse_tree(parser, errors); + + tok = peek_token(parser); + if (tok.type != TOKEN_RPAREN) { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_TOO_MANY_ARGS, + .line = tok.line, + .col = tok.col, + }); + return NULL; + } + next_token(parser); + return obj_if; +} + +Object * +parse_list(Parser *parser, Errors *errors) { + if (errors->n != 0) { + return NULL; + } + + Token tok = peek_token(parser); + switch (tok.type) { + case TOKEN_RPAREN: { + error_push(errors, (Error){ + .type = ERR_TYPE_PARSER, + .value = ERR_UNBALANCED_PAREN, + .line = tok.line, + .col = tok.col, + }); + return NULL; + } break; + case TOKEN_LAMBDA: { + return parse_lambda(parser, errors); + } break; + case TOKEN_IF: { + return parse_if(parser, errors); + } break; + default: break; } Token start = previous_token(parser); @@ -327,13 +386,29 @@ object_display(Object *obj) { printf(")"); } break; case OBJ_TYPE_LAMBDA: { - printf("#{lambda( "); + printf("#{ lambda( "); for (size_t i = 0; i < array_size(obj->params); i++) { object_display(obj->params[i]); printf(" "); } - printf(")}"); + printf(") "); + for (size_t i = 0; i < array_size(obj->body); i++) { + object_display(obj->body[i]); + printf(" "); + } + printf("}"); } break; + case OBJ_TYPE_IF: { + printf("#{ if "); + object_display(obj->condition); + printf(" "); + object_display(obj->expr_true); + if (obj->expr_false != NULL) { + printf(" "); + object_display(obj->expr_false); + } + printf(" }"); + }; } return; } -- cgit v1.2.1