Add TypeOf operator
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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
|
||||
|
||||
1
meta.py
1
meta.py
@@ -116,6 +116,7 @@ keywords = [
|
||||
]
|
||||
|
||||
interns = [
|
||||
"TypeOf",
|
||||
"SizeOf",
|
||||
"Len",
|
||||
"AlignOf",
|
||||
|
||||
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user