diff --git a/compiler/passes/code_generator.oc b/compiler/passes/code_generator.oc index 244246a..44f59bc 100644 --- a/compiler/passes/code_generator.oc +++ b/compiler/passes/code_generator.oc @@ -811,7 +811,9 @@ def CodeGenerator::gen_statement(&this, node: &AST) { .gen_indent() if node.u.child? { - .out += "return " + if not node.u.child.returns { + .out += "return " + } .gen_expression(node.u.child, is_top_level: true) .out += ";\n" } else { @@ -907,9 +909,9 @@ def CodeGenerator::gen_statement(&this, node: &AST) { ASTType::Assert => { let expr = node.u.assertion.expr .gen_indent() - .out += "ae_assert(" + .out += "if(!(" .gen_expression(expr, is_top_level: true) - .out += ", " + .out += ")) { ae_assert_fail(" { .out += "\"" .out <<= expr.span.start.str() @@ -937,7 +939,7 @@ def CodeGenerator::gen_statement(&this, node: &AST) { if expr.type == BoolLiteral and expr.u.bool_literal == false { .out += " exit(1);" } - .out += "\n" + .out += " }\n" } else => { .gen_indent() diff --git a/compiler/passes/typechecker.oc b/compiler/passes/typechecker.oc index ae548c6..4c0a74a 100644 --- a/compiler/passes/typechecker.oc +++ b/compiler/passes/typechecker.oc @@ -1727,14 +1727,18 @@ def TypeChecker::check_statement(&this, node: &AST) { let expected = cur_func.return_type let res: &Type = null - if node.u.child? then res = .check_expression(node.u.child, hint: expected) + let child = node.u.child + if child? then res = .check_expression(child, hint: expected) - if expected.base == BaseType::Void { + if child? and child.returns { + // No need to check anything + + } else if expected.base == BaseType::Void { // We allow using arrow returns in void functions, they just don't return anything. if node.u.child? { .error(Error::new(node.span, "Cannot return a value from a void function")) } - } else if node.u.child? { + } else if child? { if res? and not res.eq(expected) { .error(Error::new(node.span, `Return type {res.str()} does not match function return type {expected.str()}`)) } diff --git a/std/mod.oc b/std/mod.oc index 60651ee..8518493 100644 --- a/std/mod.oc +++ b/std/mod.oc @@ -6,10 +6,14 @@ import .variadic [extern] [exits] def exit(code: i32 = 0) +[extern "oc_trap"] def builtin_trap() + [exits] def panic(msg: str = "") { println("%s", msg) - exit(1) + dump_backtrace() + builtin_trap() + std::exit(1) } [extern "atoi"] def str::to_i32(this): i32 diff --git a/std/prelude.h b/std/prelude.h index 82617a5..bf6878f 100644 --- a/std/prelude.h +++ b/std/prelude.h @@ -29,6 +29,7 @@ void dump_backtrace() { void *array[40]; size_t size = backtrace(array, 40); char **strings = backtrace_symbols(array, size); + printf("\nBacktrace:\n"); for (size_t i = 1; i < size; i++) { printf("%s\n", strings[i]); } @@ -36,20 +37,20 @@ void dump_backtrace() { #endif } -void ae_assert(int cond, char *dbg_msg, char *msg) { - if (!cond) { - printf("--------------------------------------------------------------------------------\n"); - printf("%s\n", dbg_msg); - if (msg) { - printf(" Message: %s\n", msg); - } - printf("--------------------------------------------------------------------------------\n"); - fflush(stdout); - dump_backtrace(); - #ifdef __APPLE__ - __builtin_debugtrap(); - #else - __builtin_trap(); - #endif +#ifdef __APPLE__ + #define oc_trap __builtin_debugtrap +#else + #define oc_trap __builtin_trap +#endif + +void ae_assert_fail(char *dbg_msg, char *msg) { + printf("--------------------------------------------------------------------------------\n"); + printf("%s\n", dbg_msg); + if (msg) { + printf(" Message: %s\n", msg); } -} \ No newline at end of file + printf("--------------------------------------------------------------------------------\n"); + fflush(stdout); + dump_backtrace(); + oc_trap(); +}