about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-05-10 16:05:51 +0200
committerBaitinq <[email protected]>2025-05-10 16:05:51 +0200
commitff00882673bae48ff2ddbc9f66e79efd624824ef (patch)
tree8f885c4914cee352d9a2cabcd80c870b90dddbf5
parentExamples: Add example sorting array (diff)
downloadinterpreter-ff00882673bae48ff2ddbc9f66e79efd624824ef.tar.gz
interpreter-ff00882673bae48ff2ddbc9f66e79efd624824ef.tar.bz2
interpreter-ff00882673bae48ff2ddbc9f66e79efd624824ef.zip
Feature: Support returning void from functions
Diffstat (limited to '')
-rw-r--r--examples/21.src12
-rw-r--r--grammar.ebnf2
-rw-r--r--src/codegen.zig7
-rw-r--r--src/parser.zig8
4 files changed, 17 insertions, 12 deletions
diff --git a/examples/21.src b/examples/21.src
index 62f3dda..c4c8032 100644
--- a/examples/21.src
+++ b/examples/21.src
@@ -3,25 +3,25 @@ extern rand = () => i64;
 extern malloc = (i64) => *i64;
 extern free = (*i64) => void;
 
-let init_array = (n: i64, arr: *i64) => i64 {
+let init_array = (n: i64, arr: *i64) => void {
 	let i = 0;
 	while i < n {
 		(*(arr + i)) = rand();
 		i = i + 1;
 	};
-	return 0;
+	return;
 };
 
-let print_array = (n: i64, arr: *i64) => i64 {
+let print_array = (n: i64, arr: *i64) => void {
 	let i = 0;
 	while i < n {
 		printf("%d\n", *(arr + i));
 		i = i + 1;
 	};
-	return 0;
+	return;
 };
 
-let sort_array = (n: i64, arr: *i64) => i64 {
+let sort_array = (n: i64, arr: *i64) => void {
 	let i = 0;
 	let j = 0;
 
@@ -42,7 +42,7 @@ let sort_array = (n: i64, arr: *i64) => i64 {
 		i = i + 1;
 	};
 
-	return 0;
+	return;
 };
 
 let main = () => i64 {
diff --git a/grammar.ebnf b/grammar.ebnf
index 70a1bfd..837de9e 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -14,7 +14,7 @@ IfStatement ::= "if" Expression LBRACE Statement* RBRACE -- TODO: Should functio
 
 WhileStatement ::= "while" Expression LBRACE Statement* RBRACE
 
-ReturnStatement ::= RETURN Expression
+ReturnStatement ::= RETURN (Expression)?
 
 FunctionArguments ::= Expression ("," Expression)*
 
diff --git a/src/codegen.zig b/src/codegen.zig
index 38febe6..05d31e9 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -235,7 +235,12 @@ pub const CodeGen = struct {
 
         const expression = statement.RETURN_STATEMENT.expression;
 
-        const val = try self.generate_expression_value(expression, null);
+        if (expression == null) {
+            _ = llvm.LLVMBuildRetVoid(self.builder);
+            return;
+        }
+
+        const val = try self.generate_expression_value(expression.?, null);
         _ = llvm.LLVMBuildRet(self.builder, val.value);
     }
 
diff --git a/src/parser.zig b/src/parser.zig
index 748d08b..e89479f 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -90,7 +90,7 @@ pub const Node = union(enum) {
         },
     },
     RETURN_STATEMENT: struct {
-        expression: *Node,
+        expression: ?*Node,
     },
 };
 
@@ -601,17 +601,17 @@ pub const Parser = struct {
         return node_list.items;
     }
 
-    // ReturnStatement ::= RETURN Expression
+    // ReturnStatement ::= RETURN (Expression)?
     fn parse_return_statement(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing return statement {any}\n", .{self.peek_token()});
 
         _ = try self.parse_token(tokenizer.TokenType.RETURN);
 
-        const expression = try self.parse_expression();
+        const maybe_expression = self.accept_parse(parse_expression);
 
         return self.create_node(.{
             .RETURN_STATEMENT = .{
-                .expression = @constCast(expression),
+                .expression = maybe_expression,
             },
         });
     }