Add TypeOf operator

This commit is contained in:
Krzosa Karol
2022-10-11 11:13:07 +02:00
parent 4004b8b8d3
commit e37bf8b1bc
8 changed files with 61 additions and 38 deletions

View File

@@ -24,6 +24,7 @@ enum Ast_Kind: U32{
AST_SIZE_OF, AST_SIZE_OF,
AST_LENGTH_OF, AST_LENGTH_OF,
AST_ALIGN_OF, AST_ALIGN_OF,
AST_TYPE_OF,
AST_SWITCH, AST_SWITCH,
AST_SWITCH_CASE, AST_SWITCH_CASE,

View File

@@ -38,6 +38,7 @@ keyword_for = l->intern("for"_s);
keyword_enum = l->intern("enum"_s); keyword_enum = l->intern("enum"_s);
l->interns.first_keyword = keyword_struct.str; l->interns.first_keyword = keyword_struct.str;
l->interns.last_keyword = keyword_enum.str; l->interns.last_keyword = keyword_enum.str;
intern_typeof = l->intern("TypeOf"_s);
intern_sizeof = l->intern("SizeOf"_s); intern_sizeof = l->intern("SizeOf"_s);
intern_len = l->intern("Len"_s); intern_len = l->intern("Len"_s);
intern_alignof = l->intern("AlignOf"_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)){ if(is_flag_set(compile_flags, COMPILE_AND_RUN)){
String testing = compile_flags&COMPILE_TESTING ? "testing"_s : ""_s; String testing = compile_flags&COMPILE_TESTING ? "testing"_s : ""_s;
#if OS_WINDOWS #if OS_WINDOWS
String sys = string_fmt(scratch, "a.exe %Q", testing); String sys = string_fmt(scratch, "a.exe %Q", testing);
#else #else
String sys = string_fmt(scratch, "./a.out %Q", testing); String sys = string_fmt(scratch, "./a.out %Q", testing);
#endif #endif
int result = system((char *)sys.str); int result = system((char *)sys.str);
assert(result != -1); assert(result != -1);
if(result == 0){ if(result == 0){

View File

@@ -32,6 +32,7 @@ Intern_String keyword_pass;
Intern_String keyword_else; Intern_String keyword_else;
Intern_String keyword_for; Intern_String keyword_for;
Intern_String keyword_enum; Intern_String keyword_enum;
Intern_String intern_typeof;
Intern_String intern_sizeof; Intern_String intern_sizeof;
Intern_String intern_len; Intern_String intern_len;
Intern_String intern_alignof; Intern_String intern_alignof;

View File

@@ -5,15 +5,13 @@ Current:
- [ ] String declaration in Language.core - [ ] String declaration in Language.core
- [ ] Way to import and force evaluate #import_lazy #import ? - [ ] Way to import and force evaluate #import_lazy #import ?
- [ ] Typeof operator - [ ] Typeof operator
- [ ] Imports are leaking names ! Multimedia leaks windows stuff
- [ ] Test and bulletproof any, slices - [ ] Test and bulletproof any, slices
Memory: Memory:
- [ ] Redesign Type map to use List and reduce wasting space - [ ] 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! - [ ] 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 In the future

View File

@@ -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); Operand name = resolve_expr(expr, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
node->kind = AST_SIZE_OF; 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; Ast_Type *type = name.type == type_type ? name.type_val : name.type;
type_complete(type); type_complete(type);
if(type->size == 0){ 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"); 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); rewrite_into_const(node, Ast_Builtin, v);
return operand_const_rvalue(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 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 { else {
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
if(name.type->kind != TYPE_LAMBDA){ if(name.type->kind != TYPE_LAMBDA){

View File

@@ -53,6 +53,24 @@ main :: (): int
// To do this we need a cast // To do this we need a cast
combining_types := this_is_s64_by_default->F32 + this_is_f32_by_default 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(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(string_val[0] == 'S')
Assert(cstring_val[0] == 'C') Assert(cstring_val[0] == 'C')
@@ -62,15 +80,6 @@ main :: (): int
Assert(this_is_f32_by_default == 15.1255) Assert(this_is_f32_by_default == 15.1255)
Assert(combining_types == 15.1255 + 20) 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.a == 1)
Assert(data1.b == 0) Assert(data1.b == 0)
Assert(data1.c == 0) Assert(data1.c == 0)
@@ -80,6 +89,11 @@ main :: (): int
Assert(data2.c == 0) Assert(data2.c == 0)
Assert(data2.d == 0) Assert(data2.d == 0)
Assert(size0 == size1)
Assert(align0 == align1)
Assert(type0 == type1)
Assert(TypeOf(data2) == Data)
return 0 return 0
Data :: struct Data :: struct

View File

@@ -116,6 +116,7 @@ keywords = [
] ]
interns = [ interns = [
"TypeOf",
"SizeOf", "SizeOf",
"Len", "Len",
"AlignOf", "AlignOf",

View File

@@ -276,7 +276,7 @@ mapping = [
] ]
print("MapVKToKey :: (vk: U32): Key") print("MapVKToKey :: (vk: WPARAM): Key")
el = "" el = ""
for val,map in mapping: for val,map in mapping:
print(f" {el}if vk == {map} ;; return Key.{val}") print(f" {el}if vk == {map} ;; return Key.{val}")