Fixing printing / memory issues, Add stage arena, printing types in errors properly

This commit is contained in:
Krzosa Karol
2022-06-18 09:50:34 +02:00
parent f876b69779
commit 28f89def4b
3 changed files with 48 additions and 42 deletions

View File

@@ -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);

View File

@@ -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(

View File

@@ -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<Ast_Call_Item *> items = {scratch};