about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-02-15 10:56:08 +0100
committerBaitinq <[email protected]>2025-02-15 11:00:04 +0100
commitfa6d9cdf57db4244a331035d35d1b962630e3ae1 (patch)
treed3926279eb046bbc11d4102ba8b336d037596da1
parentExamples: Update initial example with types (diff)
downloadpry-lang-fa6d9cdf57db4244a331035d35d1b962630e3ae1.tar.gz
pry-lang-fa6d9cdf57db4244a331035d35d1b962630e3ae1.tar.bz2
pry-lang-fa6d9cdf57db4244a331035d35d1b962630e3ae1.zip
Feature: Introduce initial support for function return types
-rw-r--r--examples/-1.src2
-rw-r--r--examples/0.src2
-rw-r--r--examples/1.5.src4
-rw-r--r--examples/1.src2
-rw-r--r--examples/10.src2
-rw-r--r--examples/11.src6
-rw-r--r--examples/2.src6
-rw-r--r--examples/3.src2
-rw-r--r--examples/4.src4
-rw-r--r--examples/5.src6
-rw-r--r--examples/6.5.src2
-rw-r--r--examples/6.src4
-rw-r--r--examples/7.src8
-rw-r--r--examples/8.src4
-rw-r--r--examples/9.src2
-rw-r--r--grammar.ebnf2
-rw-r--r--src/codegen.zig8
-rw-r--r--src/parser.zig8
18 files changed, 42 insertions, 32 deletions
diff --git a/examples/-1.src b/examples/-1.src
index 67db0a6..c92945a 100644
--- a/examples/-1.src
+++ b/examples/-1.src
@@ -1,5 +1,5 @@
 /* HELLO! Welcome to the unnamed language */
 
