From cd3098da45e6514805707f09f761de87ea347bed Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sun, 12 Jun 2022 11:58:36 +0200 Subject: [PATCH] Add char * which is supposed to work like in C and int --- G.globals.kl | 4 ++- ast.cpp | 4 +-- ccodegen.cpp | 13 +++++--- compiler.h | 4 ++- main.cpp | 4 +-- typechecking.cpp | 5 +-- typechecking.h | 4 +++ types.h | 81 +++++++++++------------------------------------- 8 files changed, 43 insertions(+), 76 deletions(-) diff --git a/G.globals.kl b/G.globals.kl index 8a5db57..11a7a15 100644 --- a/G.globals.kl +++ b/G.globals.kl @@ -28,7 +28,9 @@ imp_array := [5]S64{1,2} imp_array_c: [5]S64 = {[0] = 1, [2] = 2, [1] = 0} // @todo this should be illegal // without_size: []S64 = {} // @todo: this should be slice, converting from array should be implicit -string: char = "string" +string: *char = "string" +first_letter := string[0] +decl_char: char = 55 //----------------------------------------------------------------------------- // Pointers diff --git a/ast.cpp b/ast.cpp index 1a3613d..004b391 100644 --- a/ast.cpp +++ b/ast.cpp @@ -64,13 +64,13 @@ struct Ast_Type; struct Ast_Expr:Ast{ }; #define VALUE_FIELDS \ -Ast_Type *type; \ +Ast_Type *type; \ union{ \ bool bool_val; \ F64 f64_val; \ Intern_String intern_val; \ BigInt big_int_val;\ - Ast_Type *type_val; \ + Ast_Type *type_val; \ }; #define INLINE_VALUE_FIELDS union{Value value; struct{VALUE_FIELDS};} struct Value{VALUE_FIELDS}; diff --git a/ccodegen.cpp b/ccodegen.cpp index 26ddacb..f777756 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -90,11 +90,13 @@ gen_value(Value a){ const char *string = bigint_to_error_string(scratch, &a.big_int_val, 10); gen("%s", string); }break; - case TYPE_CHAR: - gen("\"%s\"", a.intern_val.str); - break; - case TYPE_STRING: case TYPE_UNTYPED_STRING: - gen("LIT(\"%s\")", a.intern_val.str); + CASE_STRING: + if(is_pointer(a.type)){ + assert(a.type == type_pointer_to_char); + gen("\"%s\"", a.intern_val.str); + } else{ + gen("LIT(\"%s\")", a.intern_val.str); + } break; CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break; CASE_FLOAT: gen("%f", a.f64_val); break; @@ -380,6 +382,7 @@ gen_ast(Ast *ast){ gen_value(node->value); }break; CASE_STRING:{ + assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1); gen("// const String %s = ", node->name.str); gen_value(node->value); }break; diff --git a/compiler.h b/compiler.h index 5fbc729..ebe140e 100644 --- a/compiler.h +++ b/compiler.h @@ -185,7 +185,7 @@ struct Parse_Ctx:Lexer{ }; global B32 emit_line_directives; - +function void init_type(); //----------------------------------------------------------------------------- // Constructors //----------------------------------------------------------------------------- @@ -227,4 +227,6 @@ parse_init(Parse_Ctx *ctx, Allocator *perm_allocator, Allocator *heap_allocator) lex_init(ctx->perm, ctx->heap, ctx); pctx = ctx; + + init_type(); } \ No newline at end of file diff --git a/main.cpp b/main.cpp index fab4267..5b98711 100644 --- a/main.cpp +++ b/main.cpp @@ -181,7 +181,7 @@ int main(int argument_count, char **arguments){ test_intern_table(); -#if 1 +#if 0 emit_line_directives = true; if(argument_count > 1){ Scratch scratch; @@ -203,7 +203,7 @@ int main(int argument_count, char **arguments){ system((const char *)run_program.str); } - #else +#else Scratch scratch; Array files = {scratch}; // files.add("lambdas.kl"_s); diff --git a/typechecking.cpp b/typechecking.cpp index 0b3a743..a92a6ce 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -373,6 +373,7 @@ insert_builtin_types_into_package(Ast_Package *p){ insert_type_into_package(p, "Bool"_s , type_bool); insert_type_into_package(p, "String"_s, type_string); insert_type_into_package(p, "char"_s, type_char); + insert_type_into_package(p, "int"_s, type_int); insert_type_into_package(p, "S8"_s, type_s8); insert_type_into_package(p, "S16"_s, type_s16); insert_type_into_package(p, "S32"_s, type_s32); @@ -394,7 +395,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); if(resolved.type != type_type) - compiler_error(ast->pos, "Expected [Type] got instead %s", type_names[resolved.type->kind]); + compiler_error(ast->pos, "Expected [Type] got instead %s", docname(resolved.type)); return resolved.type_val; } @@ -804,7 +805,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){ node->type = type_pointer(value.type_val); return operand_type(node->type); } - else{ compiler_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", type_names[value.type->kind]); return {}; } + else{ compiler_error(node->pos, "Dereferencing expression %s that is not a [Pointer] or [Type]", docname(value.type)); return {}; } } else if(node->op == TK_Dereference){ node->type = type_pointer(value.type); diff --git a/typechecking.h b/typechecking.h index 308c436..cba0f8c 100644 --- a/typechecking.h +++ b/typechecking.h @@ -230,3 +230,7 @@ type_complete(Ast_Type *type){ pctx->ordered_decls.add((Ast_Decl *)type->ast); } +function void +init_type(){ + type_pointer_to_char = type_pointer(type_char); +} \ No newline at end of file diff --git a/types.h b/types.h index 8b92661..ce5de6b 100644 --- a/types.h +++ b/types.h @@ -13,6 +13,8 @@ enum Ast_Type_Kind{ TYPE_S32, TYPE_S16, TYPE_S8 , + TYPE_INT, + TYPE_CHAR, TYPE_U64, TYPE_U32, TYPE_U16, @@ -22,7 +24,6 @@ enum Ast_Type_Kind{ TYPE_POINTER, TYPE_BOOL, // LAST_NUMERIC TYPE_STRING, - TYPE_CHAR, TYPE_VOID, TYPE_ARRAY, TYPE_LAMBDA, @@ -41,47 +42,14 @@ enum Ast_Type_Kind{ TYPE_LAST_NUMERIC = TYPE_BOOL, }; -#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64 +#define CASE_SINT case TYPE_S8:case TYPE_S16:case TYPE_S32:case TYPE_S64: case TYPE_CHAR: case TYPE_INT #define CASE_UINT case TYPE_U8:case TYPE_U16:case TYPE_U32:case TYPE_U64 #define CASE_INT case TYPE_UNTYPED_INT: CASE_SINT: CASE_UINT #define CASE_BOOL case TYPE_UNTYPED_BOOL: case TYPE_BOOL #define CASE_FLOAT case TYPE_UNTYPED_FLOAT: case TYPE_F32: case TYPE_F64 -#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_CHAR +#define CASE_STRING case TYPE_UNTYPED_STRING: case TYPE_STRING: case TYPE_POINTER #define CASE_UNTYPED case TYPE_UNTYPED_INT: case TYPE_UNTYPED_BOOL: case TYPE_UNTYPED_FLOAT: case TYPE_UNTYPED_STRING -const char *type_names[] = { - "[Invalid Ast_Type]", - "[Completing]", - "[Incomplete]", - - "[Untyped_Bool]", - "[Untyped_Int]", - "[Untyped_Float]", - "[Untyped_String]", - - "[S64]", - "[S32]", - "[S16]", - "[S8]", - "[U64]", - "[U32]", - "[U16]", - "[U8]", - "[Float32]", - "[Float64]", - "[Bool]", - "[String]", - "[char]", - "[void]", - "[Pointer]", - "[Array]", - "[Lambda]", - "[Struct]", - "[Union]", - "[Enum]", - "[Type]", -}; - struct Ast; struct Ast_Type; struct Ast_Resolved_Member{ @@ -96,6 +64,7 @@ struct Ast_Type{ Ast_Type_Kind kind; SizeU size; SizeU align; + S32 is_unsigned; Ast *ast; union{ @@ -142,6 +111,7 @@ docname(Ast_Type *type){ case TYPE_BOOL: return "[Bool]"; case TYPE_STRING: return "[String]"; case TYPE_CHAR: return "[char]"; + case TYPE_INT: return "[int]"; case TYPE_VOID: return "[void]"; case TYPE_POINTER: return "[Pointer]"; case TYPE_ARRAY: return "[Array]"; @@ -184,7 +154,6 @@ const SizeU pointer_size = sizeof(SizeU); const SizeU pointer_align = __alignof(SizeU); global Ast_Type type__void = {TYPE_VOID}; global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; -global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)}; global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; global Ast_Type type__type = {TYPE_TYPE}; @@ -196,17 +165,22 @@ global Ast_Type type__s16 = {TYPE_S16, sizeof(S16), __alignof(S16)}; global Ast_Type type__s32 = {TYPE_S32, sizeof(S32), __alignof(S32)}; global Ast_Type type__s64 = {TYPE_S64, sizeof(S64), __alignof(S64)}; -global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8)}; -global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16)}; -global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32)}; -global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64)}; +global Ast_Type type__u8 = {TYPE_U8, sizeof(U8), __alignof(U8), true}; +global Ast_Type type__u16 = {TYPE_U16, sizeof(U16), __alignof(U16), true}; +global Ast_Type type__u32 = {TYPE_U32, sizeof(U32), __alignof(U32), true}; +global Ast_Type type__u64 = {TYPE_U64, sizeof(U64), __alignof(U64), true}; global Ast_Type type__untyped_bool = {TYPE_UNTYPED_BOOL, sizeof(bool), __alignof(bool)}; global Ast_Type type__untyped_int = {TYPE_UNTYPED_INT, sizeof(S64), __alignof(S64)}; global Ast_Type type__untyped_string = {TYPE_UNTYPED_STRING, sizeof(String), __alignof(String)}; global Ast_Type type__untyped_float = {TYPE_UNTYPED_FLOAT, sizeof(double), __alignof(double)}; +global Ast_Type type__char = {TYPE_CHAR, sizeof(char), __alignof(char)}; +global Ast_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)}; global Ast_Type *type_char = &type__char; +global Ast_Type *type_int = &type__int; +global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime + global Ast_Type *type_type = &type__type; global Ast_Type *type_void = &type__void; global Ast_Type *type_string = &type__string; @@ -238,12 +212,12 @@ force_inline B32 is_lambda(Ast_Type *a){return a->kind == TYPE_LAMBDA;} force_inline B32 is_array(Ast_Type *a){return a->kind == TYPE_ARRAY;} force_inline B32 is_enum(Ast_Type *a){return a->kind == TYPE_ENUM;} force_inline B32 is_pointer(Ast_Type *a){return a->kind == TYPE_POINTER;} -force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a->kind == TYPE_CHAR;} +force_inline B32 is_string(Ast_Type *a){return a->kind == TYPE_STRING || a->kind == TYPE_UNTYPED_STRING || a == type_pointer_to_char;} force_inline B32 is_untyped_int(Ast_Type *a){return a->kind == TYPE_UNTYPED_INT;} force_inline B32 is_typed_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8);} force_inline B32 is_int(Ast_Type *a){return (a->kind >= TYPE_S64 && a->kind <= TYPE_U8) || a->kind == TYPE_UNTYPED_INT;} -force_inline B32 is_signed_int(Ast_Type *a){return a->kind >= TYPE_S64 && a->kind <= TYPE_S8;} -force_inline B32 is_unsigned_int(Ast_Type *a){return a->kind >= TYPE_U64 && a->kind <= TYPE_U8;} +force_inline B32 is_signed_int(Ast_Type *a){return !a->is_unsigned;} +force_inline B32 is_unsigned_int(Ast_Type *a){return a->is_unsigned;} force_inline B32 is_float(Ast_Type *a){return a->kind == TYPE_F32 || a->kind == TYPE_F64 || a->kind == TYPE_UNTYPED_FLOAT;} force_inline B32 is_f32(Ast_Type *a){return a->kind == TYPE_F32;} force_inline B32 is_f64(Ast_Type *a){return a->kind == TYPE_F64;} @@ -256,22 +230,3 @@ is_numeric(Ast_Type *type){ return (type->kind >= TYPE_UNTYPED_FIRST_NUMERIC && type->kind <= TYPE_UNTYPED_LAST_NUMERIC) || (type->kind >= TYPE_FIRST_NUMERIC && type->kind <= TYPE_LAST_NUMERIC); } - -function U64 -int_type_max(Ast_Type *type){ - switch(type->kind){ - case TYPE_BOOL: return 1; - case TYPE_UNTYPED_BOOL: return 1; - case TYPE_UNTYPED_INT: return S64MAX; - case TYPE_S64: return S64MAX; - case TYPE_S32: return S32MAX; - case TYPE_S16: return S16MAX; - case TYPE_S8: return S8MAX; - case TYPE_U64: return U64MAX; - case TYPE_U32: return U32MAX; - case TYPE_U16: return U16MAX; - case TYPE_U8: return U8MAX; - invalid_default_case; - } - invalid_return; -}