From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp1.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 eMe6D/HU3GYfZQAA62LTzQ:P1 (envelope-from ) for ; Sun, 08 Sep 2024 00:34:25 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e224::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp1.migadu.com with LMTPS id eMe6D/HU3GYfZQAA62LTzQ (envelope-from ) for ; Sun, 08 Sep 2024 00:34:25 +0200 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b="DojNumC/"; dkim=pass header.d=johnnyrichard.com header.s=key1 header.b=IIk5Ud4w; dmarc=pass (policy=quarantine) header.from=johnnyrichard.com; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=johnnyrichard.com; s=key1; t=1725748465; h=from:from:sender:sender: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:list-id: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=NvVAElWZH+A6R2CdJ0ftHkFaOTX3XKOw/c+iP3lA3sU=; b=NNx3PQsASwOHbb5cT8FJdahaIIRJyL3wHL9EkXl5CJQOlrMqGga3XPlAtAgtI77WuhSOna mZwDEsrPhCowmFzOKsSflldbqvEC/FNIWVgHJi5NYMOy75qMxXzCkvciA3m/MPWQr/XEah YjKVUuHYCPSwua0ybMpg2gKm5PvyIQCPBUk0Pi+x1sjbPYGrq1RwyNgrt1RZOErz7+OQBt 0WIrURSOc6rnhTyh+YG/eAWw19NlMUlZ4WytisEQGJpuAD/FnQWPs8xqVSeFtPz2W9Qdwn h58Arzt0zKd124PPhWYxDNC6Z4ZRoy4v39xx+aq1d2vVt4KkSk4lOkT4+d0l9g== ARC-Seal: i=1; s=key1; d=johnnyrichard.com; t=1725748465; a=rsa-sha256; cv=none; b=UXGoL6haZXUlITrX2sokf8LrlSfsY5l4ugypCbYQASf0eeXns2kGUsbQvB2Fr7dm7Ijiha jEhFFOXnepWCmCZ+dhnV4QfVAQ5vq2p2c0yLERJzRPVnWkiyxginMW4ERybXO4M11jFteh m8fyxOd5a6KnIdHCviOBIQeBmoyA94w0ONJBaE+yIwqVhcEycBRcAs+ERH79axJ0UlhA8P DTSKRfVokb9pDLoTSoMuTFWFtxg2n6fgobrevtYg5RsIELXKVl2WIcqytR0IneStfxtvtC r/D5vgziKnT1ObaFSwjPIODqfA38h9C6bDyjO6kQ7EfqvLZJOd29yhL6rzSAxA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b="DojNumC/"; dkim=pass header.d=johnnyrichard.com header.s=key1 header.b=IIk5Ud4w; dmarc=pass (policy=quarantine) header.from=johnnyrichard.com; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht 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 08C26878F7 for ; Sun, 8 Sep 2024 00:34:25 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=2IA1/WrxRtMJwXUwPVZpVzMtW0fPfT9oxDDgN3peyGw=; 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=1725748464; v=1; b=DojNumC/xkqfbkI0zuvXUz4NhcB5sZmwkhqnjOZyb8gTMD8InNkKmhNM/NmkvelAhLewOnJd Jw8mqJSMJ1va9/NKNseemGbkwLc8PshIatYbEdpPdoPF9iZE02KCLaKU5r/xby2ylsObt2pLAx4 E1Y9kkFpTazdmmLuxWqGXSv9UBG2Uqh0ypBSVnSo8G4XmYtkGBUCJgR2jZdAyqagGpiGHtr9ZcT 647BcblSrWQfXepEyLlLCaf9ifW3qMhpXU3fjyFH7pSuWhYEYytOr/g2NfTpAH1W6ZUt1IHaHOa YzNCHONwc9WfdBZ4UwxpaExFppZWnvisazEnvVSsoMUMA== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id DD03D2027A for ; Sat, 07 Sep 2024 22:34:24 +0000 (UTC) Received: from out-176.mta1.migadu.com (out-176.mta1.migadu.com [95.215.58.176]) by mail-a.sr.ht (Postfix) with ESMTPS id F3A3B20235 for <~johnnyrichard/olang-devel@lists.sr.ht>; Sat, 07 Sep 2024 22:34: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=1725748463; 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=NvVAElWZH+A6R2CdJ0ftHkFaOTX3XKOw/c+iP3lA3sU=; b=IIk5Ud4wubw8mZJQjOfx59bzFOUJBXE0MjdGGpicpq4evet2fYgg7lKOqVdzxrUr9Hd5Y5 FUGAFPLSbtZAieeXUYsk2icmORofkOcwOkF28MHfHS+kSN2zXwuTPlIgwzYJ97LpJVmS+Z Mxk3rn03BUoU5Co+u9KplgvcL6RDo22vL46ccqystTtHmMED7/D31yMd/5V5UwddXC7ldg QOaoqUymbebbJ/jD8pj3zolTVAc9DwGQx3c6yXOo3to6WM1laf1NkAG9dKcJ2oBlcwI/Hj oj5NyhBASFPA3Ip1Okjevr3ih+jOkYl4ThTLTHDQKqMs86FNuOi+smf/c5lwSQ== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Carlos Maniero Subject: [PATCH olang 2/4] parser: parse a simple if statement Date: Sun, 8 Sep 2024 02:31:10 +0200 Message-ID: <20240908003402.145538-3-johnny@johnnyrichard.com> In-Reply-To: <20240908003402.145538-1-johnny@johnnyrichard.com> References: <20240908003402.145538-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-Queue-Id: 08C26878F7 X-Migadu-Scanner: mx12.migadu.com X-Migadu-Spam-Score: -5.89 X-Spam-Score: -5.89 X-TUID: /qBmq/U+OHHA From: Carlos Maniero There is no support for else-branch at this point. Signed-off-by: Carlos Maniero --- src/ast.c | 13 ++++ src/ast.h | 11 +++ src/parser.c | 79 +++++++++++++++++++- src/pretty_print_ast.c | 14 ++++ tests/integration/tests/0020_if_statement.ol | 15 ++++ 5 files changed, 128 insertions(+), 4 deletions(-) diff --git a/src/ast.c b/src/ast.c index aa9e6db..c1fb6f5 100644 --- a/src/ast.c +++ b/src/ast.c @@ -90,6 +90,19 @@ ast_new_node_return_stmt(arena_t *arena) return node_return_stmt; } +ast_node_t * +ast_new_node_if_stmt(arena_t *arena, ast_node_t *cond, ast_node_t *then) +{ + ast_node_t *node_if_stmt = arena_alloc(arena, sizeof(ast_node_t)); + assert(node_if_stmt); + + node_if_stmt->kind = AST_NODE_IF_STMT; + node_if_stmt->as_if_stmt.cond = cond; + node_if_stmt->as_if_stmt.then = then; + + return node_if_stmt; +} + ast_node_t * ast_new_node_block(arena_t *arena) { diff --git a/src/ast.h b/src/ast.h index 024f2cc..15260c5 100644 --- a/src/ast.h +++ b/src/ast.h @@ -32,6 +32,7 @@ typedef enum AST_NODE_FN_DEF, AST_NODE_BINARY_OP, AST_NODE_RETURN_STMT, + AST_NODE_IF_STMT, AST_NODE_LITERAL, AST_NODE_UNKNOWN } ast_node_kind_t; @@ -106,6 +107,12 @@ typedef struct ast_return_stmt ast_node_t *data; } ast_return_stmt_t; +typedef struct ast_if_stmt +{ + ast_node_t *cond; + ast_node_t *then; +} ast_if_stmt_t; + typedef struct ast_node { ast_node_kind_t kind; @@ -117,6 +124,7 @@ typedef struct ast_node ast_literal_t as_literal; ast_block_t as_block; ast_return_stmt_t as_return_stmt; + ast_if_stmt_t as_if_stmt; }; } ast_node_t; @@ -135,6 +143,9 @@ ast_new_node_literal_u32(arena_t *arena, uint32_t value); 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_node_t * ast_new_node_block(arena_t *arena); diff --git a/src/parser.c b/src/parser.c index 24094b3..c0ef977 100644 --- a/src/parser.c +++ b/src/parser.c @@ -36,6 +36,12 @@ parser_parse_type(parser_t *parser, type_t *type); static ast_node_t * parser_parse_block(parser_t *parser); +static ast_node_t * +parser_parse_return_stmt(parser_t *parser); + +static ast_node_t * +parser_parse_if_stmt(parser_t *parser); + ast_node_t * parser_parse_fn_definition(parser_t *parser); @@ -324,6 +330,46 @@ parser_parse_block(parser_t *parser) return NULL; } + token_t next_token; + +StartLoop: + lexer_peek_next(parser->lexer, &next_token); + ast_node_t *node = NULL; + + switch (next_token.kind) { + case TOKEN_RETURN: { + node = parser_parse_return_stmt(parser); + break; + } + case TOKEN_IF: { + node = parser_parse_if_stmt(parser); + break; + } + default: { + goto EndLoop; + } + } + + if (node == NULL) { + return NULL; + } + + list_append(node_block->as_block.nodes, node); + + goto StartLoop; +EndLoop: + + skip_line_feeds(parser->lexer); + if (!skip_expected_token(parser, TOKEN_CCURLY)) { + return NULL; + } + + return node_block; +} + +static ast_node_t * +parser_parse_return_stmt(parser_t *parser) +{ if (!skip_expected_token(parser, TOKEN_RETURN)) { return NULL; } @@ -338,17 +384,42 @@ parser_parse_block(parser_t *parser) node_return_stmt->as_return_stmt.data = expr; - list_append(node_block->as_block.nodes, node_return_stmt); if (!skip_expected_token(parser, TOKEN_LF)) { return NULL; } - skip_line_feeds(parser->lexer); - if (!skip_expected_token(parser, TOKEN_CCURLY)) { + + return node_return_stmt; +} + +static ast_node_t * +parser_parse_if_stmt(parser_t *parser) +{ + if (!skip_expected_token(parser, TOKEN_IF)) { return NULL; } - return node_block; + ast_node_t *cond = parser_parse_expr(parser); + + if (cond == NULL) { + return NULL; + } + + ast_node_t *then = parser_parse_block(parser); + + if (then == NULL) { + return NULL; + } + + ast_node_t *node_if_stmt = ast_new_node_if_stmt(parser->arena, cond, then); + assert(node_if_stmt); + + if (!skip_expected_token(parser, TOKEN_LF)) { + return NULL; + } + skip_line_feeds(parser->lexer); + + return node_if_stmt; } static bool diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c index 6ca172f..c3debe3 100644 --- a/src/pretty_print_ast.c +++ b/src/pretty_print_ast.c @@ -161,6 +161,20 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) return node; } + case AST_NODE_IF_STMT: { + pretty_print_node_t *node = pretty_print_node_new(arena); + ast_if_stmt_t if_stmt = ast->as_if_stmt; + + node->name = "If_Statement"; + + pretty_print_node_t *child = ast_node_to_pretty_print_node(if_stmt.cond, arena); + list_append(node->children, child); + + child = ast_node_to_pretty_print_node(if_stmt.then, arena); + list_append(node->children, child); + + return node; + } case AST_NODE_LITERAL: { pretty_print_node_t *node = pretty_print_node_new(arena); ast_literal_t literal = ast->as_literal; diff --git a/tests/integration/tests/0020_if_statement.ol b/tests/integration/tests/0020_if_statement.ol index f2f3262..ef3cd36 100644 --- a/tests/integration/tests/0020_if_statement.ol +++ b/tests/integration/tests/0020_if_statement.ol @@ -23,3 +23,18 @@ fn main(): u32 { # TEST test_contains_tokens WITH # ./tests/0020_if_statement.ol:17:3: # END + +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# `-Block +# |-If_Statement +# | |-Binary_Operation (==) +# | | |-Literal +# | | `-Literal +# | `-Block +# | `-Return_Statement +# | `-Literal +# `-Return_Statement +# `-Literal +# END -- 2.46.0