Lot's of work on Any and Type
This commit is contained in:
4
ast.cpp
4
ast.cpp
@@ -113,8 +113,7 @@ struct Ast_Var_Unpack: Ast_Expr{
|
|||||||
struct Ast_Unary: Ast_Expr{
|
struct Ast_Unary: Ast_Expr{
|
||||||
Token_Kind op;
|
Token_Kind op;
|
||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
Ast_Type *resolved_type_val;
|
U64 padding[2]; // For folding constants into atoms
|
||||||
U64 padding[1]; // For folding constants into atoms
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Index: Ast_Expr{
|
struct Ast_Index: Ast_Expr{
|
||||||
@@ -175,6 +174,7 @@ struct Ast_Lambda : Ast_Expr {
|
|||||||
struct Ast_Array: Ast_Expr{
|
struct Ast_Array: Ast_Expr{
|
||||||
Ast_Expr *base;
|
Ast_Expr *base;
|
||||||
Ast_Expr *expr;
|
Ast_Expr *expr;
|
||||||
|
U64 padding[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast_Switch_Case: Ast{
|
struct Ast_Switch_Case: Ast{
|
||||||
|
|||||||
30
ccodegen.cpp
30
ccodegen.cpp
@@ -178,7 +178,7 @@ gen_value(Value a){
|
|||||||
assert(a.type == type_pointer_to_char);
|
assert(a.type == type_pointer_to_char);
|
||||||
gen("\"%Q\"", a.intern_val);
|
gen("\"%Q\"", a.intern_val);
|
||||||
} else{
|
} else{
|
||||||
gen("LIT(\"%Q\")", a.intern_val);
|
gen("(String){(U8 *)\"%Q\", %d}", a.intern_val, a.intern_val.len);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_BOOL: a.bool_val ? gen("true"):gen("false"); 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
|
function bool
|
||||||
gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
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){
|
switch(ast->kind){
|
||||||
CASE(IDENT, Atom){
|
CASE(IDENT, Atom){
|
||||||
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
if(node->resolved_decl->kind == AST_MODULE_NAMESPACE || node->resolved_decl->kind == AST_FILE_NAMESPACE)
|
||||||
@@ -344,21 +337,9 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
|
|
||||||
CASE(UNARY, Unary){
|
CASE(UNARY, Unary){
|
||||||
gen("(");
|
gen("(");
|
||||||
if(node->op != TK_PostIncrement && node->op != TK_PostDecrement){
|
if(node->op != TK_PostIncrement && node->op != TK_PostDecrement) gen("%s", name(node->op));
|
||||||
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));
|
|
||||||
}
|
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr);
|
||||||
if(node->op == TK_PostIncrement || node->op == TK_PostDecrement) gen("%s", name(node->op));
|
if(node->op == TK_PostIncrement || node->op == TK_PostDecrement) gen("%s", name(node->op));
|
||||||
gen(")");
|
gen(")");
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
@@ -398,7 +379,7 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
|
|||||||
gen(".%Q = ", it->resolved_name);
|
gen(".%Q = ", it->resolved_name);
|
||||||
else if(is_array(node->resolved_type))
|
else if(is_array(node->resolved_type))
|
||||||
gen("[%d] = ", (int)it->resolved_index);
|
gen("[%d] = ", (int)it->resolved_index);
|
||||||
gen_expr(it->item);
|
gen_expr(it->item, it->resolved_type);
|
||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
}
|
}
|
||||||
gen("}");
|
gen("}");
|
||||||
@@ -832,7 +813,6 @@ typedef struct String{
|
|||||||
U8 *str;
|
U8 *str;
|
||||||
S64 len;
|
S64 len;
|
||||||
}String;
|
}String;
|
||||||
#define LIT(x) (String){.str=(U8 *)x, .len=sizeof(x)-1}
|
|
||||||
#define assert(x) do{if(!(x))__debugbreak();}while(0)
|
#define assert(x) do{if(!(x))__debugbreak();}while(0)
|
||||||
#define assert_msg(x,...) assert(x)
|
#define assert_msg(x,...) assert(x)
|
||||||
|
|
||||||
@@ -919,7 +899,7 @@ typedef struct String{
|
|||||||
gen(".struct_member_count = %d, ", it->agg.members.len);
|
gen(".struct_member_count = %d, ", it->agg.members.len);
|
||||||
gen(".struct_members = (Type_Info_Struct_Member[]){");
|
gen(".struct_members = (Type_Info_Struct_Member[]){");
|
||||||
For_Named(it->agg.members, m){
|
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("}");
|
gen("}");
|
||||||
|
|||||||
2
main.cpp
2
main.cpp
@@ -43,7 +43,6 @@ want to export all the symbols, we can namespace them optionally.
|
|||||||
@todo
|
@todo
|
||||||
[ ] - Probably need to give Ast_Expr a Value field, then I can express Type nicely
|
[ ] - 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
|
[ ] - 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
|
[ ] - #test construct that would gather all tests and run them on start of program or something
|
||||||
[ ] - Foreign import that would link library
|
[ ] - 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
|
[ ] - 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
|
@donzo
|
||||||
|
[x] - Implementing type Any
|
||||||
[x] - Runtime TypeInfo
|
[x] - Runtime TypeInfo
|
||||||
[x] - Proper type Type support
|
[x] - Proper type Type support
|
||||||
[x] - Switch
|
[x] - Switch
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ Slice :: struct
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Dynamic_Array :: struct
|
||||||
|
data: *void
|
||||||
|
len : S64
|
||||||
|
cap : S64
|
||||||
|
|
||||||
Any :: struct
|
Any :: struct
|
||||||
data: *void
|
data: *void
|
||||||
type: Type
|
type: Type
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ print :: (a: Any)
|
|||||||
OutputDebugStringA("Pointer")
|
OutputDebugStringA("Pointer")
|
||||||
default;; OutputDebugStringA("Unknown")
|
default;; OutputDebugStringA("Unknown")
|
||||||
|
|
||||||
|
// print_array :: (a: []Any)
|
||||||
|
// for i := 0, i < length_of(a), i+=1
|
||||||
|
// print(a[i])
|
||||||
|
|
||||||
|
|
||||||
app_is_running := true
|
app_is_running := true
|
||||||
window_procedure :: (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM): LRESULT
|
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
|
if good_scheduling := false, timeBeginPeriod(1) == TIMERR_NOERROR
|
||||||
good_scheduling = true
|
good_scheduling = true
|
||||||
|
|
||||||
|
some_type: Type = Vec2
|
||||||
char_info := get_type_info(char)
|
char_info := get_type_info(char)
|
||||||
val := 4232.23
|
val := 4232.23
|
||||||
thing: Any = val
|
thing: Any = val
|
||||||
print(val)
|
print(val)
|
||||||
|
// print_array({125.23, 32})
|
||||||
|
|
||||||
assert(char_info.kind == Type_Info_Kind.CHAR)
|
assert(char_info.kind == Type_Info_Kind.CHAR)
|
||||||
#assert(int == int)
|
#assert(int == int)
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ resolve_typespec(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context =
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Scratch scratch;
|
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))
|
if(is_flag_set(flags, RESOLVE_TYPESPEC_COMPLETE))
|
||||||
type_complete(resolved.type_val);
|
type_complete(resolved.type_val);
|
||||||
if(resolved.type != type_type)
|
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;
|
Ast_Type *item_type = type->arr.base;
|
||||||
S64 size = type->arr.size;
|
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);
|
compiler_error(node->pos, "Too many items in compound expression, expected: %lld got: %lld", size, node->exprs.len);
|
||||||
|
|
||||||
S64 default_counter = 0;
|
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 type = resolve_expr(node->base, AST_CANT_BE_NULL);
|
||||||
Operand expr = require_const_int(node->expr, AST_CAN_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");
|
if(type.type != type_type) compiler_error(node->pos, "Prefix array operator is only allowed on types");
|
||||||
|
|
||||||
type_complete(type.type_val);
|
type_complete(type.type_val);
|
||||||
|
|
||||||
|
if(!is_flag_set(flags, RESOLVE_TYPESPEC)){
|
||||||
|
rewrite_into_const(node, Ast_Array, type.value);
|
||||||
|
}
|
||||||
|
|
||||||
if(node->expr){
|
if(node->expr){
|
||||||
node->resolved_type = type_array(type.type_val, bigint_as_unsigned(&expr.big_int_val));
|
node->resolved_type = type_array(type.type_val, bigint_as_unsigned(&expr.big_int_val));
|
||||||
} else{
|
} else{
|
||||||
node->resolved_type = type_slice(type.type_val, node);
|
node->resolved_type = type_slice(type.type_val, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return operand_type(node->resolved_type);
|
return operand_type(node->resolved_type);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
@@ -919,7 +922,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
if(is_string(left.type)){
|
if(is_string(left.type)){
|
||||||
return operand_lvalue(type_u8);
|
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));
|
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){
|
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(node->op == TK_Pointer){
|
||||||
if(value.type->kind == TYPE_POINTER){
|
if(value.type->kind == TYPE_POINTER){
|
||||||
node->resolved_type = value.type->base;
|
node->resolved_type = value.type->base;
|
||||||
return operand_lvalue(node->resolved_type);
|
return operand_lvalue(node->resolved_type);
|
||||||
}
|
}
|
||||||
else if(value.type->kind == TYPE_TYPE){
|
else if(value.type->kind == TYPE_TYPE){
|
||||||
node->resolved_type = type_type;
|
if(!is_flag_set(flags, RESOLVE_TYPESPEC)){
|
||||||
node->resolved_type_val = type_pointer(value.type_val);
|
rewrite_into_const(node, Ast_Array, value.value);
|
||||||
return operand_type(node->resolved_type_val);
|
}
|
||||||
|
|
||||||
|
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 {}; }
|
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){
|
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;
|
Ast_Type *type = op.type;
|
||||||
if(type){
|
if(type){
|
||||||
@@ -1016,7 +1022,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
|
|||||||
|
|
||||||
type_complete(type);
|
type_complete(type);
|
||||||
node->resolved_type = type;
|
node->resolved_type = type;
|
||||||
if(is_array(type)){
|
if(is_array(type) || is_slice(type)){
|
||||||
resolve_compound_array(node, type);
|
resolve_compound_array(node, type);
|
||||||
}
|
}
|
||||||
else if(is_struct(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){
|
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");
|
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;
|
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
||||||
Value v = value_int(type->align);
|
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){
|
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");
|
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;
|
Ast_Type *type = name.type == type_type ? name.type_val : name.type;
|
||||||
Value v = value_int(type->size);
|
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){
|
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(name.type == type_type){
|
||||||
if(is_array(name.type_val)){
|
if(is_array(name.type_val)){
|
||||||
Value value = value_int(name.type_val->arr.size);
|
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){
|
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)
|
if(name.type->kind != TYPE_LAMBDA)
|
||||||
compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type));
|
compiler_error(node->pos, "Calling %Q which is not a [Lambda]", typestring(name.type));
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ FLAG32(Resolve_Flag){
|
|||||||
AST_CANT_BE_NULL = bit_flag(0),
|
AST_CANT_BE_NULL = bit_flag(0),
|
||||||
AST_CAN_BE_NULL = bit_flag(1),
|
AST_CAN_BE_NULL = bit_flag(1),
|
||||||
RESOLVE_TYPESPEC_COMPLETE = bit_flag(2),
|
RESOLVE_TYPESPEC_COMPLETE = bit_flag(2),
|
||||||
|
RESOLVE_TYPESPEC = bit_flag(3),
|
||||||
};
|
};
|
||||||
|
|
||||||
FLAG32(Search_Flag){
|
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 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 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
|
// Operands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user