ox

The Ox programming language, compiler and tools (WIP)
Log | Files | Refs | README | LICENSE

commit 157c35dfb7ac97d1c349d9db91be4bce02a692c9
parent 5c9795844aebf8f4141ad09db177de3d49e79008
Author: citbl <citbl@citbl.org>
Date:   Sun,  7 Dec 2025 12:23:05 +1000

better type matching and message

Diffstat:
Msrc/gen/gen.c | 9++++++---
Msrc/parser/stmt.c | 5++++-
Asrc/typer.c | 27+++++++++++++++++++++++++++
Asrc/typer.h | 6++++++
4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/gen/gen.c b/src/gen/gen.c @@ -1,6 +1,7 @@ #include "../gen.h" #include "../parser.h" #include "../utils.h" +#include "../typer.h" #include <stdint.h> #include <stdio.h> @@ -1063,9 +1064,11 @@ build_statement(Gen* gen, Node* node) case NODE_RETURN: { Node* return_expr = node->data.ret.expr; if (return_expr) { - gcc_jit_rvalue* ret_val = handle_expr(gen, return_expr); - gcc_jit_rvalue_get_type(ret_val); - gcc_jit_block_end_with_return(gen->curr_block, loc, ret_val); + gcc_jit_rvalue* ret_rval = handle_expr(gen, return_expr); + gcc_jit_type* expect_type = gcc_jit_function_get_return_type(gen->curr_func); + gcc_jit_type* ret_type = gcc_jit_rvalue_get_type(ret_rval); + types_match_or_panic(node, expect_type, ret_type); + gcc_jit_block_end_with_return(gen->curr_block, loc, ret_rval); } else { gcc_jit_block_end_with_void_return(gen->curr_block, loc); } diff --git a/src/parser/stmt.c b/src/parser/stmt.c @@ -170,10 +170,13 @@ parse_continue_statement(Parser* par) Node* parse_return_statement(Parser* par) { - expect(par, TOKEN_RETURN); // consume 'return' + Token tok = expect(par, TOKEN_RETURN); // consume 'return' Node* ret = (Node*)calloc(1, sizeof(Node)); if (ret == NULL) panic("parse_return_statemenet: could not alloc"); ret->type = NODE_RETURN; + ret->filename = par->filename; + ret->line = tok.line; + ret->col = tok.col; ret->scope = NULL; TokenType next_type = peek(par).type; diff --git a/src/typer.c b/src/typer.c @@ -0,0 +1,27 @@ +#include "typer.h" +#include "utils.h" +#include <string.h> + +static const char* +c_types_to_ox_str(const char* ctype) +{ + if (strcmp(ctype, "__int32_t") == 0) { + return "i32"; + } else if (strcmp(ctype, "__int64_t") == 0) { + return "i64"; + } else { + return "UNKNOWN C TYPE"; + } +} + +void +types_match_or_panic(Node* node, gcc_jit_type* expect, gcc_jit_type* actual) +{ + if (!gcc_jit_compatible_types(expect, actual)) { + gcc_jit_object* obj_a = gcc_jit_type_as_object(expect); + gcc_jit_object* obj_b = gcc_jit_type_as_object(actual); + const char* type_a = c_types_to_ox_str(gcc_jit_object_get_debug_string(obj_a)); + const char* type_b = c_types_to_ox_str(gcc_jit_object_get_debug_string(obj_b)); + panic_at(node, "Incompatible types: expected type <%s>, but got <%s>", type_a, type_b); + } +} diff --git a/src/typer.h b/src/typer.h @@ -0,0 +1,6 @@ +#pragma once + +#include <libgccjit.h> +#include "types.h" + +void types_match_or_panic(Node*, gcc_jit_type* a, gcc_jit_type* b);