From 28f89def4ba003e15b274f89c9cef408bfb1cf07 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 18 Jun 2022 09:50:34 +0200 Subject: [PATCH] Fixing printing / memory issues, Add stage arena, printing types in errors properly --- compiler.h | 2 ++ programs/main.kl | 1 + typechecking.cpp | 87 +++++++++++++++++++++++++----------------------- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/compiler.h b/compiler.h index ab3efad..13a048a 100644 --- a/compiler.h +++ b/compiler.h @@ -179,6 +179,7 @@ Intern_String intern_flag; struct Parse_Ctx:Lexer{ Allocator *perm; // Stores: AST, tokens, interns Allocator *heap; + Arena stage_arena; U64 type_ids; U64 unique_ids; // @Debug @@ -241,6 +242,7 @@ parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator) ctx->ordered_decls = {ctx->heap}; ctx->type_map = {ctx->heap}; ctx->modules = {ctx->heap}; + ctx->stage_arena = arena_sub(perm_allocator, mib(4), "Compiler stage arena"_s); bigint_allocator = ctx->perm; lex_init(ctx->perm, ctx->heap, ctx); diff --git a/programs/main.kl b/programs/main.kl index 8b37c25..8f212b1 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -70,6 +70,7 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS assert(RegisterClassW(&w) != 0) buff: *char = allocate(100) + thing: int = buff screen_size: Vec2I = {1280, 720} window := CreateWindowExW( diff --git a/typechecking.cpp b/typechecking.cpp index 699e8ef..acd419d 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -5,17 +5,6 @@ function String gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name //----------------------------------------------------------------------------- // Evaluating constant expressions //----------------------------------------------------------------------------- -function void -check_value_bounds(Token *pos, Value *a){ - if(!is_int(a->type)) return; - - Scratch scratch; - if(!bigint_fits_in_bits(&a->big_int_val, a->type->size*8, is_signed_int(a->type))){ - const char *string = bigint_to_error_string(scratch, &a->big_int_val, 10); - compiler_error(pos, "Value %s doesn't fit in type %s", string, docname(a->type)); - } -} - function void typename_base(String_Builder *sb, Ast_Type *type){ switch(type->kind){ @@ -58,17 +47,30 @@ typename_base(String_Builder *sb, Ast_Type *type){ } } -// @todo: takes too much memory from caller -// Caching String_Builder would be cool and then having -// a pass arena or something -function const char * +function String get_typename(Allocator *a, Ast_Type *type){ - String_Builder sb = {a}; - sb.addf("["); - typename_base(&sb, type); - sb.addf("]"); - String result = string_flatten(a, &sb); - return (const char *)result.str; + pctx->gen.addf("["); + typename_base(&pctx->gen, type); + pctx->gen.addf("]"); + String result = string_flatten(a, &pctx->gen); + pctx->gen.reset(); + return result; +} + +function String +typestring(Ast_Type *type){ + return get_typename(&pctx->stage_arena, type); +} + +function void +check_value_bounds(Token *pos, Value *a){ + if(!is_int(a->type)) return; + + Scratch scratch; + if(!bigint_fits_in_bits(&a->big_int_val, a->type->size*8, is_signed_int(a->type))){ + const char *string = bigint_to_error_string(scratch, &a->big_int_val, 10); + compiler_error(pos, "Value %s doesn't fit in type %Q", string, typestring(a->type)); + } } function Value @@ -91,7 +93,7 @@ convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){ ; // nothing to do else if(is_string(a.type) && is_string(new_type)) ; // nothing to do - else compiler_error(pos, "Type mismatch when converting from %s to %s", docname(a.type), docname(new_type)); + else compiler_error(pos, "Type mismatch when converting from %Q to %Q", typestring(a.type), typestring(new_type)); a.type = new_type; check_value_bounds(pos, &a); @@ -108,7 +110,7 @@ make_sure_types_are_compatible_for_constant_evaluation(Token *pos, Value *a, Val } else if(is_typed(a->type) && is_typed(b->type)){ if(a->type != b->type){ - fail: compiler_error(pos, "Type mismatch in make_sure_types_are_compatible_for_constant_evaluation - left: %s right: %s", docname(a->type), docname(b->type)); + fail: compiler_error(pos, "Type mismatch in make_sure_types_are_compatible_for_constant_evaluation - left: %Q right: %Q", typestring(a->type), typestring(b->type)); } } @@ -133,7 +135,7 @@ compare_values(Token *pos, Token_Kind op, Value a, Value b, bool is_const){ if(is_enum(a.type) && (a.type == b.type)) goto skip_eval; if(!(is_numeric(a.type) && is_numeric(b.type))) - compiler_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type)); + compiler_error(pos, "Constant application of binary %s on values of type %Q and %Q is not allowed", name(op), typestring(a.type), typestring(b.type)); make_sure_types_are_compatible_for_constant_evaluation(pos, &a, &b); @@ -187,7 +189,7 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b, bool is_const){ return compare_values(pos, op, a, b, is_const); if(!(is_numeric(a.type) && is_numeric(b.type))) - compiler_error(pos, "Constant application of binary %s on values of type %s and %s is not allowed", name(op), docname(a.type), docname(b.type)); + compiler_error(pos, "Constant application of binary %s on values of type %Q and %Q is not allowed", name(op), typestring(a.type), typestring(b.type)); make_sure_types_are_compatible_for_constant_evaluation(pos, &a, &b); @@ -253,7 +255,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){ Value *a = &operand->value; Ast_Type *type = a->type; if(!is_numeric(type)) - compiler_error(pos, "Unary [%s] cant be applied to value of type %s", name(op), docname(type)); + compiler_error(pos, "Unary [%s] cant be applied to value of type %Q", name(op), typestring(type)); if(op == TK_Not) a->type = untyped_bool; @@ -302,7 +304,7 @@ eval_unary(Token *pos, Token_Kind op, Operand *operand){ default:goto failure; } } break; - default: failure: compiler_error(pos, "Constant application of unary %s on values of type %s is not allowed", name(op), docname(a->type)); + default: failure: compiler_error(pos, "Constant application of unary %s on values of type %Q is not allowed", name(op), typestring(a->type)); } } @@ -358,8 +360,9 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ } if(type && expr->type != type){ - Scratch scratch; - compiler_error(pos, "Assigning but incompatible types, expression: %s expected var type: %s", get_typename(scratch, expr->type), get_typename(scratch, type)); + String expr_type_string = typestring(expr->type); + String type_string = typestring(type); + compiler_error(pos, "Assigning but incompatible types, expression: %Q expected var type: %Q", expr_type_string, type_string); } type_complete(expr->type); @@ -440,7 +443,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE)) type_complete(resolved.type_val); if(resolved.type != type_type) - compiler_error(ast->pos, "Expected [Type] got instead %s", get_typename(scratch, resolved.type)); + compiler_error(ast->pos, "Expected [Type] got instead %Q", typestring(resolved.type)); return resolved.type_val; } @@ -455,7 +458,7 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, Scratch scratch; Operand op = resolve_expr(expr, flags, compound_context); if(!is_bool(op.type)){ - compiler_error(expr->pos, "Expected type [Bool] got instead type %s :: %s", get_typename(scratch, op.type), error); + compiler_error(expr->pos, "Expected type [Bool] got instead type %Q :: %s", typestring(op.type), error); } return op; @@ -473,7 +476,7 @@ require_const_int(Ast_Expr *expr, Resolve_Flag flags, Ast_Type *compound_context if(!op.is_const) compiler_error(expr->pos, "Expected a const value"); if(!is_int(op.type)) - compiler_error(expr->pos, "Expected a constant integer got instead %s", docname(op.type)); + compiler_error(expr->pos, "Expected a constant integer got instead %Q", typestring(op.type)); return op; } @@ -500,7 +503,7 @@ resolve_stmt(Ast *ast, Ast_Type *ret){ Value value = {}; value.type = type; value = convert_untyped_to_typed(node->pos, value, ret); if(value.type && value.type != ret) - compiler_error(node->pos, "Return statement has different type then returned value, expecting: %s got instead %s", docname(ret), docname(type)); + compiler_error(node->pos, "Return statement has different type then returned value, expecting: %Q got instead %Q", typestring(ret), typestring(type)); node->resolved_type = value.type; BREAK(); } @@ -665,7 +668,7 @@ resolve_cast(Ast_Binary *node){ expr.type = type; } else goto failure; } break; - default: failure: compiler_error(node->pos, "Failed to cast from %s to %s", docname(expr.type), docname(type));; + default: failure: compiler_error(node->pos, "Failed to cast from %Q to %Q", typestring(expr.type), typestring(type));; } assert(original_type != type ? expr.type == type : 1); @@ -866,7 +869,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL); Operand index = resolve_expr(node->index, AST_CANT_BE_NULL); if(!is_int(index.type)){ - compiler_error(node->pos, "Trying to index the array with invalid type, expected [Int] got instead %s", docname(index.type)); + compiler_error(node->pos, "Trying to index the array with invalid type, expected [Int] got instead %Q", typestring(index.type)); } node->index_original_type = left.type; @@ -875,7 +878,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ return operand_lvalue(type_u8); } else if(!is_array(left.type) && !is_pointer(left.type)){ - compiler_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %s instead", docname(left.type)); + compiler_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %Q instead", typestring(left.type)); } return operand_lvalue(left.type->arr.base); @@ -890,7 +893,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ Operand right = resolve_expr(node->right, AST_CANT_BE_NULL); right.value = convert_untyped_to_typed(node->pos, right.value, left.type); - if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %s and right is %s", docname(left.type), docname(right.type)); + if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %Q and right is %Q", typestring(left.type), typestring(right.type)); node->resolved_type = right.type; return {}; } @@ -936,7 +939,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ node->resolved_type = type_pointer(value.type_val); return operand_type(node->resolved_type); } - else{ compiler_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", docname(value.type)); return {}; } + else{ compiler_error(node->pos, "Dereferencing expression %Q that is not a [Pointer] or [Type]", typestring(value.type)); return {}; } } else if(node->op == TK_Dereference){ node->resolved_type = type_pointer(value.type); @@ -960,7 +963,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ Ast_Type *type = op.type; if(type){ if(type != type_type) - compiler_error(node->pos, "Expected type [Type] got instead %s", docname(type)); + compiler_error(node->pos, "Expected type [Type] got instead %Q", typestring(type)); type = op.type_val; } if(!type) @@ -1010,7 +1013,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ rewrite_into_const(node, Ast_Builtin, value); return operand_const_rvalue(value); } - else compiler_error(node->pos, "Can't get length of type %s", docname(name.type_val)); + else compiler_error(node->pos, "Can't get length of type %Q", typestring(name.type_val)); } else if(name.type->kind == TYPE_UNTYPED_STRING){ Value value = value_int(name.intern_val.len); @@ -1020,14 +1023,14 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ else if(is_array(name.type) || is_slice(name.type) || is_string(name.type)){ return operand_rvalue(type_s64); } - else compiler_error(node->pos, "Can't get length of type %s", docname(name.type)); + else compiler_error(node->pos, "Can't get length of type %Q", typestring(name.type)); BREAK(); } CASE(CALL, Call){ Operand name = resolve_expr(node->name, AST_CANT_BE_NULL); if(name.type->kind != TYPE_LAMBDA) - compiler_error(node->pos, "Calling %s which is not a [Lambda]", docname(name.type)); + compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type)); Scratch scratch; Array items = {scratch};