diff options
| author | Baitinq <[email protected]> | 2025-05-20 23:19:46 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-20 23:19:46 +0200 |
| commit | b736233822765222c3963d03749b8f6200000dd3 (patch) | |
| tree | 868202dd7161897cbc2b0f745791b57d3608e140 /src | |
| parent | Feature: Add support for casting types (diff) | |
| download | interpreter-b736233822765222c3963d03749b8f6200000dd3.tar.gz interpreter-b736233822765222c3963d03749b8f6200000dd3.tar.bz2 interpreter-b736233822765222c3963d03749b8f6200000dd3.zip | |
Feature: Add more type checks
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap/main.src | 10 | ||||
| -rw-r--r-- | src/bootstrap/tokenizer.src | 28 | ||||
| -rw-r--r-- | src/codegen.zig | 38 |
3 files changed, 40 insertions, 36 deletions
diff --git a/src/bootstrap/main.src b/src/bootstrap/main.src index aa916d9..7917e04 100644 --- a/src/bootstrap/main.src +++ b/src/bootstrap/main.src @@ -1,13 +1,3 @@ -extern fopen = (*i8, *i8) => *i8; -extern fgets = (*i8, i64, *i8) => void; -extern feof = (*i8) => bool; -extern fseek = (*i8, i64, i64) => i64; -extern ftell = (*i8) => i64; -extern fread = (*i8, i64, i64, *i8) => i64; -extern fclose = (*i8) => *i8; -extern malloc = (i64) => *i8; -extern free = (*i8) => void; - import "!stdlib.src"; import "tokenizer.src"; diff --git a/src/bootstrap/tokenizer.src b/src/bootstrap/tokenizer.src index cb09e3f..051050c 100644 --- a/src/bootstrap/tokenizer.src +++ b/src/bootstrap/tokenizer.src @@ -1,5 +1,5 @@ extern strlen = (*i8) => i64; -extern memcpy = (*i8, *i8, i64) => void; +extern memcpy = (*void, *void, i64) => void; extern sprintf = (*i8, *i8, varargs) => void; extern atoi = (*i8) => i64; extern fopen = (*i8, *i8) => *i8; @@ -9,6 +9,8 @@ extern fseek = (*i8, i64, i64) => i64; extern ftell = (*i8) => i64; extern fread = (*i8, i64, i64, *i8) => i64; extern fclose = (*i8) => *i8; +extern malloc = (i64) => *void; +extern free = (*void) => void; import "!stdlib.src"; @@ -27,7 +29,7 @@ let read_file = (filename: *i8) => *i8 { file_size = ftell(file); fseek(file, 0, 0); - buf = malloc(file_size + 1); + buf = cast(*i8, malloc(file_size + 1)); let bytes_read = fread(buf, 1, file_size, file); (*(buf + bytes_read)) = '\0'; @@ -89,8 +91,8 @@ let tokenizer_accept_string = (str: *i8) => bool { let str_len = strlen(str); if offset + str_len > file_size { return false; }; - let s = malloc(1000); - memcpy(s, buf + offset, str_len); + let s = cast(*i8, malloc(1000)); + memcpy(cast(*void, s), cast(*void, buf + offset), str_len); if strcmp(s, str) { offset = offset + str_len; @@ -102,7 +104,7 @@ let tokenizer_accept_string = (str: *i8) => bool { let tokenizer_consume_until_condition = (condition: (i8) => bool) => *i8 { let start = offset; - let res = malloc(1000); + let res = cast(*i8, malloc(1000)); while true { if offset >= file_size { @@ -168,7 +170,7 @@ let tokenizer_accept_int_type = () => *i64 { if strlen(string) == 0 { return null; }; - let x = malloc(8); + let x = cast(*i64, malloc(8)); *x = atoi(string); return x; }; @@ -312,7 +314,7 @@ let tokenizer_next = () => *i8 { let maybe_int = tokenizer_accept_int_type(); if maybe_int != null { - let t = malloc(1000); + let t = cast(*i8, malloc(1000)); sprintf(t, "int:%d", *maybe_int); return t; @@ -320,7 +322,7 @@ let tokenizer_next = () => *i8 { let maybe_char = tokenizer_accept_char_type(); if maybe_char != null { - let t = malloc(1000); + let t = cast(*i8, malloc(1000)); sprintf(t, "char:%d", *maybe_char); return t; @@ -328,7 +330,7 @@ let tokenizer_next = () => *i8 { let maybe_string = tokenizer_accept_string_type(); if maybe_string != null { - let t = malloc(1000); + let t = cast(*i8, malloc(1000)); sprintf(t, "string:%s", maybe_string); return t; @@ -347,7 +349,7 @@ let tokenizer_next = () => *i8 { return null; }; - let t = malloc(100); + let t = cast(*i8, malloc(100)); sprintf(t, "identifier:%s", string); return t; @@ -360,7 +362,7 @@ let tokenizer_init = (filename: *i8) => i64 { println("%s", buf); - tokens = malloc(100000); + tokens = cast(*i8, malloc(100000)); while true { let t = tokenizer_next(); @@ -382,8 +384,8 @@ let tokenizer_init = (filename: *i8) => i64 { }; let tokenizer_deinit = () => i64 { - free(tokens); - free(buf); + free(cast(*void, tokens)); + free(cast(*void, buf)); return 0; }; diff --git a/src/codegen.zig b/src/codegen.zig index d6415cf..c9e39ea 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -161,16 +161,15 @@ 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)); } if (assignment_statement.is_dereference) { ptr = llvm.LLVMBuildLoad2(self.builder, try self.get_llvm_type(typ), ptr, ""); - } else { - // TODO: we should still do this with dereferences, but differently - // TODO: Do this in more places! (everywhere get_llvm_type?) - std.debug.assert(self.compare_types(typ, variable.node_type)); } - _ = llvm.LLVMBuildStore(self.builder, variable.value, ptr); if (assignment_statement.is_dereference) { @@ -187,7 +186,6 @@ pub const CodeGen = struct { if (assignment_statement.is_declaration) { try self.environment.add_variable(identifier.name, new_variable); } else { - // TODO: Dont allow changing types of variables if its not declaration try self.environment.set_variable(identifier.name, new_variable); } } else { @@ -223,8 +221,11 @@ pub const CodeGen = struct { var arguments = std.ArrayList(llvm.LLVMValueRef).init(self.arena); - for (function_call_statement.arguments) |argument| { + 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.assert(self.compare_types(expected_type, arg.node_type, false)); try arguments.append(arg.value); } @@ -458,6 +459,7 @@ 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 = .{ @@ -729,15 +731,24 @@ pub const CodeGen = struct { } } - fn compare_types(self: *CodeGen, a: *parser.Node, b: *parser.Node) bool { + fn compare_types(self: *CodeGen, a: *parser.Node, b: *parser.Node, is_dereference: bool) bool { std.debug.assert(a.* == parser.Node.TYPE); std.debug.assert(b.* == parser.Node.TYPE); - const a_type = a.TYPE; + var a_type = a.TYPE; const b_type = b.TYPE; + if (a_type == .SIMPLE_TYPE and std.mem.eql(u8, "varargs", a_type.SIMPLE_TYPE.name)) { + return true; + } + + if (is_dereference) { + a_type = a_type.POINTER_TYPE.type.TYPE; + } + if (!std.mem.eql(u8, @tagName(a_type), @tagName(b_type))) { - std.debug.print("Tagname mismatch: {s} vs {s}\n", .{ @tagName(a_type), @tagName(b_type) }); + std.debug.print("Tagname mismatch: {any} vs {any}\n", .{ a_type, b_type }); + return false; } switch (a_type) { @@ -752,7 +763,7 @@ pub const CodeGen = struct { .FUNCTION_TYPE => |a_func| { const b_func = b_type.FUNCTION_TYPE; - if (!self.compare_types(a_func.return_type, b_func.return_type)) { + if (!self.compare_types(a_func.return_type, b_func.return_type, false)) { std.debug.print("Function return type mismatch\n", .{}); return false; } @@ -763,7 +774,7 @@ pub const CodeGen = struct { } for (a_func.parameters, b_func.parameters) |a_param, b_param| { - if (!self.compare_types(a_param, b_param)) { + if (!self.compare_types(a_param, b_param, false)) { std.debug.print("Parameter type mismatch\n", .{}); return false; } @@ -773,7 +784,8 @@ pub const CodeGen = struct { }, .POINTER_TYPE => |a_ptr| { const b_ptr = b_type.POINTER_TYPE; - const res = self.compare_types(a_ptr.type, b_ptr.type); + + const res = self.compare_types(a_ptr.type, b_ptr.type, false); if (!res) { std.debug.print("Pointer base type mismatch\n", .{}); } |