-let main = () => i8 {
+let main = () => i64 {
 	return 7;
 };
diff --git a/examples/0.src b/examples/0.src
index c4cf91d..29a5c85 100644
--- a/examples/0.src
+++ b/examples/0.src
@@ -1,6 +1,6 @@
 /* HELLO! Welcome to the unnamed language */
 
-let main = () => {
+let main = () => i64 {
 	print(18);
 	
 	return 2;
diff --git a/examples/1.5.src b/examples/1.5.src
index 0f6f7a0..1f99ee3 100644
--- a/examples/1.5.src
+++ b/examples/1.5.src
@@ -1,9 +1,9 @@
-let x = () => {
+let x = () => i64 {
 	print(22);
 	return 11;
 };
 
-let main = () => {
+let main = () => i64 {
 	let i = 4;
 
 	print(i);
diff --git a/examples/1.src b/examples/1.src
index cb29345..cc9cfe7 100644
--- a/examples/1.src
+++ b/examples/1.src
@@ -1,4 +1,4 @@
-let main = () => {
+let main = () => i64 {
 	let i = 4;
 
 	print(i);
diff --git a/examples/10.src b/examples/10.src
index 428ac92..0ec38ea 100644
--- a/examples/10.src
+++ b/examples/10.src
@@ -1,4 +1,4 @@
-let main = () => {
+let main = () => i64 {
 	let counter = 0;
 
 	while !(counter == 10) {
diff --git a/examples/11.src b/examples/11.src
index a572883..f859a0b 100644
--- a/examples/11.src
+++ b/examples/11.src
@@ -1,10 +1,10 @@
-let main = () => {
-	let x = (a) => {
+let main = () => i64 {
+	let x = (a) => i64 {
 		print(a);
 		return 1;
 	};
 
-	let y = (f) => {
+	let y = (f) => i64 {
 		return f(2);
 	};
 
diff --git a/examples/2.src b/examples/2.src
index a25bea5..646f1fa 100644
--- a/examples/2.src
+++ b/examples/2.src
@@ -1,11 +1,9 @@
-let main = () => {
+let main = () => i64 {
 	let test = 1922;
 
 	let uwu = test;
 
-	print(uwu); /* <- This is what triggers the problem */
+	print(uwu);
 
 	return 0;
 };
-
-/* TODO */
diff --git a/examples/3.src b/examples/3.src
index 49a0a52..92fb50a 100644
--- a/examples/3.src
+++ b/examples/3.src
@@ -1,4 +1,4 @@
-let main = () => {
+let main = () => i64 {
 	let seventeen = 10 + 2 + 4;
 
 	seventeen = seventeen + 1;
diff --git a/examples/4.src b/examples/4.src
index b7f10d3..b6e8ab3 100644
--- a/examples/4.src
+++ b/examples/4.src
@@ -1,5 +1,5 @@
-let main = () => {
-	let print_one = () => {
+let main = () => i64 {
+	let print_one = () => i64 {
 		print(1);
 		return 4;
 	};
diff --git a/examples/5.src b/examples/5.src
index 5d6baaa..7f4f38f 100644
--- a/examples/5.src
+++ b/examples/5.src
@@ -2,16 +2,16 @@
 
 let x = 18;
 
-let foo = () => {
+let foo = () => i64 {
 	let x = 1;
 	print(x);
 	return x;
 };
 
-let main = () => {
+let main = () => i64 {
 	print(x);
 	let x = 2;
-	let y= foo();
+	let y = foo();
 	print(x);
 	return x + y;
 };
diff --git a/examples/6.5.src b/examples/6.5.src
index ff3e40f..53abd86 100644
--- a/examples/6.5.src
+++ b/examples/6.5.src
@@ -1,4 +1,4 @@
-let main = () => {
+let main = () => i64 {
 	let x = !(1 == 1);
 	if !x {
 		printb(x);
diff --git a/examples/6.src b/examples/6.src
index 6ee6e52..6702c7a 100644
--- a/examples/6.src
+++ b/examples/6.src
@@ -1,10 +1,10 @@
-let print_input = (input_a, input_b) => {
+let print_input = (input_a, input_b) => i64 {
 	print(input_a);
 	print(input_b);
 	return input_a + input_b;
 };
 
-let main = () => {
+let main = () => i64 {
 	let i = print_input(1,4);
 	return print_input(7, 2) + i;
 };
diff --git a/examples/7.src b/examples/7.src
index 3fe60b6..c0690b6 100644
--- a/examples/7.src
+++ b/examples/7.src
@@ -1,10 +1,10 @@
-let ten = () => {
-	return () => {
+let ten = () => i64 {
+	return () => i64 {
 		return 10;
 	}();
-};
+}; /* TODO */
 
-let main = () => {
+let main = () => i64 {
 	let i = 4;
 	
 	if (1 - -1 * 2) == 5 - (-1 + 1 + ten() / 2) + 3 {
diff --git a/examples/8.src b/examples/8.src
index 33323f7..67c7dc3 100644
--- a/examples/8.src
+++ b/examples/8.src
@@ -1,4 +1,4 @@
-let fib = (n) => {
+let fib = (n) => i64 {
 	if n == 0 {
 		return 0;
 	};
@@ -8,7 +8,7 @@ let fib = (n) => {
 	return fib(n-2) + fib(n-1);
 };
 
-let main = () => {
+let main = () => i64 {
 	let result = fib(7);
 	print(result);
 	return result;
diff --git a/examples/9.src b/examples/9.src
index e898252..9b514e6 100644
--- a/examples/9.src
+++ b/examples/9.src
@@ -1,4 +1,4 @@
-let main = () => {
+let main = () => i64 {
 	let i = true;
 	i = !i;
 
diff --git a/grammar.ebnf b/grammar.ebnf
index 7175f6a..9265242 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -26,6 +26,6 @@ UnaryExpression ::= ("!" | "-") UnaryExpression | PrimaryExpression
 
 PrimaryExpression ::= NUMBER | BOOLEAN | IDENTIFIER | FunctionCallStatement | FunctionDefinition | LPAREN Expression RPAREN
 
-FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW LBRACE Statement* ReturnStatement SEMICOLON RBRACE
+FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW IDENTIFIER LBRACE Statement* ReturnStatement SEMICOLON RBRACE
 
 FunctionParameters ::= IDENTIFIER ("," IDENTIFIER)*
diff --git a/src/codegen.zig b/src/codegen.zig
index 3884923..ed1890d 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -247,7 +247,8 @@ pub const CodeGen = struct {
                     std.debug.assert(param.PRIMARY_EXPRESSION == .IDENTIFIER);
                     try paramtypes.append(core.LLVMInt64Type());
                 }
-                const function_type = core.LLVMFunctionType(core.LLVMInt64Type(), paramtypes.items.ptr, @intCast(paramtypes.items.len), 0) orelse return CodeGenError.CompilationError;
+                const return_type = get_llvm_type(function_definition.return_type);
+                const function_type = core.LLVMFunctionType(return_type, paramtypes.items.ptr, @intCast(paramtypes.items.len), 0) orelse return CodeGenError.CompilationError;
                 const function = core.LLVMAddFunction(self.llvm_module, try std.fmt.allocPrintZ(self.arena, "{s}", .{name orelse "unnamed_func"}), function_type) orelse return CodeGenError.CompilationError;
                 const function_entry = core.LLVMAppendBasicBlock(function, "entrypoint") orelse return CodeGenError.CompilationError;
                 core.LLVMPositionBuilderAtEnd(self.builder, function_entry);
@@ -455,6 +456,11 @@ pub const CodeGen = struct {
         });
     }
 
+    fn get_llvm_type(type_name: []const u8) types.LLVMTypeRef {
+        if (std.mem.eql(u8, type_name, "i64")) return core.LLVMInt64Type();
+        unreachable;
+    }
+
     fn create_print_function(self: *CodeGen) !void {
         const print_function_type = core.LLVMFunctionType(core.LLVMVoidType(), @constCast(&[_]types.LLVMTypeRef{core.LLVMInt64Type()}), 1, 0);
         const print_function = core.LLVMAddFunction(self.llvm_module, "print", print_function_type);
diff --git a/src/parser.zig b/src/parser.zig
index c5eb623..7d71de3 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -62,6 +62,7 @@ pub const Node = union(enum) {
     FUNCTION_DEFINITION: struct {
         statements: []*Node,
         parameters: []*Node,
+        return_type: []const u8,
     },
     RETURN_STATEMENT: struct {
         expression: *Node,
@@ -376,7 +377,7 @@ pub const Parser = struct {
         };
     }
 
-    // FunctionDefinition ::= LPAREN FunctionParamters? RPAREN ARROW LBRACE Statement* ReturnStatement RBRACE
+    // FunctionDefinition ::= LPAREN FunctionParameters? RPAREN ARROW IDENTIFIER LBRACE Statement* ReturnStatement SEMICOLON RBRACE
     fn parse_function_definition(self: *Parser) ParserError!*Node {
         errdefer if (!self.try_context) std.debug.print("Error parsing function definition {any}\n", .{self.peek_token()});
 
@@ -387,6 +388,10 @@ pub const Parser = struct {
         _ = try self.parse_token(tokenizer.TokenType.RPAREN);
 
         _ = try self.parse_token(tokenizer.TokenType.ARROW);
+
+        const type_expr = try self.parse_primary_expression();
+        if (type_expr.PRIMARY_EXPRESSION != .IDENTIFIER) return ParserError.ParsingError;
+
         _ = try self.parse_token(tokenizer.TokenType.LBRACE);
 
         var nodes = std.ArrayList(*Node).init(self.arena);
@@ -401,6 +406,7 @@ pub const Parser = struct {
         return self.create_node(.{ .FUNCTION_DEFINITION = .{
             .statements = nodes.items,
             .parameters = parameters,
+            .return_type = type_expr.PRIMARY_EXPRESSION.IDENTIFIER.name,
         } });
     }