From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp0.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id IDVTIONMBmeorwAAqHPOHw:P1 (envelope-from ) for ; Wed, 09 Oct 2024 11:29:07 +0200 Received: from aspmx1.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp0.migadu.com with LMTPS id IDVTIONMBmeorwAAqHPOHw (envelope-from ) for ; Wed, 09 Oct 2024 11:29:07 +0200 X-Envelope-To: patches@johnnyrichard.com Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=bU+alS6T; dkim=pass header.d=johnnyrichard.com header.s=key1 header.b=h8qrqoXe; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; dmarc=pass (policy=quarantine) header.from=johnnyrichard.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=johnnyrichard.com; s=key1; t=1728466147; 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:list-id: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=htV7k5m3GCkcfSstrQeQkhyaLjHfF74JbOc5qW+tpNM=; b=uVOKpyATrSqMadG3YWAUCRXg6ChfhryeCsRtksInkebGeVAIjKTuSe1vu80wTj3MoKdY+J 3i4WQtxjO8UlifW7iAHBE6tPgpkbdFzga7a0D6KdlDFKAeJnff2SYrsyKz2P5Wm2+5y5Xm LACxE789FSjwuQW3uzWbNVbms67wVqZ1dSi6XfouoK+a/1tkDurbmXn5VFMK1yfxREPlW8 qz8wIzBQm6tTS/bzuOL3HdErGRqCmbjiQnpuY7md5KnlT5f58bgZ0Ami+m/LTKlApoWoUo MdeqrHjuGbfUmC7QpcqPWNhdKaXgr0VX4ytcD5DzecszbFElR0VpiLnUPQdAlg== ARC-Seal: i=1; s=key1; d=johnnyrichard.com; t=1728466147; a=rsa-sha256; cv=none; b=LMlixsqPPEF+EPOBrYgAyNnxG/ZJcE60SMvHmpS0rD/KW7FAc2LqrunezNhmfwJDFTN4+I TU7etD9aVbHGnCB1eWa03GE950YNGubCYAGTsGi0YbZ58w0YF0iGqSwdKkR3tG2CpSFmay +zrHJAYdHdYk1v6gLCZkF8r8pwYQCXO1vxEQ9m8TqA8izx4bYP+rZeKQ+ZDPnAzvvQajSl fZ7lsPbHFVrFwZh8zNQ5adTq+sthmtrHEWjolkNjDnzLPwyyY3xIHQynTDNbei2jhaQo8A izKaAyumadAcdIEDJPrJd3h+joqeLgH+YCh2eFZNWZrS9nUizavo4WlMyn8KkA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=lists.sr.ht header.s=20240113 header.b=bU+alS6T; dkim=pass header.d=johnnyrichard.com header.s=key1 header.b=h8qrqoXe; spf=pass (aspmx1.migadu.com: domain of lists@sr.ht designates 46.23.81.152 as permitted sender) smtp.mailfrom=lists@sr.ht; dmarc=pass (policy=quarantine) header.from=johnnyrichard.com 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 7224959A8C for ; Wed, 09 Oct 2024 11:29:06 +0200 (CEST) DKIM-Signature: a=rsa-sha256; bh=ePRx8W+bj2vl5NFPJ1ov6wymzLzA0XynsAhHZsizECQ=; c=simple/simple; d=lists.sr.ht; h=From:To:Cc:Subject:Date:List-Unsubscribe:List-Subscribe:List-Archive:List-Post:List-ID; q=dns/txt; s=20240113; t=1728466146; v=1; b=bU+alS6TwmmRTctzJbVrwYHwcQWnThQW2IuI3NzdaSi/nwdPo6XkHDMX5jvFWrFJpiYVp3jJ rA5mx6OAhH+z2FFcZ8a9364Ei3+KrGNctvnFMAwbVaG8DAkYX5IPa4+/qPeF6qETnrlew/v5i4W kEBB4Z/NfYHLBgeWAsccJN8YGHpu9dKXg+Fe599RfGetNZR45AurBgBEMQeaEj8Z3UnsusFKriD pAsMnXvbp5ImzmNYzR4g57RoKZ9Sg0GZBBNjm0KCCJQVD59HEGdLh+pNkIJeZgdF5/jfgLWAuT7 OdWmjoVDthCAOcag27gtRqex33/cbir5Vo1QrGFfnJFsw== Received: from lists.sr.ht (unknown [46.23.81.154]) by mail-a.sr.ht (Postfix) with ESMTPSA id 40172201FA for ; Wed, 09 Oct 2024 09:29:06 +0000 (UTC) Received: from out-179.mta1.migadu.com (out-179.mta1.migadu.com [95.215.58.179]) by mail-a.sr.ht (Postfix) with ESMTPS id A07BA201E6 for <~johnnyrichard/olang-devel@lists.sr.ht>; Wed, 09 Oct 2024 09:29:05 +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=1728466145; 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; bh=htV7k5m3GCkcfSstrQeQkhyaLjHfF74JbOc5qW+tpNM=; b=h8qrqoXehb3hgDIcdHkUYKlEBc2KCDzFk9Cn1a2avDkDqvBIFpbagT/sHo5xkQX6+Kbj+A KKU5dm7DQhqpkCnoVM8SwRVEBklMXZPfAsCAgOGNJFAclVJxguXkIwq0PrxoITRmYpVa3P 8Rg4cYxGCj/XJvT+tVzj7vnpPqumFK6FKyfcGrKzUmZSlVv93/EgERg0rmOz67hnRDDu+u 6T1Uyu5N0YusPMua9/ZbJefmxnMNwuRfXROr9x80YKD5RA3Ah5c/MP6PgrQSI0b01+q6mh CmfWWnEoy1mQstQ7Vc2yS2tGfPigCxfIi51QMCUmQ2kFHsbja7oCy6WUe5yNJQ== From: Johnny Richard To: ~johnnyrichard/olang-devel@lists.sr.ht Cc: Johnny Richard Subject: [PATCH olang v1] parser: codegen(x86_64): docs: implement else if Date: Wed, 9 Oct 2024 13:28:38 +0200 Message-ID: <20241009112841.297176-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.89 X-Spam-Score: -4.89 X-Migadu-Queue-Id: 7224959A8C X-Migadu-Scanner: mx13.migadu.com X-TUID: o8TbyMVEKCoe Signed-off-by: Johnny Richard --- docs/info/getting-started.texi | 2 + docs/info/specification.texi | 2 +- src/codegen_linux_x86_64.c | 67 ++++++++++++++++++++-------------- src/parser.c | 8 +++- tests/olc/0032_else_if.ol | 50 +++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 tests/olc/0032_else_if.ol diff --git a/docs/info/getting-started.texi b/docs/info/getting-started.texi index 394b266..a68f5b1 100644 --- a/docs/info/getting-started.texi +++ b/docs/info/getting-started.texi @@ -71,6 +71,8 @@ Any non zero expr is true. @verbatim if expr { # statement +} else if expr { + # statement } else { # statement } diff --git a/docs/info/specification.texi b/docs/info/specification.texi index 1bac50f..6caaac8 100644 --- a/docs/info/specification.texi +++ b/docs/info/specification.texi @@ -42,7 +42,7 @@ language. ::= ( ',' )* ::= '(' ( | ) ')' ::= | | | | - ::= 'if' + ::= 'if' ( 'else' ( | ) )? ::= 'while' ::= 'return' diff --git a/src/codegen_linux_x86_64.c b/src/codegen_linux_x86_64.c index 5749e65..10005b9 100644 --- a/src/codegen_linux_x86_64.c +++ b/src/codegen_linux_x86_64.c @@ -66,6 +66,9 @@ codegen_linux_x86_64_emit_start_entrypoint(codegen_x86_64_t *codegen); static void codegen_linux_x86_64_emit_function(codegen_x86_64_t *codegen, ast_fn_definition_t *fn); +static void +codegen_linux_x86_64_emit_if(codegen_x86_64_t *codegen, ast_if_stmt_t is_stmt); + static void codegen_linux_x86_64_put_stack_offset(codegen_x86_64_t *codegen, symbol_t *symbol, size_t offset); @@ -597,34 +600,7 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block) } case AST_NODE_IF_STMT: { - ast_if_stmt_t if_stmt = node->as_if_stmt; - - ast_node_t *cond = if_stmt.cond; - ast_node_t *then = if_stmt.then; - ast_node_t *_else = if_stmt._else; - - size_t end_if_label = codegen_linux_x86_64_get_next_label(codegen); - size_t end_else_label = codegen_linux_x86_64_get_next_label(codegen); - - codegen_linux_x86_64_emit_expression(codegen, cond); - fprintf(codegen->out, " cmp $1, %%rax\n"); - fprintf(codegen->out, " jnz .L%ld\n", end_if_label); - - assert(then->kind == AST_NODE_BLOCK && "invalid if-then block"); - ast_block_t then_block = then->as_block; - - codegen_linux_x86_64_emit_block(codegen, &then_block); - fprintf(codegen->out, " jmp .L%ld\n", end_else_label); - - fprintf(codegen->out, ".L%ld:\n", end_if_label); - - if (_else != NULL) { - ast_block_t else_block = _else->as_block; - codegen_linux_x86_64_emit_block(codegen, &else_block); - } - - fprintf(codegen->out, ".L%ld:\n", end_else_label); - + codegen_linux_x86_64_emit_if(codegen, node->as_if_stmt); break; } @@ -664,6 +640,41 @@ codegen_linux_x86_64_emit_block(codegen_x86_64_t *codegen, ast_block_t *block) codegen->base_offset = block_offset; } +static void +codegen_linux_x86_64_emit_if(codegen_x86_64_t *codegen, ast_if_stmt_t if_stmt) +{ + ast_node_t *cond = if_stmt.cond; + ast_node_t *then = if_stmt.then; + ast_node_t *_else = if_stmt._else; + + size_t end_if_label = codegen_linux_x86_64_get_next_label(codegen); + size_t end_else_label = codegen_linux_x86_64_get_next_label(codegen); + + codegen_linux_x86_64_emit_expression(codegen, cond); + fprintf(codegen->out, " cmp $1, %%rax\n"); + fprintf(codegen->out, " jnz .L%ld\n", end_if_label); + + assert(then->kind == AST_NODE_BLOCK && "invalid if-then block"); + ast_block_t then_block = then->as_block; + + codegen_linux_x86_64_emit_block(codegen, &then_block); + fprintf(codegen->out, " jmp .L%ld\n", end_else_label); + + fprintf(codegen->out, ".L%ld:\n", end_if_label); + + if (_else != NULL) { + if (_else->kind == AST_NODE_IF_STMT) { + ast_if_stmt_t else_if = _else->as_if_stmt; + codegen_linux_x86_64_emit_if(codegen, else_if); + } else { + ast_block_t else_block = _else->as_block; + codegen_linux_x86_64_emit_block(codegen, &else_block); + } + } + + fprintf(codegen->out, ".L%ld:\n", end_else_label); +} + static size_t type_to_bytes(type_t *type) { diff --git a/src/parser.c b/src/parser.c index d498ea5..5d6290b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -573,7 +573,13 @@ parser_parse_if_stmt(parser_t *parser) lexer_next_token(parser->lexer, &next_token); skip_line_feeds(parser->lexer); - _else = parser_parse_block(parser); + lexer_peek_next(parser->lexer, &next_token); + + if (next_token.kind == TOKEN_IF) { + _else = parser_parse_if_stmt(parser); + } else { + _else = parser_parse_block(parser); + } if (_else == NULL) { return NULL; diff --git a/tests/olc/0032_else_if.ol b/tests/olc/0032_else_if.ol new file mode 100644 index 0000000..6260838 --- /dev/null +++ b/tests/olc/0032_else_if.ol @@ -0,0 +1,50 @@ +# 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 +{ + if 0 != 0 { + return 1 + } else if 1 == 1 { + return 0 + } + return 1 +} + +# XTEST test_compile(exit_code=0) + +# XTEST test_run_binary(exit_code=0) + +# TEST test_ast WITH +# Translation_Unit +# `-Function_Definition +# `-Block +# |-If_Statement +# | |-Binary_Operation (!=) +# | | |-Literal +# | | `-Literal +# | |-Block +# | | `-Return_Statement +# | | `-Literal +# | `-If_Statement +# | |-Binary_Operation (==) +# | | |-Literal +# | | `-Literal +# | `-Block +# | `-Return_Statement +# | `-Literal +# `-Return_Statement +# `-Literal +# END base-commit: 55edba3a0a62d33556e3366c49cd7ce5beab6665 -- 2.46.0