diff --git a/core_ast.cpp b/core_ast.cpp index 6776c5a..eb63afe 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -24,6 +24,7 @@ enum Ast_Kind: U32{ AST_SIZE_OF, AST_LENGTH_OF, AST_ALIGN_OF, + AST_TYPE_OF, AST_SWITCH, AST_SWITCH_CASE, diff --git a/core_compiler.cpp b/core_compiler.cpp index 863735c..b667935 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -38,6 +38,7 @@ keyword_for = l->intern("for"_s); keyword_enum = l->intern("enum"_s); l->interns.first_keyword = keyword_struct.str; l->interns.last_keyword = keyword_enum.str; +intern_typeof = l->intern("TypeOf"_s); intern_sizeof = l->intern("SizeOf"_s); intern_len = l->intern("Len"_s); intern_alignof = l->intern("AlignOf"_s); @@ -340,11 +341,11 @@ compile_file(String filename, U32 compile_flags = COMPILE_NULL){ if(is_flag_set(compile_flags, COMPILE_AND_RUN)){ String testing = compile_flags&COMPILE_TESTING ? "testing"_s : ""_s; - #if OS_WINDOWS +#if OS_WINDOWS String sys = string_fmt(scratch, "a.exe %Q", testing); - #else +#else String sys = string_fmt(scratch, "./a.out %Q", testing); - #endif +#endif int result = system((char *)sys.str); assert(result != -1); if(result == 0){ diff --git a/core_globals.cpp b/core_globals.cpp index 7b97f25..3e9adb5 100644 --- a/core_globals.cpp +++ b/core_globals.cpp @@ -32,6 +32,7 @@ Intern_String keyword_pass; Intern_String keyword_else; Intern_String keyword_for; Intern_String keyword_enum; +Intern_String intern_typeof; Intern_String intern_sizeof; Intern_String intern_len; Intern_String intern_alignof; diff --git a/core_main.cpp b/core_main.cpp index 3dbacd5..c842ada 100644 --- a/core_main.cpp +++ b/core_main.cpp @@ -5,15 +5,13 @@ Current: - [ ] String declaration in Language.core - [ ] Way to import and force evaluate #import_lazy #import ? - [ ] Typeof operator - -- [ ] Imports are leaking names ! Multimedia leaks windows stuff - [ ] Test and bulletproof any, slices Memory: - [ ] Redesign Type map to use List and reduce wasting space - [ ] Redesign lexing to minimize memory usage, we got rid of heap but in a naive way! -- [ ] Probably need to move all the global data into the context if we want to use this as library +- [ ] Probably need to move all the global data into the context if we want to use this as library or not? In the future diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 1b91d48..0713ca2 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1425,17 +1425,43 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); node->kind = AST_SIZE_OF; - if(!name.is_const){ - compiler_error(node->pos, "SizeOf requires a constant value"); + + Ast_Type *type = name.type == type_type ? name.type_val : name.type; + type_complete(type); + + if(type->size == 0){ + compiler_error(node->pos, "Internal compiler error: calling SizeOf but the resulting size of type is obviously invalid suggesting that type was not completed properly"); } + Value v = value_int(type->size); + rewrite_into_const(node, Ast_Builtin, v); + return operand_const_rvalue(v); + } + + else if(expr_atom_is_equal_intern(node->name, intern_typeof)){ + Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); + + Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); + node->kind = AST_TYPE_OF; + Ast_Type *type = name.type == type_type ? name.type_val : name.type; + + Operand result = operand_type(type); + rewrite_into_const(node, Ast_Builtin, result.value); + return result; + } + + else if(expr_atom_is_equal_intern(node->name, intern_alignof)){ + Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); + Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); + node->kind = AST_ALIGN_OF; + Ast_Type *type = name.type == type_type ? name.type_val : name.type; type_complete(type); if(type->size == 0){ compiler_error(node->pos, "Internal compiler error: calling SizeOf but the resulting size of type is obviously invalid suggesting that type was not completed properly"); } - Value v = value_int(type->size); + Value v = value_int(type->align); rewrite_into_const(node, Ast_Builtin, v); return operand_const_rvalue(v); } @@ -1462,25 +1488,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str else compiler_error(node->pos, "Can't get length of type %Q", typestring(name.type)); } - else if(expr_atom_is_equal_intern(node->name, intern_alignof)){ - Ast_Expr *expr = unpack_ast_call_expr_for_builtin(node); - Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); - node->kind = AST_ALIGN_OF; - if(!name.is_const) { - compiler_error(node->pos, "AlignOf requires a constant value"); - } - - Ast_Type *type = name.type == type_type ? name.type_val : name.type; - type_complete(type); - if(type->size == 0){ - compiler_error(node->pos, "Internal compiler error: calling SizeOf but the resulting size of type is obviously invalid suggesting that type was not completed properly"); - } - - Value v = value_int(type->align); - rewrite_into_const(node, Ast_Builtin, v); - return operand_const_rvalue(v); - } - else { Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); if(name.type->kind != TYPE_LAMBDA){ diff --git a/examples/language_basics.core b/examples/language_basics.core index 19ef7df..ad72646 100644 --- a/examples/language_basics.core +++ b/examples/language_basics.core @@ -53,6 +53,24 @@ main :: (): int // To do this we need a cast combining_types := this_is_s64_by_default->F32 + this_is_f32_by_default + // Compound statements + // Struct is at the bottom of the file! + data1 := Data{ + a = 1, + d = 2 + } + data2: Data = { + a = 4, + b = 2, + } + + size0 := SizeOf(Data) + size1 := SizeOf(data1) + align0 := AlignOf(Data) + align1 := AlignOf(data1) + type0 := TypeOf(Data) + type1 := TypeOf(data1) + Assert(s64val == 0 && s32val == 0 && s16val == 0 && s8val == 0 && intval == 0 && u64val == 0 && u32val == 0 && u16val == 0 && u8val == 0 && f64val == 0 && f32val == 0) Assert(string_val[0] == 'S') Assert(cstring_val[0] == 'C') @@ -62,15 +80,6 @@ main :: (): int Assert(this_is_f32_by_default == 15.1255) Assert(combining_types == 15.1255 + 20) - // Compound statements - data1 := Data{ - a = 1, - d = 2 - } - data2: Data = { - a = 4, - b = 2, - } Assert(data1.a == 1) Assert(data1.b == 0) Assert(data1.c == 0) @@ -80,6 +89,11 @@ main :: (): int Assert(data2.c == 0) Assert(data2.d == 0) + Assert(size0 == size1) + Assert(align0 == align1) + Assert(type0 == type1) + Assert(TypeOf(data2) == Data) + return 0 Data :: struct diff --git a/meta.py b/meta.py index 98a50ec..43dccd3 100644 --- a/meta.py +++ b/meta.py @@ -116,6 +116,7 @@ keywords = [ ] interns = [ + "TypeOf", "SizeOf", "Len", "AlignOf", diff --git a/modules/win32_multimedia.core b/modules/win32_multimedia.core index 1b4d2e7..903e395 100644 --- a/modules/win32_multimedia.core +++ b/modules/win32_multimedia.core @@ -276,7 +276,7 @@ mapping = [ ] -print("MapVKToKey :: (vk: U32): Key") +print("MapVKToKey :: (vk: WPARAM): Key") el = "" for val,map in mapping: print(f" {el}if vk == {map} ;; return Key.{val}")