From 140cd959daabf5c18b9cccc210a58ab50351e884 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 11 Apr 2022 18:39:27 -0300 Subject: Add funcall node type and fix type resolution bugs --- src/parser.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 80 insertions(+), 12 deletions(-) (limited to 'src/parser.c') diff --git a/src/parser.c b/src/parser.c index 252ceaa..92f7654 100644 --- a/src/parser.c +++ b/src/parser.c @@ -233,6 +233,34 @@ parse_builtin(Parser *parser) { return NULL; } +Node * +parse_funcall(Parser *parser) { + Token tok = peek_token(parser); + Node *name = parse_symbol(parser); + if (name == NULL) { + return NULL; + } + Node *node = alloc_node(NODE_FUNCALL); + node->funcall.name = name; + node->line = tok.line; + node->col = tok.col; + array_init(node->funcall.args, 0); + while (has_next(parser)) { + Token next = peek_token(parser); + if (next.type == TOKEN_RPAREN) { + next_token(parser); + return node; + } + Node *arg = parse_next(parser); + if (arg == NULL) { + break; + } + array_push(node->funcall.args, arg); + } + push_error(ERR_TYPE_PARSER, ERR_UNMATCHED_PAREN, tok.line, tok.col); + return NULL; +} + Node * parse_def(Parser *parser) { Token tok = next_token(parser); @@ -416,8 +444,7 @@ parse_paren(Parser *parser) { default: break; } - push_error(ERR_TYPE_PARSER, ERR_UNIMPLEMENTED, tok.line, tok.col); - return NULL; + return parse_funcall(parser); } Node * @@ -518,6 +545,10 @@ alloc_parsetree(void) { bool parse_roots(Parser *parser) { while (has_next(parser)) { + Token tok = peek_token(parser); + if (tok.type == TOKEN_EOF) { + break; + } Node *node = parse_next(parser); if (node == NULL) { return false; @@ -679,6 +710,11 @@ symbol_check(Parser *parser, Node *node) { return false; } } break; + case NODE_FUNCALL: { + if (!symbol_check(parser, node->funcall.name)) { + return false; + } + } break; default: break; } return true; @@ -799,7 +835,9 @@ resolve_type(Parser *parser, Node *node) { case NODE_BUILTIN: { for (size_t i = 0; i < array_size(node->builtin.args); ++i) { Node *arg = node->builtin.args[i]; - resolve_type(parser, arg); + if (!resolve_type(parser, arg)) { + return false; + } } switch (node->builtin.type) { // Numbers. @@ -865,7 +903,9 @@ resolve_type(Parser *parser, Node *node) { node->expr_type = find_symbol(parser, node); } break; case NODE_FUN: { - resolve_type(parser, node->fun.body); + if (!resolve_type(parser, node->fun.body)) { + return false; + } // Check that the type of body matches the return type. StringView *type_body = &node->fun.body->expr_type->name; StringView *return_type = &node->fun.return_type->string; @@ -877,18 +917,26 @@ resolve_type(Parser *parser, Node *node) { case NODE_BLOCK: { for (size_t i = 0; i < array_size(node->block.expr); ++i) { Node *expr = node->block.expr[i]; - resolve_type(parser, expr); + if (!resolve_type(parser, expr)) { + return false; + } } Node *last_expr = node->block.expr[array_size(node->block.expr) - 1]; node->expr_type = last_expr->expr_type; } break; case NODE_IF: { - resolve_type(parser, node->ifexpr.cond); - resolve_type(parser, node->ifexpr.expr_true); + if (!resolve_type(parser, node->ifexpr.cond)) { + return false; + } + if (!resolve_type(parser, node->ifexpr.expr_true)) { + return false; + } Type *type_true = node->ifexpr.expr_true->expr_type; node->expr_type = type_true; if (node->ifexpr.expr_false != NULL) { - resolve_type(parser, node->ifexpr.expr_false); + if (!resolve_type(parser, node->ifexpr.expr_false)) { + return false; + } } // Check ifexpr.cond is a bool. @@ -913,11 +961,15 @@ resolve_type(Parser *parser, Node *node) { } break; case NODE_SET: { node->expr_type = &default_types[TYPE_VOID]; - resolve_type(parser, node->set.value); + if (!resolve_type(parser, node->set.value)) { + return false; + } } break; case NODE_DEF: { node->expr_type = &default_types[TYPE_VOID]; - resolve_type(parser, node->def.value); + if (!resolve_type(parser, node->def.value)) { + return false; + } } break; case NODE_NUMBER: { if (node->number.fractional != 0) { @@ -934,6 +986,18 @@ resolve_type(Parser *parser, Node *node) { case NODE_STRING: { node->expr_type = &default_types[TYPE_STR]; } break; + case NODE_FUNCALL: { + if (!resolve_type(parser, node->funcall.name)) { + return false; + } + node->expr_type = node->funcall.name->expr_type; + for (size_t i = 0; i < array_size(node->funcall.args); ++i) { + Node *arg = node->funcall.args[i]; + if (!resolve_type(parser, arg)) { + return false; + } + } + } break; default: break; } if (node->scope != NULL) { @@ -960,9 +1024,13 @@ semantic_analysis(Parser *parser) { for (size_t i = 0; i < array_size(parser->parse_tree->roots); ++i) { // Fill up symbol tables in proper scope and check existance. - symbol_check(parser, parser->parse_tree->roots[i]); + if (!symbol_check(parser, parser->parse_tree->roots[i])) { + return false; + } // Resolve type of expression for all elements. - resolve_type(parser, parser->parse_tree->roots[i]); + if (!resolve_type(parser, parser->parse_tree->roots[i])) { + return false; + } } return true; -- cgit v1.2.1