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