From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id CCKzIhB/9GYbIwEAqHPOHw:P1 (envelope-from ) for ; Wed, 25 Sep 2024 23:22:24 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0.migadu.com with LMTPS id CCKzIhB/9GYbIwEAqHPOHw (envelope-from ) for ; Wed, 25 Sep 2024 23:22:24 +0200 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; none Received: from mail-a.sr.ht (mail-a.sr.ht [46.23.81.152]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 8010B1C1CE for ; Wed, 25 Sep 2024 23:22:24 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=8WWqJ1xdknVMMO3BnCgdutcZsXt0A4kJYjDbvODjZjo=; c=simple/simple; d=lists.sr.ht; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Unsubscribe:List-Subscribe:List-Archive:List-Post:List-ID; q=dns/txt; s=20240113; t=1727299344; v=1; b=EdSDnCUTKw9LE2G0YWM1d6+hhssNul4wobvJtJA/vPM1adeIcn4bviRQ56z5VxM1rYVbvBaO NxHeHnZtjlH73DOINtVItp4ceZ/9jSq7WBCXazVDFAZJD3oiyyfk4iKxOCEMUH/YErXrvS1wFtf xdqqmpZsIr+PUWyAhxiQT3mf5VngMJiRs2lLuUdQHgJAzxuhzR/S+hDKt8INh6VckJRJ5DZ/xdP VDYpQHVaBJOjhJsSrZgdghWuYf3QIzBz4laOhcFteJrTUovzKmlpsPUuEbdcK55EfCvlj7pXH0V Jw56RlBrcMSTy9hNU2N5W8K5Ma3YmM2bKMAui0ZhqqL3A== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 36271201FD for ; Wed, 25 Sep 2024 21:22:24 +0000 (UTC) Received: from out-172.mta1.migadu.com (out-172.mta1.migadu.com [95.215.58.172]) by mail-a.sr.ht (Postfix) with ESMTPS id 8A35C201FB for <~johnnyrichard/olang-devel@lists.sr.ht>; Wed, 25 Sep 2024 21:22:23 +0000 (UTC) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=johnnyrichard.com; s=key1; t=1727299343; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cVj9EJZ1pn+lYSRk0eF8yJzsselEYLFpLy8fBeTr+oY=; b=Vtl4KA1YsgAMUAkHs7RMi83LXGpWWjcZtQ0SSMUI0Nf6XXJ5mYjTYnT30KZj/t++2ao7v7 xRC6dOZEoQnIRovP+pxL2QzacYpZmdMsymd89sU4dVHdK8zutvMH23sY14KVvptbhb4ruK qcPl65ASC+LRksrFLkgK1cBjn1ORV5qTmNBf5V1STOk74B7yLjRjCq0JZPfiBLo/nYRy9d /q8UdN5QEiDViePE3XsxEtmG6p+4xhRZUlYuf/T8v40J4d8zxF8w1nv8Y/wj/xOLutTtsV Re/VrrrMRmTTglqRTEQy8xCd8m950msYbAKOTuTzur3Ex/QKd6UW6R7YYkwAZw== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1 2/2] parser: add support for parsing function calls Date: Thu, 26 Sep 2024 01:20:33 +0200 Message-ID: <20240925232209.54660-3-johnny@johnnyrichard.com> In-Reply-To: <20240925232209.54660-1-johnny@johnnyrichard.com> References: <20240925232209.54660-1-johnny@johnnyrichard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Sourcehut-Patchset-Status: PROPOSED List-Unsubscribe: List-Subscribe: List-Archive: Archived-At: List-Post: List-ID: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel.lists.sr.ht> Sender: ~johnnyrichard/olang-devel <~johnnyrichard/olang-devel@lists.sr.ht> X-Migadu-Flow: FLOW_IN X-Migadu-Country: NL X-Migadu-Scanner: mx12.migadu.com X-Migadu-Spam-Score: -4.00 X-Migadu-Queue-Id: 8010B1C1CE X-Spam-Score: -4.00 X-TUID: WM7Y3CQy9q+B Signed-off-by: Johnny Richard --- src/checker.c | 29 ++++++++++++++-- src/parser.c | 59 +++++++++++++++++++++++++++++++-- src/pretty_print_ast.c | 17 ++++++++++ tests/olc/0028_function_call.ol | 7 ++-- 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/src/checker.c b/src/checker.c index 814d052..7c3767f 100644 --- a/src/checker.c +++ b/src/checker.c @@ -64,12 +64,37 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast) } case AST_NODE_FN_DEF: { - ast->as_fn_def.scope = scope; - // FIXME: insert function symbol to scope + ast_fn_definition_t *fn_def = &ast->as_fn_def; + fn_def->scope = scope; + + list_item_t *item = list_head(fn_def->params); + + while (item != NULL) { + ast_fn_param_t *param = (ast_fn_param_t *)item->value; + + symbol_t *symbol = symbol_new(checker->arena, param->id, type_from_id(param->type_id)); + scope_insert(scope, symbol); + + item = list_next(item); + } + populate_scope(checker, scope, ast->as_fn_def.block); return; } + case AST_NODE_FN_CALL: { + ast->as_fn_call.scope = scope; + + list_item_t *item = list_head(ast->as_fn_call.args); + + while (item != NULL) { + populate_scope(checker, scope, (ast_node_t *)item->value); + item = list_next(item); + } + + return; + } + case AST_NODE_IF_STMT: { populate_scope(checker, scope, ast->as_if_stmt.cond); populate_scope(checker, scope, ast->as_if_stmt.then); diff --git a/src/parser.c b/src/parser.c index fba7b72..a025ed4 100644 --- a/src/parser.c +++ b/src/parser.c @@ -52,6 +52,9 @@ parser_parse_var_def(parser_t *parser); static ast_node_t * parser_parse_fn_definition(parser_t *parser); +static list_t * +parser_parse_fn_args(parser_t *parser); + static list_t * parser_parse_fn_params(parser_t *parser); @@ -253,8 +256,18 @@ parser_parse_factor(parser_t *parser) case TOKEN_NUMBER: return ast_new_node_literal_u32(parser->arena, string_view_to_u32(token.value)); - case TOKEN_ID: - return ast_new_node_ref(parser->arena, token.value); + case TOKEN_ID: { + string_view_t id = token.value; + + lexer_peek_next(parser->lexer, &token); + + if (token.kind == TOKEN_OPAREN) { + list_t *args = parser_parse_fn_args(parser); + return ast_new_node_fn_call(parser->arena, id, args); + } + + return ast_new_node_ref(parser->arena, id); + } case TOKEN_OPAREN: { ast_node_t *expr = parser_parse_expr(parser); @@ -275,6 +288,48 @@ parser_parse_factor(parser_t *parser) } } +static list_t * +parser_parse_fn_args(parser_t *parser) +{ + if (!skip_expected_token(parser, TOKEN_OPAREN)) { + return NULL; + } + + list_t *args = arena_alloc(parser->arena, sizeof(list_t)); + if (args == NULL) { + fprintf(stderr, "[FATAL] Out of memory: parser_parse_fn_args: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + list_init(args, parser->arena); + + skip_line_feeds(parser->lexer); + + token_t token; + lexer_peek_next(parser->lexer, &token); + + bool is_not_first_arg = false; + + while (token.kind != TOKEN_CPAREN && token.kind != TOKEN_EOF) { + if (is_not_first_arg && expected_token(parser, &token, TOKEN_COMMA)) { + lexer_next_token(parser->lexer, &token); + } + + ast_node_t *expr = parser_parse_expr(parser); + list_append(args, expr); + + skip_line_feeds(parser->lexer); + lexer_peek_next(parser->lexer, &token); + is_not_first_arg = true; + } + + if (!skip_expected_token(parser, TOKEN_CPAREN)) { + return NULL; + } + + return args; +} + static list_t * parser_parse_fn_params(parser_t *parser) { diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c index b53ea5c..2541544 100644 --- a/src/pretty_print_ast.c +++ b/src/pretty_print_ast.c @@ -162,6 +162,23 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) list_append(node->children, block); return node; } + case AST_NODE_FN_CALL: { + pretty_print_node_t *node = pretty_print_node_new(arena); + ast_fn_call_t fn_call = ast->as_fn_call; + + char name[256]; + sprintf(name, "Function_Call ", SV_ARG(fn_call.id)); + node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1)); + strcpy(node->name, name); + + list_item_t *item = list_head(fn_call.args); + while (item != NULL) { + list_append(node->children, ast_node_to_pretty_print_node(item->value, arena)); + item = list_next(item); + } + + return node; + } case AST_NODE_BLOCK: { pretty_print_node_t *node = pretty_print_node_new(arena); ast_block_t block = ast->as_block; diff --git a/tests/olc/0028_function_call.ol b/tests/olc/0028_function_call.ol index ccadc0d..cfaa969 100644 --- a/tests/olc/0028_function_call.ol +++ b/tests/olc/0028_function_call.ol @@ -14,8 +14,7 @@ # along with this program. If not, see . fn main(): u8 { - # TODO: call the function once function call is implemented - return 0 + return add(40, 2) } fn add(a: u32, b: u32): u8 { @@ -27,7 +26,9 @@ fn add(a: u32, b: u32): u8 { # |-Function_Definition # | `-Block # | `-Return_Statement -# | `-Literal +# | `-Function_Call +# | |-Literal +# | `-Literal # `-Function_Definition # |-Param_Definition # |-Param_Definition -- 2.46.0