diff --git a/ccodegen.cpp b/ccodegen.cpp index a4c0740..65d0837 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -255,6 +255,13 @@ gen_lambda(Intern_String name, Ast_Lambda *lambda, B32 generate_block = true){ function bool gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){ + if(is_any(type_of_var)){ + gen("(Any){&"); + gen_expr(ast); + gen(", %d}", ast->resolved_type->type_id); + return true; + } + switch(ast->kind){ CASE(IDENT, Atom){ if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE) @@ -373,7 +380,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){ gen_expr(node->name); gen("("); For(node->exprs){ - gen_expr(it->item); + gen_expr(it->item, it->resolved_type); if(!node->exprs.is_last(&it)) gen(", "); } gen(")"); @@ -700,22 +707,23 @@ insert_builtin_into_scope(Ast_Scope *p, String name, Ast_Type *type){ function void insert_builtin_types_into_scope(Ast_Scope *p){ + insert_builtin_into_scope(p, "S64"_s, type_s64); + insert_builtin_into_scope(p, "S32"_s, type_s32); + insert_builtin_into_scope(p, "S16"_s, type_s16); + insert_builtin_into_scope(p, "S8"_s, type_s8); + insert_builtin_into_scope(p, "int"_s, type_int); + insert_builtin_into_scope(p, "char"_s, type_char); + insert_builtin_into_scope(p, "U64"_s, type_u64); + insert_builtin_into_scope(p, "U32"_s, type_u32); + insert_builtin_into_scope(p, "U16"_s, type_u16); + insert_builtin_into_scope(p, "U8"_s, type_u8); + insert_builtin_into_scope(p, "F64"_s, type_f64); + insert_builtin_into_scope(p, "F32"_s, type_f32); + insert_builtin_into_scope(p, "void"_s , type_void); insert_builtin_into_scope(p, "Bool"_s , type_bool); insert_builtin_into_scope(p, "String"_s, type_string); - insert_builtin_into_scope(p, "char"_s, type_char); - insert_builtin_into_scope(p, "int"_s, type_int); - insert_builtin_into_scope(p, "S8"_s, type_s8); - insert_builtin_into_scope(p, "S16"_s, type_s16); - insert_builtin_into_scope(p, "S32"_s, type_s32); - insert_builtin_into_scope(p, "S64"_s, type_s64); - insert_builtin_into_scope(p, "U8"_s, type_u8); - insert_builtin_into_scope(p, "U16"_s, type_u16); - insert_builtin_into_scope(p, "U32"_s, type_u32); - insert_builtin_into_scope(p, "U64"_s, type_u64); - insert_builtin_into_scope(p, "F32"_s, type_f32); - insert_builtin_into_scope(p, "F64"_s, type_f64); - insert_builtin_into_scope(p, "Any"_s, type_any); + // insert_builtin_into_scope(p, "Any"_s, type_any); insert_builtin_into_scope(p, "Type"_s, type_type); } diff --git a/main.cpp b/main.cpp index 78c3e69..721ecbc 100644 --- a/main.cpp +++ b/main.cpp @@ -41,10 +41,9 @@ want to export all the symbols, we can namespace them optionally. ------------------------------------------------------------------------------- @todo +[ ] - Probably need to give Ast_Expr a Value field, then I can express Type nicely [ ] - I would love for String, slice, Any etc. to have their struct declarations in source files, I also would want for stuff like string.str to work without weird special cases [ ] - Implementing type Any -[ ] - Runtime TypeInfo -[ ] - Proper type Type support [ ] - #test construct that would gather all tests and run them on start of program or something [ ] - Foreign import that would link library @@ -54,7 +53,6 @@ want to export all the symbols, we can namespace them optionally. [ ] - Mixing loads and imports leads to code duplication, is that what we want??? [ ] - Fix field access, cant cast, cant index [ ] - Add parent_scope to Ast_Type, Add name to Ast_Type? -[ ] - Switch [ ] - Some way to take slice of data [ ] - Optional function renaming in codegen [ ] - Using in structs to embed members, then casting offsets to that embedded member @@ -83,6 +81,9 @@ want to export all the symbols, we can namespace them optionally. [ ] - Polymorphism - create declaration of a polymorphic thing, when it's called just copy it, replace types and typecheck normally, when someone calls again you just search for the instantiation again @donzo +[x] - Runtime TypeInfo +[x] - Proper type Type support +[x] - Switch [x] - Type aliases :: should probably be strictly typed, but assigning constant values should work [x] - Array of inferred size [x] - Casting pointers to and from void should be implicit @@ -188,7 +189,13 @@ int main(int argument_count, char **arguments){ pctx->language_base_module = module; parse_all_modules(); resolve_everything_in_module(module); + + // @note: language stuff needs to be declared before type_info data + // so we mark where it ends pctx->base_language_ordered_decl_len = pctx->ordered_decls.len; + Ast_Decl *any_decl = search_for_decl(module, pctx->intern("Any"_s)); + assert(any_decl->type == type_type); + type_any = any_decl->type_val; } Ast_Module *module = add_module(0, pctx->intern(program_name)); diff --git a/programs/language.kl b/programs/language.kl index 89d02fb..6ddef1f 100644 --- a/programs/language.kl +++ b/programs/language.kl @@ -8,15 +8,14 @@ Slice :: struct data: *void len : S64 -Any :: struct - data: *void - type: Type_ID - */ +Any :: struct + data: *void + type: Type + Type_Info_Kind :: enum - NONE - S64 :: 7 // FIRST_NUMERIC + S64 // FIRST_NUMERIC S32 S16 S8 @@ -40,7 +39,6 @@ Type_Info_Kind :: enum TYPE SLICE TUPLE - ANY Type_Info_Struct_Member :: struct name: String diff --git a/programs/main.kl b/programs/main.kl index be6713d..6bb4641 100644 --- a/programs/main.kl +++ b/programs/main.kl @@ -41,24 +41,50 @@ create_bitmap :: (size: Vec2I, bottom_up: Bool = true): Windows_Bitmap result.hdc = CreateCompatibleDC(hdc) return result -print :: (type: Type) - type_info := get_type_info(type) +_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char +print_float :: (value: F64) + buff: [100]char + _gcvt(value, 10, &buff[0]) + OutputDebugStringA(&buff[0]) + +print_type :: (t: Type) + type_info := get_type_info(t) if !type_info return switch type_info.kind - S64, S32, S16, S8, int + Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT OutputDebugStringA("Integer") - U64, U32, U16, U8 + Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8 OutputDebugStringA("Unsigned") + Type_Info_Kind.F64, Type_Info_Kind.F32 + OutputDebugStringA("Float") Type_Info_Kind.POINTER OutputDebugStringA("*") - print(type_info.base_type) - Type_Info_Kind.SLICE - OutputDebugStringA("[]") - print(type_info.base_type) + print_type(type_info.base_type) default;; OutputDebugStringA("Unknown") +print :: (a: Any) + type_info := get_type_info(a.type) + if !type_info + return + + print_type(a.type) + OutputDebugStringA(" - ") + // @todo check for types here + switch type_info.kind + Type_Info_Kind.S64, Type_Info_Kind.S32, Type_Info_Kind.S16, Type_Info_Kind.S8, Type_Info_Kind.INT + OutputDebugStringA("Integer") + Type_Info_Kind.U64, Type_Info_Kind.U32, Type_Info_Kind.U16, Type_Info_Kind.U8 + OutputDebugStringA("Unsigned") + Type_Info_Kind.F64 + data := a.data->*F64 + print_float(*data) + Type_Info_Kind.POINTER + OutputDebugStringA("Pointer") + default;; OutputDebugStringA("Unknown") + + app_is_running := true window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT if msg == WM_DESTROY @@ -67,19 +93,15 @@ window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRE return 0 else;; return DefWindowProcW(hwnd, msg, wparam, lparam) -_gcvt :: #foreign (value: F64, digits: int, buffer: *char): *char -print_float :: (value: F64) - buff: [100]char - _gcvt(value, 10, &buff[0]) - OutputDebugStringA("\n") - OutputDebugStringA(&buff[0]) - WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nShowCmd: int): int if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR good_scheduling = true - print([]**S64) char_info := get_type_info(char) + val := 4232.23 + thing: Any = val + print(val) + assert(char_info.kind == Type_Info_Kind.CHAR) #assert(int == int) #assert(int != char) diff --git a/typechecking.cpp b/typechecking.cpp index aff6d6c..2697550 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -362,6 +362,9 @@ make_sure_value_is_compatible_with_type(Token *pos, Operand *expr, Ast_Type *typ assert(type); expr->type = type; } + else if(is_any(type)){ + expr->type = type; + } else if(is_void_pointer(type) && is_pointer(expr->type)){ expr->type = type; } @@ -788,8 +791,9 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type){ m->visited = true; // @copy_paste - if(m->type == type_type) + if(m->type == type_type && m->type_val){ item_type = m->type_val; + } else item_type = m->type; default_counter+=1; diff --git a/types.h b/types.h index 38684d1..d3107c1 100644 --- a/types.h +++ b/types.h @@ -3,13 +3,7 @@ //----------------------------------------------------------------------------- enum Ast_Type_Kind{ TYPE_NONE, - TYPE_COMPLETING, - TYPE_INCOMPLETE, - TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC - TYPE_UNTYPED_INT, - TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC - TYPE_UNTYPED_STRING, - TYPE_S64 = 7, // FIRST_NUMERIC + TYPE_S64, // FIRST_NUMERIC TYPE_S32, TYPE_S16, TYPE_S8 , @@ -33,7 +27,13 @@ enum Ast_Type_Kind{ TYPE_TYPE, TYPE_SLICE, TYPE_TUPLE, - TYPE_ANY, + + TYPE_COMPLETING, + TYPE_INCOMPLETE, + TYPE_UNTYPED_BOOL, // FIRST_TYPED_NUMERIC, FIRST_NUMERIC + TYPE_UNTYPED_INT, + TYPE_UNTYPED_FLOAT, // LAST_TYPED_NUMERIC + TYPE_UNTYPED_STRING, TYPE_UNTYPED_FIRST = TYPE_UNTYPED_BOOL, TYPE_UNTYPED_LAST = TYPE_UNTYPED_STRING, @@ -122,7 +122,6 @@ name(Ast_Type *type){ case TYPE_U16: return "U16"; case TYPE_U32: return "U32"; case TYPE_U64: return "U64"; - case TYPE_ANY: return "Any"; case TYPE_TUPLE: return "Tuple"; case TYPE_TYPE: return "Type"; invalid_default_case; @@ -139,7 +138,6 @@ global Ast_Type type__void = {TYPE_VOID}; global Ast_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; global Ast_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; global Ast_Type type__type = {TYPE_TYPE}; -global Ast_Type type__any = {TYPE_ANY}; global Ast_Type type__f32 = {TYPE_F32, sizeof(F32), __alignof(F32)}; global Ast_Type type__f64 = {TYPE_F64, sizeof(F64), __alignof(F64)}; @@ -163,11 +161,12 @@ 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_void = &type__void; -global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime -global Ast_Type *type_any = &type__any; +global Ast_Type *type_pointer_to_char; // Needs to be inited at runtime +global Ast_Type *type_pointer_to_void; // Needs to be inited at runtime +global Ast_Type *type_any; // Needs to be inited at runtime + global Ast_Type *type_type = &type__type; global Ast_Type *type_string = &type__string; global Ast_Type *type_bool = &type__bool; @@ -193,7 +192,7 @@ global Ast_Type *untyped_float = &type__untyped_float; //----------------------------------------------------------------------------- // Type constructors and utillities //----------------------------------------------------------------------------- -force_inline B32 is_any(Ast_Type *a){return a->kind == TYPE_ANY;} +force_inline B32 is_any(Ast_Type *a){return a == type_any;} force_inline B32 is_struct(Ast_Type *a){return a->kind == TYPE_STRUCT;} 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;}