From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id KJ8mEkPq8WbHLgAAe85BDQ:P1 (envelope-from ) for ; Tue, 24 Sep 2024 00:22:59 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id KJ8mEkPq8WbHLgAAe85BDQ (envelope-from ) for ; Tue, 24 Sep 2024 00:22:59 +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 3898277170 for ; Tue, 24 Sep 2024 00:22:59 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=nZNP0y8psfT82Czq+nPv9MMTn0s+0P8P8QWvjrPKCZM=; 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=1727130179; v=1; b=BPA/jh4oRUTgTHkKVoP7IDTwx7ycgnTlCzUflmDmvDeG1jdHFhf6ZFjw1HBnFSWBkx2vxJkf 9w3xw/gvQblTq/irgVVXWIGvGgWGlP7Z5YfLMDBfxNyDF2+G8Sd2y7t0d62L5YtPa8x3L29mV+X MX26uzkwPUC4K1Z0NT9SzMBRHq2DWaBeaDSED7RPGqqyofHkqCLZe+Nuo+51rlb9nG4u4qM0v56 LvoAKe4OcHv6D8yjHK8vVS0Gz35Cmkw9RcFAodiY6OHAiurIunOIu6hCKnNqCbjJFraJq8A6M+T cgU6XJIQBsUGE1oyQZMCioy2lxWvzUmko2oIGMigcTNvQ== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 02FC520222 for ; Mon, 23 Sep 2024 22:22:59 +0000 (UTC) Received: from out-177.mta0.migadu.com (out-177.mta0.migadu.com [91.218.175.177]) by mail-a.sr.ht (Postfix) with ESMTPS id 13B36201F0 for <~johnnyrichard/olang-devel@lists.sr.ht>; Mon, 23 Sep 2024 22:22:58 +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=1727130177; 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=6gfygEgL4jZSTyRfAJ8r3+hctesadXr+6snH5IZSKYQ=; b=UcwthaY/AOiyDDAYbuw2VstIGg82OacN5LzK6tyAtJfvV2xHzIsavZ5QXSEkcnOT8O5n0z MxJND+vYOxCEyt3ND7VdBhTUOiwpbXtVQPOSPBuTxpTxXY3jehLYuoCbhRFv7EHr5V1h0o 9lYqJOsKNMNah5fMDuLe1zz7UVhsAfbYTvnpsnTM3XaXDotLKiOAe560KHX7tGPAOEzX1T LO9VTo2Q1sHpmSYnQ+IZGRdOOsLLldLTUzpqRI1+TbpPn9SEVlmVNZK/asb4rZn6pK3PCY uXJ5Fz36lT3yRJaLpLhSf6iDlNnaHoK/sCr7oEYJO0K+OImbRK2f1QufZkKuUg== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1 3/3] parser: parse function params Date: Tue, 24 Sep 2024 00:20:00 +0200 Message-ID: <20240923222229.151017-4-johnny@johnnyrichard.com> In-Reply-To: <20240923222229.151017-1-johnny@johnnyrichard.com> References: <20240923222229.151017-1-johnny@johnnyrichard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Sourcehut-Patchset-Status: UNKNOWN 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-Spam-Score: -4.00 X-Spam-Score: -4.00 X-Migadu-Queue-Id: 3898277170 X-Migadu-Scanner: mx10.migadu.com X-TUID: /0VMoOjlOO6b Signed-off-by: Johnny Richard --- src/ast.c | 19 +++++++- src/ast.h | 12 ++++- src/parser.c | 66 ++++++++++++++++++++++---- src/pretty_print_ast.c | 17 +++++++ tests/olc/0027_function_with_params.ol | 9 ++++ 5 files changed, 112 insertions(+), 11 deletions(-) diff --git a/src/ast.c b/src/ast.c index bb74679..dc2e019 100644 --- a/src/ast.c +++ b/src/ast.c @@ -40,8 +40,12 @@ ast_new_translation_unit(arena_t *arena) } ast_node_t * -ast_new_node_fn_def(arena_t *arena, string_view_t id, string_view_t return_type, ast_node_t *block) +ast_new_node_fn_def(arena_t *arena, string_view_t id, list_t *params, string_view_t return_type, ast_node_t *block) { + assert(arena); + assert(params); + assert(block); + ast_node_t *node_fn_def = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t)); assert(node_fn_def); @@ -51,6 +55,7 @@ ast_new_node_fn_def(arena_t *arena, string_view_t id, string_view_t return_type, fn_def->id = id; fn_def->return_type = return_type; fn_def->block = block; + fn_def->params = params; return node_fn_def; } @@ -151,3 +156,15 @@ ast_new_node_block(arena_t *arena) return node_block; } + +ast_fn_param_t * +ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id) +{ + ast_fn_param_t *fn_param = (ast_fn_param_t *)arena_alloc(arena, sizeof(ast_fn_param_t)); + assert(fn_param); + + fn_param->id = id; + fn_param->type_id = type_id; + + return fn_param; +} diff --git a/src/ast.h b/src/ast.h index 6cfbfc0..7ba431f 100644 --- a/src/ast.h +++ b/src/ast.h @@ -51,9 +51,16 @@ typedef struct ast_translation_unit list_t *decls; } ast_translation_unit_t; +typedef struct ast_fn_param +{ + string_view_t id; + string_view_t type_id; +} ast_fn_param_t; + typedef struct ast_fn_definition { string_view_t id; + list_t *params; string_view_t return_type; ast_node_t *block; scope_t *scope; @@ -149,7 +156,7 @@ ast_node_t * ast_new_translation_unit(arena_t *arena); ast_node_t * -ast_new_node_fn_def(arena_t *arena, string_view_t id, string_view_t return_type, ast_node_t *block); +ast_new_node_fn_def(arena_t *arena, string_view_t id, list_t *params, string_view_t return_type, ast_node_t *block); ast_node_t * ast_new_node_var_def(arena_t *arena, string_view_t id, string_view_t type, ast_node_t *value); @@ -172,4 +179,7 @@ ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then, ast_nod ast_node_t * ast_new_node_block(arena_t *arena); +ast_fn_param_t * +ast_new_fn_param(arena_t *arena, string_view_t id, string_view_t type_id); + #endif /* AST_H */ diff --git a/src/parser.c b/src/parser.c index c79f3bd..11bb1cd 100644 --- a/src/parser.c +++ b/src/parser.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -48,9 +49,12 @@ parser_parse_if_stmt(parser_t *parser); static ast_node_t * parser_parse_var_def(parser_t *parser); -ast_node_t * +static ast_node_t * parser_parse_fn_definition(parser_t *parser); +static list_t * +parser_parse_fn_params(parser_t *parser); + static ast_node_t * parser_parse_expr(parser_t *parser); @@ -262,6 +266,55 @@ parser_parse_factor(parser_t *parser) } } +static list_t * +parser_parse_fn_params(parser_t *parser) +{ + if (!skip_expected_token(parser, TOKEN_OPAREN)) { + return NULL; + } + + list_t *params = arena_alloc(parser->arena, sizeof(list_t)); + if (params == NULL) { + fprintf(stderr, "[FATAL] Out of memory: parser_parse_fn_params: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + list_init(params, parser->arena); + + skip_line_feeds(parser->lexer); + + token_t token; + lexer_next_token(parser->lexer, &token); + + bool is_not_first_param = false; + + while (token.kind != TOKEN_CPAREN && token.kind != TOKEN_EOF) { + if (is_not_first_param && expected_token(parser, &token, TOKEN_COMMA)) { + lexer_next_token(parser->lexer, &token); + } + + if (!expected_token(parser, &token, TOKEN_ID)) { + return NULL; + } + + string_view_t type_id; + parser_parse_type(parser, &type_id); + + ast_fn_param_t *param = ast_new_fn_param(parser->arena, token.value, type_id); + list_append(params, param); + + skip_line_feeds(parser->lexer); + lexer_next_token(parser->lexer, &token); + is_not_first_param = true; + } + + if (!expected_token(parser, &token, TOKEN_CPAREN)) { + return NULL; + } + + return params; +} + ast_node_t * parser_parse_fn_definition(parser_t *parser) { @@ -279,13 +332,8 @@ parser_parse_fn_definition(parser_t *parser) skip_line_feeds(parser->lexer); - if (!skip_expected_token(parser, TOKEN_OPAREN)) { - return NULL; - } - - skip_line_feeds(parser->lexer); - - if (!skip_expected_token(parser, TOKEN_CPAREN)) { + list_t *params = parser_parse_fn_params(parser); + if (params == NULL) { return NULL; } @@ -301,7 +349,7 @@ parser_parse_fn_definition(parser_t *parser) return NULL; } - return ast_new_node_fn_def(parser->arena, fn_name_token.value, fn_return_type, block); + return ast_new_node_fn_def(parser->arena, fn_name_token.value, params, fn_return_type, block); } static bool diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c index 8116e60..b53ea5c 100644 --- a/src/pretty_print_ast.c +++ b/src/pretty_print_ast.c @@ -108,6 +108,17 @@ pretty_print_node_new(arena_t *arena) return node; } +static pretty_print_node_t * +pretty_print_new_fn_param(ast_fn_param_t *param, arena_t *arena) +{ + pretty_print_node_t *node = pretty_print_node_new(arena); + char name[256]; + sprintf(name, "Param_Definition ", SV_ARG(param->id), SV_ARG(param->type_id)); + node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1)); + strcpy(node->name, name); + return node; +} + static pretty_print_node_t * ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) { @@ -141,6 +152,12 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1)); strcpy(node->name, name); + list_item_t *param = list_head(fn_def.params); + while (param != NULL) { + list_append(node->children, pretty_print_new_fn_param(param->value, arena)); + param = list_next(param); + } + pretty_print_node_t *block = ast_node_to_pretty_print_node(fn_def.block, arena); list_append(node->children, block); return node; diff --git a/tests/olc/0027_function_with_params.ol b/tests/olc/0027_function_with_params.ol index f70fe7c..1d74d39 100644 --- a/tests/olc/0027_function_with_params.ol +++ b/tests/olc/0027_function_with_params.ol @@ -39,3 +39,12 @@ fn main(argc: u8, argv: u64): u8 { # ./0027_function_with_params.ol:18:1: <}> # END +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# |-Param_Definition +# |-Param_Definition +# `-Block +# `-Return_Statement +# `-Literal +# END -- 2.46.0