From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2.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 yKsRIBJv32ZYWgEAe85BDQ:P1 (envelope-from ) for ; Mon, 09 Sep 2024 23:56:34 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2.migadu.com with LMTPS id yKsRIBJv32ZYWgEAe85BDQ (envelope-from ) for ; Mon, 09 Sep 2024 23:56:34 +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 7457B1525E for ; Mon, 9 Sep 2024 23:56:31 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=LVhHDTxNvWsqDOnuXr1sFsWAlIykrECAhfS6AmVepJo=; 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=1725918991; v=1; b=IrvGZFPF2JnKixb7ZQhhVjcyf/PID+GMb9puP/+W1XQ8GLCm9L2mdosPqi7ECMMFIm8UblD2 jjbwQefLSByNUgEbIs4pFHw5Y4M5ZZmy14rMGVJJILcQmy68Q9XLEbIC5/gUpXdLK2xvDdzzgtA FCLxf1PZn/Sh8MCzaD97IA8W3Mr/0mAHnTHBs++yIRNFPXfbdZINdLe50D/qbBpAAws5Ug7FYGc AA556/9ZhwnNoWJ71FVP2vwv3XK9jmrtgPoQkg3KBYLD9pRjaZRlEQ//yUGCNA8yYG4JxdCI9br v9jiNZh/WSVALEt9YBFsPx9JQaPlGuod7JnUPKaHD4W8A== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 3FFFA20190 for ; Mon, 09 Sep 2024 21:56:31 +0000 (UTC) Received: from out-170.mta0.migadu.com (out-170.mta0.migadu.com [91.218.175.170]) by mail-a.sr.ht (Postfix) with ESMTPS id 9402E200B4 for <~johnnyrichard/olang-devel@lists.sr.ht>; Mon, 09 Sep 2024 21:56:30 +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=1725918990; 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=5WvFd4H8pjdWXQBSNQ8iHMH7Iii+rZEH/IKpSUQFYPc=; b=hwMv0+VCO2RMQSffboNBKDFZCfoT9A1VhXnjWWhJOq2MzVgexpjIriIFQ0swtQ9nvsKbBL L+IYU+Ro+xg8MDux9XXrCILJLApq879k3m1r3V+CXopmT7XX8a6gfM8cy/kJuHwfUmCSBm uzcOM5U3+PHG8h12e+pJZ5hhrPmzICDWU2O9FldTmGOk0kkN33b17ZqBrCDi414VIa7dIT qaOlcKdyMCaS9aXXwhP73XtVEON8Sb3UUIFpHaE/1e2TGDEDPtth1xiUVt+uTHUn99+BTr GAKnVn5i+Oh0z26E5KqKKsm1zpc2yMsgE3K806BvxJlWMOmtIXw/1YEFuZmxLg== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1 2/2] parser: add support to else branch Date: Tue, 10 Sep 2024 01:54:59 +0200 Message-ID: <20240909235611.84414-3-johnny@johnnyrichard.com> In-Reply-To: <20240909235611.84414-1-johnny@johnnyrichard.com> References: <20240909235611.84414-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-Queue-Id: 7457B1525E X-Migadu-Scanner: mx12.migadu.com X-Migadu-Spam-Score: -4.00 X-Spam-Score: -4.00 X-TUID: 4ZxepHe6eMt1 In order to implement _else_ we decided to add a new node to the _if_ ast struct, this new node will be a _block_ node. A new function to check expected token without eating next token was necessary to be implemented. Signed-off-by: Johnny Richard --- src/ast.c | 3 +- src/ast.h | 3 +- src/parser.c | 40 +++++++++++++++---- src/pretty_print_ast.c | 5 +++ .../integration/tests/0023_else_statement.ol | 16 ++++++++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/ast.c b/src/ast.c index c1fb6f5..4b252ae 100644 --- a/src/ast.c +++ b/src/ast.c @@ -91,7 +91,7 @@ ast_new_node_return_stmt(arena_t *arena) } ast_node_t * -ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then) +ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then, ast_node_t *_else) { ast_node_t *node_if_stmt = arena_alloc(arena, sizeof(ast_node_t)); assert(node_if_stmt); @@ -99,6 +99,7 @@ ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then) node_if_stmt->kind = AST_NODE_IF_STMT; node_if_stmt->as_if_stmt.cond = cond; node_if_stmt->as_if_stmt.then = then; + node_if_stmt->as_if_stmt._else = _else; return node_if_stmt; } diff --git a/src/ast.h b/src/ast.h index 15260c5..9bf3723 100644 --- a/src/ast.h +++ b/src/ast.h @@ -111,6 +111,7 @@ typedef struct ast_if_stmt { ast_node_t *cond; ast_node_t *then; + ast_node_t *_else; } ast_if_stmt_t; typedef struct ast_node @@ -144,7 +145,7 @@ ast_node_t * ast_new_node_return_stmt(arena_t *arena); ast_node_t * -ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then); +ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then, ast_node_t *_else); ast_node_t * ast_new_node_block(arena_t *arena); diff --git a/src/parser.c b/src/parser.c index c0ef977..8f49f5e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -27,6 +27,9 @@ static bool skip_expected_token(parser_t *parser, token_kind_t expected_kind); +static bool +expected_next_token(parser_t *parser, token_t *token, token_kind_t kind); + static bool expected_token(parser_t *parser, token_t *token, token_kind_t kind); @@ -260,7 +263,7 @@ parser_parse_fn_definition(parser_t *parser) token_t fn_name_token; - if (!expected_token(parser, &fn_name_token, TOKEN_IDENTIFIER)) { + if (!expected_next_token(parser, &fn_name_token, TOKEN_IDENTIFIER)) { return NULL; } @@ -304,7 +307,7 @@ parser_parse_type(parser_t *parser, type_t *type) { token_t token; - if (!expected_token(parser, &token, TOKEN_IDENTIFIER)) { + if (!expected_next_token(parser, &token, TOKEN_IDENTIFIER)) { return false; } @@ -411,12 +414,30 @@ parser_parse_if_stmt(parser_t *parser) return NULL; } - ast_node_t *node_if_stmt = ast_new_node_if_stmt(parser->arena, cond, then); - assert(node_if_stmt); + ast_node_t *_else = NULL; - if (!skip_expected_token(parser, TOKEN_LF)) { + token_t next_token; + lexer_next_token(parser->lexer, &next_token); + + // FIXME: We are not allowing line feed right after if block statement when + // the else branch is present. We also noticed that if has the same + // problem which will be addressed later. + + if (next_token.kind == TOKEN_ELSE) { + _else = parser_parse_block(parser); + + if (_else == NULL) { + return NULL; + } + + } else if (!expected_token(parser, &next_token, TOKEN_LF)) { return NULL; } + + ast_node_t *node_if_stmt = ast_new_node_if_stmt(parser->arena, cond, then, _else); + + assert(node_if_stmt); + skip_line_feeds(parser->lexer); return node_if_stmt; @@ -426,14 +447,19 @@ static bool skip_expected_token(parser_t *parser, token_kind_t expected_kind) { token_t token; - return expected_token(parser, &token, expected_kind); + return expected_next_token(parser, &token, expected_kind); } static bool -expected_token(parser_t *parser, token_t *token, token_kind_t expected_kind) +expected_next_token(parser_t *parser, token_t *token, token_kind_t expected_kind) { lexer_next_token(parser->lexer, token); + return expected_token(parser, token, expected_kind); +} +static bool +expected_token(parser_t *parser, token_t *token, token_kind_t expected_kind) +{ if (token->kind != expected_kind) { fprintf(stderr, "%s:%lu:%lu: error: got '" SV_FMT "' token but expect <%s>\n", diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c index c3debe3..3c12716 100644 --- a/src/pretty_print_ast.c +++ b/src/pretty_print_ast.c @@ -173,6 +173,11 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) child = ast_node_to_pretty_print_node(if_stmt.then, arena); list_append(node->children, child); + if (if_stmt._else != NULL) { + child = ast_node_to_pretty_print_node(if_stmt._else, arena); + list_append(node->children, child); + } + return node; } case AST_NODE_LITERAL: { diff --git a/tests/integration/tests/0023_else_statement.ol b/tests/integration/tests/0023_else_statement.ol index 60096e2..a741537 100644 --- a/tests/integration/tests/0023_else_statement.ol +++ b/tests/integration/tests/0023_else_statement.ol @@ -24,3 +24,19 @@ fn main(): u32 { # TEST test_contains_tokens WITH # ./tests/0023_else_statement.ol:19:5: # END + +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# `-Block +# `-If_Statement +# |-Binary_Operation (!=) +# | |-Literal +# | `-Literal +# |-Block +# | `-Return_Statement +# | `-Literal +# `-Block +# `-Return_Statement +# `-Literal +# END -- 2.46.0