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{
|
||||
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{
|
||||
|
||||
30
ccodegen.cpp
30
ccodegen.cpp
@@ -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,21 +337,9 @@ 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));
|
||||
if(node->op == TK_PostIncrement || node->op == TK_PostDecrement) gen("%s", name(node->op));
|
||||
gen(")");
|
||||
BREAK();
|
||||
}
|
||||
@@ -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("}");
|
||||
|
||||
2
main.cpp
2
main.cpp
@@ -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
|
||||
|
||||
@@ -10,6 +10,11 @@ Slice :: struct
|
||||
|
||||
*/
|
||||
|
||||
Dynamic_Array :: struct
|
||||
data: *void
|
||||
len : S64
|
||||
cap : S64
|
||||
|
||||
Any :: struct
|
||||
data: *void
|
||||
type: Type
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user