Lot's of work on Any and Type

This commit is contained in:
Krzosa Karol
2022-06-19 15:28:18 +02:00
parent 014ef07b9f
commit 79edfae55b
7 changed files with 48 additions and 43 deletions

View File

@@ -113,8 +113,7 @@ struct Ast_Var_Unpack: Ast_Expr{
struct Ast_Unary: Ast_Expr{
Token_Kind op;
Ast_Expr *expr;
Ast_Type *resolved_type_val;
U64 padding[1]; // For folding constants into atoms
U64 padding[2]; // For folding constants into atoms
};
struct Ast_Index: Ast_Expr{
@@ -175,6 +174,7 @@ struct Ast_Lambda : Ast_Expr {
struct Ast_Array: Ast_Expr{
Ast_Expr *base;
Ast_Expr *expr;
U64 padding[2];
};
struct Ast_Switch_Case: Ast{

View File

@@ -178,7 +178,7 @@ gen_value(Value a){
assert(a.type == type_pointer_to_char);
gen("\"%Q\"", a.intern_val);
} else{
gen("LIT(\"%Q\")", a.intern_val);
gen("(String){(U8 *)\"%Q\", %d}", a.intern_val, a.intern_val.len);
}
break;
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); break;
@@ -255,13 +255,6 @@ 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)
@@ -344,19 +337,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
CASE(UNARY, Unary){
gen("(");
if(node->op != TK_PostIncrement && node->op != TK_PostDecrement){
if(node->op == TK_Pointer){
// Normal types are usually generated with gen_simple_decl
// if they are part of the expression they are a value
// which means we need to shortcircuit here with proper type_id
Ast_Type *base = get_type_base(node->resolved_type);
if(base == type_type){
gen("%d)", node->resolved_type_val->type_id);
return true;
}
}
gen("%s", name(node->op));
}
if(node->op != TK_PostIncrement && node->op != TK_PostDecrement) gen("%s", name(node->op));
gen_expr(node->expr);
if(node->op == TK_PostIncrement || node->op == TK_PostDecrement) gen("%s", name(node->op));
gen(")");
@@ -398,7 +379,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
gen(".%Q = ", it->resolved_name);
else if(is_array(node->resolved_type))
gen("[%d] = ", (int)it->resolved_index);
gen_expr(it->item);
gen_expr(it->item, it->resolved_type);
if(!node->exprs.is_last(&it)) gen(", ");
}
gen("}");
@@ -832,7 +813,6 @@ typedef struct String{
U8 *str;
S64 len;
}String;
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
#define assert(x) do{if(!(x))__debugbreak();}while(0)
#define assert_msg(x,...) assert(x)
@@ -919,7 +899,7 @@ typedef struct String{
gen(".struct_member_count = %d, ", it->agg.members.len);
gen(".struct_members = (Type_Info_Struct_Member[]){");
For_Named(it->agg.members, m){
gen("{.name = LIT(\"%Q\"), .type = %d, .offset = %d}, ", m.name, m.type->type_id, m.offset);
gen("{.name = (String){(U8 *)\"%Q\", %d}, .type = %d, .offset = %d}, ", m.name, m.name.len, m.type->type_id, m.offset);
}
gen("}");

View File

@@ -43,7 +43,6 @@ 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
[ ] - #test construct that would gather all tests and run them on start of program or something
[ ] - Foreign import that would link library
@@ -81,6 +80,7 @@ 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] - Implementing type Any
[x] - Runtime TypeInfo
[x] - Proper type Type support
[x] - Switch

View File

@@ -10,6 +10,11 @@ Slice :: struct
*/
Dynamic_Array :: struct
data: *void
len : S64
cap : S64
Any :: struct
data: *void
type: Type

View File

@@ -84,6 +84,10 @@ print :: (a: Any)
OutputDebugStringA("Pointer")
default;; OutputDebugStringA("Unknown")
// print_array :: (a: []Any)
// for i := 0, i < length_of(a), i+=1
// print(a[i])
app_is_running := true
window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT
@@ -97,10 +101,12 @@ WinMain :: (hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: LPSTR, nS
if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR
good_scheduling = true
some_type: Type = Vec2
char_info := get_type_info(char)
val := 4232.23
thing: Any = val
print(val)
// print_array({125.23, 32})
assert(char_info.kind == Type_Info_Kind.CHAR)
#assert(int == int)

View File

@@ -459,7 +459,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context =
return 0;
Scratch scratch;
Operand resolved = resolve_expr(ast, flags, compound_context);
Operand resolved = resolve_expr(ast, flags | RESOLVE_TYPESPEC, compound_context);
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
type_complete(resolved.type_val);
if(resolved.type != type_type)
@@ -723,7 +723,7 @@ resolve_compound_array(Ast_Call *node, Ast_Type *type){
Ast_Type *item_type = type->arr.base;
S64 size = type->arr.size;
if(node->exprs.len > size)
if(is_array(type) && node->exprs.len > size)
compiler_error(node->pos, "Too many items in compound expression, expected: %lld got: %lld", size, node->exprs.len);
S64 default_counter = 0;
@@ -886,15 +886,18 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
Operand type = resolve_expr(node->base, AST_CANT_BE_NULL);
Operand expr = require_const_int(node->expr, AST_CAN_BE_NULL);
if(type.type != type_type) compiler_error(node->pos, "Prefix array operator is only allowed on types");
type_complete(type.type_val);
if(!is_flag_set(flags, RESOLVE_TYPESPEC)){
rewrite_into_const(node, Ast_Array, type.value);
}
if(node->expr){
node->resolved_type = type_array(type.type_val, bigint_as_unsigned(&expr.big_int_val));
} else{
node->resolved_type = type_slice(type.type_val, node);
}
return operand_type(node->resolved_type);
BREAK();
}
@@ -919,7 +922,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
if(is_string(left.type)){
return operand_lvalue(type_u8);
}
else if(!is_array(left.type) && !is_pointer(left.type)){
else if(!is_array(left.type) && !is_pointer(left.type) && !is_slice(left.type)){
compiler_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %Q instead", typestring(left.type));
}
@@ -971,16 +974,19 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(UNARY, Unary){
Operand value = resolve_expr(node->expr, AST_CANT_BE_NULL);
Operand value = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
if(node->op == TK_Pointer){
if(value.type->kind == TYPE_POINTER){
node->resolved_type = value.type->base;
return operand_lvalue(node->resolved_type);
}
else if(value.type->kind == TYPE_TYPE){
node->resolved_type = type_type;
node->resolved_type_val = type_pointer(value.type_val);
return operand_type(node->resolved_type_val);
if(!is_flag_set(flags, RESOLVE_TYPESPEC)){
rewrite_into_const(node, Ast_Array, value.value);
}
node->resolved_type = type_pointer(value.type_val);
return operand_type(node->resolved_type);
}
else{ compiler_error(node->pos, "Dereferencing expression %Q that is not a [Pointer] or [Type]", typestring(value.type)); return {}; }
}
@@ -1001,7 +1007,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(COMPOUND, Call){
Operand op = resolve_expr(node->typespec, AST_CAN_BE_NULL);
Operand op = resolve_expr(node->typespec, inherit_flag(flags, AST_CAN_BE_NULL));
Ast_Type *type = op.type;
if(type){
@@ -1016,7 +1022,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
type_complete(type);
node->resolved_type = type;
if(is_array(type)){
if(is_array(type) || is_slice(type)){
resolve_compound_array(node, type);
}
else if(is_struct(type)){
@@ -1029,7 +1035,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(ALIGN_OF, Builtin){
Operand name = resolve_expr(node->expr, AST_CANT_BE_NULL);
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
if(!name.is_const) compiler_error(node->pos, "align_of requires a constant value");
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
Value v = value_int(type->align);
@@ -1039,7 +1045,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(SIZE_OF, Builtin){
Operand name = resolve_expr(node->expr, AST_CANT_BE_NULL);
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
if(!name.is_const) compiler_error(node->pos, "size_of requires a constant value");
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
Value v = value_int(type->size);
@@ -1049,7 +1055,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(LENGTH_OF, Builtin){
Operand name = resolve_expr(node->expr, AST_CANT_BE_NULL);
Operand name = resolve_expr(node->expr, inherit_flag(flags, AST_CANT_BE_NULL));
if(name.type == type_type){
if(is_array(name.type_val)){
Value value = value_int(name.type_val->arr.size);
@@ -1071,7 +1077,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
}
CASE(CALL, Call){
Operand name = resolve_expr(node->name, AST_CANT_BE_NULL);
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL));
if(name.type->kind != TYPE_LAMBDA)
compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type));

View File

@@ -10,6 +10,7 @@ FLAG32(Resolve_Flag){
AST_CANT_BE_NULL = bit_flag(0),
AST_CAN_BE_NULL = bit_flag(1),
RESOLVE_TYPESPEC_COMPLETE = bit_flag(2),
RESOLVE_TYPESPEC = bit_flag(3),
};
FLAG32(Search_Flag){
@@ -20,6 +21,13 @@ function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compo
function void resolve_decl(Ast_Decl *ast);
function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);
function Resolve_Flag
inherit_flag(Resolve_Flag flag, B32 ast_can_be_null){
unset_flag(flag, AST_CAN_BE_NULL);
set_flag(flag, ast_can_be_null);
return flag;
}
//-----------------------------------------------------------------------------
// Operands
//-----------------------------------------------------------------------------