From 218ca7266ab91aba37796d1744e17cce59bfc89e Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 17 Jun 2022 10:58:12 +0200 Subject: [PATCH] Add routine for getting proper typename --- main.cpp | 2 +- programs/base_test.kl | 4 +-- typechecking.cpp | 64 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/main.cpp b/main.cpp index 7bbe029..b1294da 100644 --- a/main.cpp +++ b/main.cpp @@ -42,7 +42,6 @@ want to export all the symbols, we can namespace them optionally. @todo [ ] - Better error messages when type difference -[ ] - Casting pointers to and from void should be implicit [ ] - Kilobyte, Megabyte, Gigabyte [ ] - Mixing loads and imports leads to code duplication, is that what we want??? [ ] - Fix field access, cant cast, cant index @@ -74,6 +73,7 @@ want to export all the symbols, we can namespace them optionally. [ ] - Conditional compilation #if @donzo +[x] - Casting pointers to and from void should be implicit [x] - Multiple return values [x] - Add c string [-] - Should compound resolution use an algorithm to reorder compounds to initialize all fields in order diff --git a/programs/base_test.kl b/programs/base_test.kl index 495e012..11a77fb 100644 --- a/programs/base_test.kl +++ b/programs/base_test.kl @@ -3,7 +3,7 @@ main :: (argc: int, argv: **char): int arena: Arena arena_init(&arena) - data: *S64 = arena_push_size(&arena, size_of(S64)) + data: *S64 = allocate((&arena)->*Allocator, size_of(S64)) *data = 10 - arena_release(&arena) \ No newline at end of file + arena_release(&arena) diff --git a/typechecking.cpp b/typechecking.cpp index 93e9e58..699e8ef 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -16,6 +16,61 @@ check_value_bounds(Token *pos, Value *a){ } } +function void +typename_base(String_Builder *sb, Ast_Type *type){ + switch(type->kind){ + case TYPE_INCOMPLETE: sb->addf("INCOMPLETE"); break; + case TYPE_COMPLETING: sb->addf("COMPLETING"); break; + case TYPE_TYPE: sb->addf("TYPE"); break; + case TYPE_POINTER: + sb->addf("*"); + typename_base(sb, type->base); + break; + case TYPE_LAMBDA: + sb->addf("("); + For(type->func.args) typename_base(sb, it); + sb->addf("):"); + typename_base(sb, type->func.ret); + break; + case TYPE_ARRAY: + sb->addf("[%d]", (int)type->arr.size); + typename_base(sb, type->arr.base); + break; + case TYPE_SLICE: + sb->addf("[]"); + typename_base(sb, type->base); + break; + case TYPE_STRUCT: + case TYPE_ENUM:{ + // @todo direct access + auto constant = (Ast_Decl *)type->ast; + auto name = constant->name; + sb->addf("%Q", name); + break; + } + case TYPE_UNTYPED_BOOL: sb->addf("Untyped_Bool"); break; + case TYPE_UNTYPED_INT: sb->addf("Untyped_Int"); break; + case TYPE_UNTYPED_FLOAT: sb->addf("Untyped_Float"); break; + case TYPE_UNTYPED_STRING: sb->addf("Untyped_String"); break; + default: { + sb->addf("%s", name(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 * +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; +} + function Value convert_untyped_to_typed(Token *pos, Value a, Ast_Type *new_type){ assert(new_type); @@ -303,7 +358,8 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ } if(type && expr->type != type){ - compiler_error(pos, "Assigning but incompatible types, expression: %s expected var type: %s", docname(expr->type), docname(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)); } type_complete(expr->type); @@ -379,11 +435,12 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context = if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return 0; + Scratch scratch; Operand resolved = resolve_expr(ast, flags, 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", docname(resolved.type)); + compiler_error(ast->pos, "Expected [Type] got instead %s", get_typename(scratch, resolved.type)); return resolved.type_val; } @@ -395,9 +452,10 @@ resolve_and_require_bool(const char *error, Ast_Expr *expr, Resolve_Flag flags, else compiler_error(0, "Compiler error: Null expression"); } + 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", docname(op.type), error); + compiler_error(expr->pos, "Expected type [Bool] got instead type %s :: %s", get_typename(scratch, op.type), error); } return op;