about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <[email protected]>2025-05-22 23:16:27 +0200
committerBaitinq <[email protected]>2025-05-22 23:16:27 +0200
commit07e1f24cb43fbe3937383c0414fa035519e587f1 (patch)
tree0fb4607237266d5c31355709e32a45ee11c6d191 /src
parentFeature: Add more type checks (diff)
downloadpry-lang-07e1f24cb43fbe3937383c0414fa035519e587f1.tar.gz
pry-lang-07e1f24cb43fbe3937383c0414fa035519e587f1.tar.bz2
pry-lang-07e1f24cb43fbe3937383c0414fa035519e587f1.zip
Codegen: Typecheck function return types and change null type
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/tokenizer.src20
-rw-r--r--src/codegen.zig21
2 files changed, 24 insertions, 17 deletions
diff --git a/src/bootstrap/tokenizer.src b/src/bootstrap/tokenizer.src
index 051050c..ad98f1c 100644
--- a/src/bootstrap/tokenizer.src
+++ b/src/bootstrap/tokenizer.src
@@ -16,10 +16,10 @@ import "!stdlib.src";
 
 let offset = 0;
 
-let buf = null;
+let buf = cast(*i8, null);
 let file_size = 0;
 
-let tokens = null;
+let tokens = cast(*i8, null);
 let tokens_len = 0;
 
 let read_file = (filename: *i8) => *i8 {
@@ -157,7 +157,7 @@ let tokenizer_consume_until_condition = (condition: (i8) => bool) => *i8 {
 		offset = offset + 1;
 	};
 
-	return null;
+	return cast(*i8, null);
 };
 
 let tokenizer_accept_int_type = () => *i64 {
@@ -165,10 +165,10 @@ let tokenizer_accept_int_type = () => *i64 {
 		return !isdigit(c);
 	});
 	if string == null {
-		return null;
+		return cast(*i64, null);
 	};
 	if strlen(string) == 0 {
-		return null;
+		return cast(*i64, null);
 	};
 	let x = cast(*i64, malloc(8));
 	*x = atoi(string);
