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 0JcpCtvaBme3KgEAe85BDQ:P1 (envelope-from ) for ; Wed, 09 Oct 2024 21:34:51 +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 0JcpCtvaBme3KgEAe85BDQ (envelope-from ) for ; Wed, 09 Oct 2024 21:34:51 +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 1A65B1EC26 for ; Wed, 09 Oct 2024 21:34:51 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=JZoYLqfqeXTbFRA9vAYDa/n0BKgNo0WGGA/tan6HdVo=; 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=1728502491; v=1; b=LMY4YYc1Qc6gmf5+TjyKajqqKNgDmx7WqXuvuoTH6ng8xqs68z9G3Z95wF22e1+AZyXrRTJR QbIwnxlumDzV5v+2O/NOFytjU+dq7ZE68KZaFh0dAsfWA1hfdNcgHipEg/4EZtnZTGqrD8a08tv B+GxLGxAKZ0ZNCWWs2EavE+dMdTvoZ+51GVQLmN2TOy0/e2l/9FgNWErXuQU0TVRmc5v6JZs0sM DjKQUVRCUzIkL/d9IcV3w8a9S5JHW4yzzRTrfjOpGrZRVQeCLWjqge2CUktc/LtKmgdU34obNQa 9KsVE2VkWYvZc8grbJ7yIsEJjNcc6Jh/44k1bKUKg920Q== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id F2D802015C for ; Wed, 09 Oct 2024 19:34:50 +0000 (UTC) Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) by mail-a.sr.ht (Postfix) with ESMTPS id 2A7A2201D8 for <~johnnyrichard/olang-devel@lists.sr.ht>; Wed, 09 Oct 2024 19:34:50 +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=1728502490; 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=nEW/czvP9xjIccJpgd32hqc3Hy4pqWOXusrQpnJ3SPw=; b=canO63IWlNzeo7gYmrNbRI9Zms1nZfKGE5oUDevY0yONb6amX4q8ZrQU02jOlBnc4VG0f+ Zmcyc6HA49tTw6BokuczIPtWJzeCZ2/b7BNoIGGAOtWic40aaM/wDQ7paYVZhBXFty/ARM 4f2gcbpTnTCnG9jn1HrCgNZAicpQpso6nfu3njd1H5OIoGNBB6Vs5DpqJDvbJAKfKt1dYv /S1nOWOHHQcWI3QJdBb2Ia0TvVohYWcc9JLvpCX5cwMcdzdPbJlh+8wdGpzAczItb4kUvI 8JTnMF1YnQXK9UtujrMuFmF0k0zq8IW1caBVohtbLs7UQAhrhqJ6gi3b7mv5MA== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1 3/3] parser: codegen(x86_64): add bitwise not unary op support Date: Wed, 9 Oct 2024 23:18:29 +0200 Message-ID: <20241009213425.412949-4-johnny@johnnyrichard.com> In-Reply-To: <20241009213425.412949-1-johnny@johnnyrichard.com> References: <20241009213425.412949-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-Spam-Score: -4.00 X-Spam-Score: -4.00 X-Migadu-Queue-Id: 1A65B1EC26 X-Migadu-Scanner: mx12.migadu.com X-TUID: iSVUUikLhCmb Currently, all compiler tests rely on the exit code returned by a binary program, which restricts our testing to 8-bit unsigned numbers. To effectively test the bitwise-not unary operation within a main function, we utilize UINT32_MAX (4294967295), which represents a value with all bits set. The result of applying the bitwise-not operation to 0 is then used as the exit code. Signed-off-by: Johnny Richard --- src/ast.c | 14 ++++++++ src/ast.h | 22 ++++++++++++ src/checker.c | 7 ++++ src/codegen_linux_x86_64.c | 18 ++++++++++ src/parser.c | 35 ++++++++++++++++++++ src/pretty_print_ast.c | 22 +++++++++++- tests/olc/0033_unary_operator_bitwise_not.ol | 16 +++++++-- 7 files changed, 131 insertions(+), 3 deletions(-) diff --git a/src/ast.c b/src/ast.c index 79daca6..5a36ccb 100644 --- a/src/ast.c +++ b/src/ast.c @@ -117,6 +117,20 @@ ast_new_node_bin_op(arena_t *arena, token_loc_t loc, ast_binary_op_kind_t kind, return node_bin_op; } +ast_node_t * +ast_new_node_unary_op(arena_t *arena, token_loc_t loc, ast_unary_op_kind_t kind, ast_node_t *expr) +{ + ast_node_t *node_unary_op = (ast_node_t *)arena_alloc(arena, sizeof(ast_node_t)); + assert(node_unary_op); + + node_unary_op->kind = AST_NODE_UNARY_OP; + node_unary_op->loc = loc; + node_unary_op->as_unary_op.kind = kind; + node_unary_op->as_unary_op.expr = expr; + + return node_unary_op; +} + ast_node_t * ast_new_node_literal_u32(arena_t *arena, token_loc_t loc, uint32_t value) { diff --git a/src/ast.h b/src/ast.h index fccc303..ee94f57 100644 --- a/src/ast.h +++ b/src/ast.h @@ -36,6 +36,7 @@ typedef enum AST_NODE_FN_CALL, AST_NODE_VAR_DEF, AST_NODE_BINARY_OP, + AST_NODE_UNARY_OP, AST_NODE_VAR_ASSIGN_STMT, AST_NODE_RETURN_STMT, AST_NODE_IF_STMT, @@ -148,6 +149,23 @@ typedef struct ast_binary_op ast_node_t *rhs; } ast_binary_op_t; +typedef enum ast_unary_op_kind +{ + AST_UNARY_BITWISE_NOT, + AST_UNARY_LOGICAL_NOT, + AST_UNARY_NEGATIVE, + AST_UNARY_POSITIVE, + AST_UNARY_DEREFERENCE, + AST_UNARY_ADDRESSOF, +} ast_unary_op_kind_t; + +typedef struct ast_unary_op +{ + ast_node_meta_t meta; + ast_unary_op_kind_t kind; + ast_node_t *expr; +} ast_unary_op_t; + typedef struct ast_var_assign_stmt { ast_node_meta_t meta; @@ -189,6 +207,7 @@ typedef union ast_node ast_fn_call_t as_fn_call; ast_var_definition_t as_var_def; ast_binary_op_t as_bin_op; + ast_unary_op_t as_unary_op; ast_literal_t as_literal; ast_ref_t as_ref; ast_block_t as_block; @@ -218,6 +237,9 @@ ast_new_node_var_def(arena_t *arena, token_loc_t loc, string_view_t id, type_t * ast_node_t * ast_new_node_bin_op(arena_t *arena, token_loc_t loc, ast_binary_op_kind_t kind, ast_node_t *lhs, ast_node_t *rhs); +ast_node_t * +ast_new_node_unary_op(arena_t *arena, token_loc_t loc, ast_unary_op_kind_t kind, ast_node_t *expr); + ast_node_t * ast_new_node_literal_u32(arena_t *arena, token_loc_t loc, uint32_t value); diff --git a/src/checker.c b/src/checker.c index 7a9a7b6..62d612f 100644 --- a/src/checker.c +++ b/src/checker.c @@ -177,6 +177,13 @@ populate_scope(checker_t *checker, scope_t *scope, ast_node_t *ast) return; } + case AST_NODE_UNARY_OP: { + ast_unary_op_t unary_op = ast->as_unary_op; + + populate_scope(checker, scope, unary_op.expr); + return; + } + case AST_NODE_VAR_ASSIGN_STMT: { ast_var_assign_stmt_t var_assign_stmt = ast->as_var_assign_stmt; diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c index ac268ad..ae28aa5 100644 --- a/src/codegen_linux_x86_64.c +++ b/src/codegen_linux_x86_64.c @@ -530,6 +530,24 @@ codegen_linux_x86_64_emit_expression(codegen_x86_64_t *codegen, ast_node_t *expr } } } + + case AST_NODE_UNARY_OP: { + ast_unary_op_t unary_op = expr_node->as_unary_op; + switch (unary_op.kind) { + case AST_UNARY_BITWISE_NOT: { + size_in_bytes_t expr_bytes = codegen_linux_x86_64_emit_expression(codegen, unary_op.expr); + + fprintf(codegen->out, " not %s\n", get_reg_for(REG_ACCUMULATOR, expr_bytes)); + + return expr_bytes; + } + default: { + assert(0 && "unsupported unary operation"); + return 0; + } + } + } + default: assert(0 && "unsupported expression"); } diff --git a/src/parser.c b/src/parser.c index 0bfa282..f712bfc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -209,6 +209,27 @@ get_binary_op_precedence(token_kind_t kind) } } +static ast_unary_op_kind_t +token_kind_to_unary_op_kind(token_kind_t token_kind) +{ + switch (token_kind) { + case TOKEN_AND: + return AST_UNARY_ADDRESSOF; + case TOKEN_STAR: + return AST_UNARY_DEREFERENCE; + case TOKEN_PLUS: + return AST_UNARY_POSITIVE; + case TOKEN_DASH: + return AST_UNARY_NEGATIVE; + case TOKEN_TILDE: + return AST_UNARY_BITWISE_NOT; + case TOKEN_BANG: + return AST_UNARY_LOGICAL_NOT; + default: + assert(false && "unable to covert the token_kind_t to unary_op_kind_t"); + } +} + static ast_node_t * parser_parse_expr_1(parser_t *parser, ast_node_t *lhs, size_t prev_precedence) { @@ -275,6 +296,20 @@ parser_parse_factor(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_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); diff --git a/src/pretty_print_ast.c b/src/pretty_print_ast.c index edc6320..3a42412 100644 --- a/src/pretty_print_ast.c +++ b/src/pretty_print_ast.c @@ -258,7 +258,7 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) char name[256]; switch (literal.kind) { case AST_LITERAL_U32: { - sprintf(name, "Literal ", literal.as_u32); + sprintf(name, "Literal ", literal.as_u32); node->name = (char *)arena_alloc(arena, sizeof(char) * (strlen(name) + 1)); strcpy(node->name, name); break; @@ -383,6 +383,26 @@ ast_node_to_pretty_print_node(ast_node_t *ast, arena_t *arena) return node; } + + case AST_NODE_UNARY_OP: { + pretty_print_node_t *node = pretty_print_node_new(arena); + ast_unary_op_t unary_op = ast->as_unary_op; + + switch (unary_op.kind) { + case AST_UNARY_BITWISE_NOT: { + node->name = "Unary_Operation (~)"; + break; + } + default: + assert(false && "unary operation kind not implemented"); + } + + pretty_print_node_t *expr = ast_node_to_pretty_print_node(unary_op.expr, arena); + list_append(node->children, expr); + + return node; + } + default: { printf("node kind = '%d' not implmented\n", ast->kind); assert(false); diff --git a/tests/olc/0033_unary_operator_bitwise_not.ol b/tests/olc/0033_unary_operator_bitwise_not.ol index 1891549..7a9f59d 100644 --- a/tests/olc/0033_unary_operator_bitwise_not.ol +++ b/tests/olc/0033_unary_operator_bitwise_not.ol @@ -18,10 +18,22 @@ fn main(): u32 { return ~e } -# XTEST test_compile(exit_code=0) +# TEST test_compile(exit_code=0) # -# XTEST test_run_binary(exit_code=0) +# TEST test_run_binary(exit_code=0) # # TEST test_contains_tokens WITH # ./0033_unary_operator_bitwise_not.ol:18:10: <~> # END +# +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# `-Block +# |-Var_Definition +# | `-Literal +# `-Return_Statement +# `-Unary_Operation (~) +# `-Reference +# END + -- 2.46.0