From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0.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 sKFPHeDkDGehBAAAqHPOHw:P1 (envelope-from ) for ; Mon, 14 Oct 2024 11:31:12 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:4876::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0.migadu.com with LMTPS id sKFPHeDkDGehBAAAqHPOHw (envelope-from ) for ; Mon, 14 Oct 2024 11:31:12 +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 651C237063 for ; Mon, 14 Oct 2024 11:31:09 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=U1Oh4BHXALDOOfBXZMe0igCEsyvIWMMvq0U5GjiNzfU=; 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=1728898263; v=1; b=F7ITDNz7Hsh0+bwbFpTSbDhwcpffXzLwE9/EZt8iTh6EBp+m2Eim+cgiBiL5pk2u7gj2FjV/ vuXX7I6nJfTPC2cLnaDtuWK3jyC9HEy0WM3P11rqdAnCQd6lvG/+bwsrApkpWVtWJoYb5WRt5lq oSp2QGShBQzsCDeWfoGnYgHRufyEv+RD285brJ27wbRUxEi9gzfDhaegycx7dWHQYBgYG1cz75/ 73nxvOhROZzT2FK1VSJq9caJGqfmpk8Iqft3fsuQvolamZ1fYUH5BHonReb2NUS517RxsqVwf6H uZUqLi1BO4TDxIqCIzkjh/IsqI6n/qhBRC5dcm6uqLMjw== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 673E220183 for ; Mon, 14 Oct 2024 09:31:03 +0000 (UTC) Received: from out-187.mta0.migadu.com (out-187.mta0.migadu.com [91.218.175.187]) by mail-a.sr.ht (Postfix) with ESMTPS id AF9B72017A for <~johnnyrichard/olang-devel@lists.sr.ht>; Mon, 14 Oct 2024 09:31:02 +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=1728898262; 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=lyLQGRDscN5sBig8hFBjbK5uSCO3zSGJXKPpMd/u0C0=; b=kLPj4gEOhp0X9cS9av+5lLBEORPU/vyosVDA9+cqLCrMKi8g8E/fCOPLZc5CbObOyzjcbI b5N/yvohFf249om1McxPryjZUB50/F1226J0TmloXDT288IESCMt2BGnIO63K5guEXf+qV AnlQy1aWnNJCNXpFKbX9m3wguMnuWDQq8QiQce1Df7j6uD4UMbXp6J44At3MY5mGL383tR 7dzI7OglCcobqsufzUvPZhawMBugfFOYfkHBpRAIgQml52TFSZBKUsetCfLNAxsNA1AKBn EYOlAO8VCqNKJb+hbyl33n0gfnHpcLxU3q1Cv+nbvCvdmYhU4sjWf08AoOmJmw== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1 2/2] parser: spec: allow nested unary expressions Date: Mon, 14 Oct 2024 13:29:48 +0200 Message-ID: <20241014113011.108922-3-johnny@johnnyrichard.com> In-Reply-To: <20241014113011.108922-1-johnny@johnnyrichard.com> References: <20241014113011.108922-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-Country: NL X-Migadu-Flow: FLOW_IN X-Migadu-Spam-Score: -4.00 X-Spam-Score: -4.00 X-Migadu-Queue-Id: 651C237063 X-Migadu-Scanner: mx10.migadu.com X-TUID: 2xCwjfbxqgEm Signed-off-by: Johnny Richard --- docs/info/olang.ebnf | 13 ++++---- src/parser.c | 58 ++++++++++++++++++++++++---------- tests/olc/0035_unary_nested.ol | 36 +++++++++++++++++++++ 3 files changed, 84 insertions(+), 23 deletions(-) create mode 100644 tests/olc/0035_unary_nested.ol diff --git a/docs/info/olang.ebnf b/docs/info/olang.ebnf index 76a5c2f..791c6f0 100644 --- a/docs/info/olang.ebnf +++ b/docs/info/olang.ebnf @@ -52,19 +52,18 @@ ::= ( ('<' | '>' | '<=' | '>=') )* ::= ( ('<<' | '>>') )* ::= ( ('+' | '-') )* - ::= ( ('*' | '/' | '%') )* - ::= - | - | - | - | '(' ')' - ::= + ::= ( ('*' | '/' | '%') )* + ::= ( )* ::= '&' | '*' | '+' | '-' | '~' | '!' + ::= + | + | + | '(' ')' (* Identifiers *) ::= ('u8' | 'u16' | 'u32' | 'u64') ( '*')* diff --git a/src/parser.c b/src/parser.c index 8b103df..35cf017 100644 --- a/src/parser.c +++ b/src/parser.c @@ -28,6 +28,9 @@ static bool skip_expected_token(parser_t *parser, token_kind_t expected_kind); +static void +skip_next_token(parser_t *parser); + static bool expected_next_token(parser_t *parser, token_t *token, token_kind_t kind); @@ -64,6 +67,9 @@ parser_parse_fn_params(parser_t *parser); static ast_node_t * parser_parse_expr(parser_t *parser); +static ast_node_t * +parser_parse_unary_expr(parser_t *parser); + static ast_node_t * parser_parse_primary_expr(parser_t *parser); @@ -247,7 +253,7 @@ parser_parse_expr_1(parser_t *parser, ast_node_t *lhs, size_t prev_precedence) token_t token_op; lexer_next_token(parser->lexer, &token_op); - ast_node_t *rhs = parser_parse_primary_expr(parser); + ast_node_t *rhs = parser_parse_unary_expr(parser); if (rhs == NULL) { return NULL; } @@ -278,7 +284,7 @@ parser_parse_expr_1(parser_t *parser, ast_node_t *lhs, size_t prev_precedence) static ast_node_t * parser_parse_expr(parser_t *parser) { - ast_node_t *lhs = parser_parse_primary_expr(parser); + ast_node_t *lhs = parser_parse_unary_expr(parser); if (lhs == NULL) { return NULL; } @@ -286,6 +292,33 @@ parser_parse_expr(parser_t *parser) return parser_parse_expr_1(parser, lhs, BINOP_MIN_PREC); } +static ast_node_t * +parser_parse_unary_expr(parser_t *parser) +{ + token_t token; + lexer_peek_next(parser->lexer, &token); + switch (token.kind) { + case TOKEN_AND: + case TOKEN_STAR: + case TOKEN_PLUS: + case TOKEN_DASH: + case TOKEN_TILDE: + case TOKEN_BANG: { + skip_next_token(parser); + ast_node_t *expr = parser_parse_unary_expr(parser); + if (expr == NULL) { + return NULL; + } + + ast_unary_op_kind_t kind = token_kind_to_unary_op_kind(token.kind); + return ast_new_node_unary_op(parser->arena, token.loc, kind, expr); + } + default: { + return parser_parse_primary_expr(parser); + } + } +} + static ast_node_t * parser_parse_primary_expr(parser_t *parser) { @@ -310,20 +343,6 @@ parser_parse_primary_expr(parser_t *parser) return ast_new_node_ref( parser->arena, token_id.loc, token_id.value); } - case TOKEN_AND: - case TOKEN_STAR: - case TOKEN_PLUS: - case TOKEN_DASH: - case TOKEN_TILDE: - case TOKEN_BANG: { - ast_node_t *expr = parser_parse_primary_expr(parser); - if (expr == NULL) { - return NULL; - } - - ast_unary_op_kind_t kind = token_kind_to_unary_op_kind(token.kind); - return ast_new_node_unary_op(parser->arena, token.loc, kind, expr); - } case TOKEN_OPAREN: { ast_node_t *expr = parser_parse_expr(parser); @@ -740,6 +759,13 @@ skip_expected_token(parser_t *parser, token_kind_t expected_kind) return expected_next_token(parser, &token, expected_kind); } +static void +skip_next_token(parser_t *parser) +{ + token_t token; + lexer_next_token(parser->lexer, &token); +} + static bool expected_next_token(parser_t *parser, token_t *token, diff --git a/tests/olc/0035_unary_nested.ol b/tests/olc/0035_unary_nested.ol new file mode 100644 index 0000000..ef4e936 --- /dev/null +++ b/tests/olc/0035_unary_nested.ol @@ -0,0 +1,36 @@ +# Copyright (C) 2024 olang mantainers +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +fn main(): u32 { + var e: u32 = 0 + return ~~e +} + +# TEST test_compile(exit_code=0) +# +# TEST test_run_binary(exit_code=0) +# +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# `-Block +# |-Var_Definition +# | `-Literal +# `-Return_Statement +# `-Unary_Operation (~) +# `-Unary_Operation (~) +# `-Reference +# END + -- 2.46.0