@@ -179,7 +179,7 @@ let tokenizer_accept_char_type = () => *i8 {
 	let prev_offset = offset;
 	if !tokenizer_accept_string("'") {
 		offset = prev_offset;
-		return null;
+		return cast(*i8, null);
 	};
 
 	let string = tokenizer_consume_until_condition((c: i8) => bool {
@@ -188,7 +188,7 @@ let tokenizer_accept_char_type = () => *i8 {
 
 	if !tokenizer_accept_string("'") {
 		offset = prev_offset;
-		return null;
+		return cast(*i8, null);
 	};
 
 	return string;
@@ -198,7 +198,7 @@ let tokenizer_accept_string_type = () => *i8 {
 	let prev_offset = offset;
 	if !tokenizer_accept_string("\"") {
 		offset = prev_offset;
-		return null;
+		return cast(*i8, null);
 	};
 
 	let string = tokenizer_consume_until_condition((c: i8) => bool {
@@ -207,7 +207,7 @@ let tokenizer_accept_string_type = () => *i8 {
 
 	if !tokenizer_accept_string("\"") {
 		offset = prev_offset;
-		return null;
+		return cast(*i8, null);
 	};
 
 	return string;
@@ -346,7 +346,7 @@ let tokenizer_next = () => *i8 {
 		return true;
 	});
 	if strlen(string) == 0 {
-		return null;
+		return cast(*i8, null);
 	};
 
 	let t = cast(*i8, malloc(100));
diff --git a/src/codegen.zig b/src/codegen.zig
index c9e39ea..11b8dd2 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -25,6 +25,7 @@ pub const CodeGen = struct {
     while_loop_exit: ?llvm.LLVMBasicBlockRef,
     while_block: ?llvm.LLVMBasicBlockRef,
     current_function: ?llvm.LLVMValueRef,
+    current_function_return_type: ?*parser.Node,
 
     pub fn init(arena: std.mem.Allocator) !*CodeGen {
         // Initialize LLVM
@@ -48,6 +49,7 @@ pub const CodeGen = struct {
             .while_loop_exit = null,
             .while_block = null,
             .current_function = null,
+            .current_function_return_type = null,
         };
 
         return self;
@@ -161,10 +163,9 @@ pub const CodeGen = struct {
             } else {
                 ptr = self.environment.get_variable(identifier.name).?.value;
                 typ = self.environment.get_variable(identifier.name).?.node_type;
-                // TODO: Do this in more places! (everywhere get_llvm_type?)  Also check types in return and cmp
-                const expected_type = typ;
-                std.debug.print("TYP {s}: {any} vs {any} -- {any}\n", .{ identifier.name, expected_type.TYPE, variable.node_type.TYPE, variable.node });
-                std.debug.assert(self.compare_types(expected_type, variable.node_type, assignment_statement.is_dereference));
+                // TODO: Do this in more places! (everywhere get_llvm_type or get_variable?)  Also check types in return and cmp
+                std.debug.print("TYP {s}: {any} vs {any} -- {any}\n", .{ identifier.name, typ.TYPE, variable.node_type.TYPE, variable.node });
+                std.debug.assert(self.compare_types(typ, variable.node_type, assignment_statement.is_dereference));
             }
 
             if (assignment_statement.is_dereference) {
@@ -224,7 +225,7 @@ pub const CodeGen = struct {
         for (0.., function_call_statement.arguments) |i, argument| {
             const arg = try self.generate_expression_value(argument, null);
             const expected_type = function.node_type.TYPE.FUNCTION_TYPE.parameters[i];
-            std.debug.print("TYP {s}: {any} vs {any}\n", .{ function_call_statement.expression.PRIMARY_EXPRESSION.IDENTIFIER.name, expected_type.TYPE, arg.node_type.TYPE });
+            std.debug.print("2 TYP {s}: {any} vs {any}\n", .{ function_call_statement.expression.PRIMARY_EXPRESSION.IDENTIFIER.name, expected_type.TYPE, arg.node_type.TYPE });
             std.debug.assert(self.compare_types(expected_type, arg.node_type, false));
             try arguments.append(arg.value);
         }
@@ -258,6 +259,10 @@ pub const CodeGen = struct {
         }
 
         const val = try self.generate_expression_value(expression.?, null);
+
+        std.debug.print("3TYP {any}: {any} vs {any}\n", .{ expression.?, self.current_function_return_type.?, val.node_type });
+        std.debug.assert(self.compare_types(self.current_function_return_type.?, val.node_type, false));
+
         _ = llvm.LLVMBuildRet(self.builder, val.value);
     }
 
@@ -380,8 +385,11 @@ pub const CodeGen = struct {
                 try self.environment.create_scope();
                 const last_function = self.current_function;
                 self.current_function = function;
+                const last_return_type = self.current_function_return_type;
+                self.current_function_return_type = function_definition.return_type;
                 defer {
                     self.current_function = last_function;
+                    self.current_function_return_type = last_return_type;
                     self.environment.drop_scope();
                 }
 
@@ -459,13 +467,12 @@ pub const CodeGen = struct {
             },
             .PRIMARY_EXPRESSION => |primary_expression| switch (primary_expression) {
                 .NULL => {
-                    //TODO: This should likely be *void.
                     return try self.generate_literal(llvm.LLVMConstNull(llvm.LLVMPointerType(llvm.LLVMInt8Type(), 0)), name, expression, try self.create_node(.{
                         .TYPE = .{
                             .POINTER_TYPE = .{
                                 .type = try self.create_node(.{
                                     .TYPE = .{ .SIMPLE_TYPE = .{
-                                        .name = "i8",
+                                        .name = "void",
                                     } },
                                 }),
                             },