diff --git a/ccodegen.cpp b/ccodegen.cpp index 0108f75..9d10b8f 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -20,15 +20,15 @@ gen_indent(){ function void gen_simple_decl_prefix(Ast_Resolved_Type *ast){ switch(ast->kind){ - case TYPE_Int: gen("int "); break; - case TYPE_Bool: gen("bool "); break; - case TYPE_Unsigned: gen("unsigned "); break; - case TYPE_String: gen("String "); break; - case TYPE_Void: gen("void "); break; - case TYPE_Pointer:{gen_simple_decl_prefix(ast->base); gen("*");} break; - case TYPE_Array: gen_simple_decl_prefix(ast->base); break; - case TYPE_Lambda:break; - case TYPE_Struct: { + case TYPE_INT: gen("int "); break; + case TYPE_BOOL: gen("bool "); break; + case TYPE_UNSIGNED: gen("unsigned "); break; + case TYPE_STRING: gen("String "); break; + case TYPE_VOID: gen("void "); break; + case TYPE_POINTER:{gen_simple_decl_prefix(ast->base); gen("*");} break; + case TYPE_ARRAY: gen_simple_decl_prefix(ast->base); break; + case TYPE_LAMBDA:break; + case TYPE_STRUCT: { auto name = ast->sym->name; gen("%s ", name.str); }break; @@ -39,22 +39,22 @@ gen_simple_decl_prefix(Ast_Resolved_Type *ast){ function void gen_simple_decl_postfix(Ast_Resolved_Type *ast){ switch(ast->kind){ - case TYPE_Int: break; - case TYPE_Bool: break; - case TYPE_Unsigned: break; - case TYPE_String: break; - case TYPE_Void: break; - case TYPE_Pointer: gen_simple_decl_postfix(ast->base); break; - case TYPE_Array: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break; - case TYPE_Lambda:break; - case TYPE_Struct:break; + case TYPE_INT: break; + case TYPE_BOOL: break; + case TYPE_UNSIGNED: break; + case TYPE_STRING: break; + case TYPE_VOID: break; + case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break; + case TYPE_ARRAY: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break; + case TYPE_LAMBDA:break; + case TYPE_STRUCT:break; invalid_default_case; } } function void gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){ - if(ast->kind == TYPE_Lambda) { + if(ast->kind == TYPE_LAMBDA) { gen_simple_decl_prefix(ast->func.ret); gen("(*%s)(", name.str); For(ast->func.args){ @@ -75,39 +75,39 @@ gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){ function void gen_expr(Ast_Expr *ast){ switch(ast->kind){ - Ast_Begin(AST_IDENT, Ast_Atom){ + CASE(IDENT, Atom){ gen("%s", node->intern_val.str); - Ast_End(); + BREAK(); } - Ast_Begin(AST_INT, Ast_Atom){ + CASE(INT, Atom){ gen("%lld", node->int_val); - Ast_End(); + BREAK(); } - Ast_Begin(AST_STR, Ast_Atom){ + CASE(STR, Atom){ gen("LIT(\"%s\")", node->intern_val.str); - Ast_End(); + BREAK(); } - Ast_Begin(AST_INDEX, Ast_Index){ + CASE(INDEX, Index){ gen_expr(node->expr); gen("["); gen_expr(node->index); gen("]"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_BINARY, Ast_Binary){ + CASE(BINARY, Binary){ gen("("); gen_expr(node->left); gen("%s", token_kind_string(node->op).str); gen_expr(node->right); gen(")"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_UNARY, Ast_Unary){ + CASE(UNARY, Unary){ switch(node->op){ case TK_Pointer: { gen("(*"); @@ -121,20 +121,20 @@ gen_expr(Ast_Expr *ast){ } break; invalid_default_case; } - Ast_End(); + BREAK(); } - Ast_Begin(AST_CAST, Ast_Cast){ + CASE(CAST, Cast){ gen("("); gen("("); gen_simple_decl(resolved_type_get(node->typespec), {}); gen(")"); gen_expr(node->expr); gen(")"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_COMPOUND, Ast_Compound){ + CASE(COMPOUND, Compound){ gen("("); gen_simple_decl(node->type, {}); gen(")"); @@ -159,7 +159,7 @@ gen_expr(Ast_Expr *ast){ } gen("}"); - Ast_End(); + BREAK(); } invalid_default_case; @@ -184,25 +184,25 @@ function void gen_ast(Ast *ast){ switch(ast->kind){ - Ast_Begin(AST_PACKAGE, Ast_Package){ + CASE(PACKAGE, Package){ For(node->ordered) { genln(""); gen_ast(*it); } - Ast_End(); + BREAK(); } - Ast_Begin(AST_RETURN, Ast_Return){ + CASE(RETURN, Return){ gen("return"); if(node->expr){ gen(" "); gen_expr(node->expr); } gen(";"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_VAR, Ast_Var){ + CASE(VAR, Var){ Sym *sym = resolved_get(node); gen_simple_decl(sym->type, node->name); if(node->expr){ @@ -210,10 +210,10 @@ gen_ast(Ast *ast){ gen_expr(node->expr); } gen(";"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_INIT, Ast_Init){ + CASE(INIT, Init){ Sym *sym = resolved_get(node); gen_simple_decl(sym->type, node->ident->intern_val); if(node->expr){ @@ -221,10 +221,10 @@ gen_ast(Ast *ast){ gen_expr(node->expr); } gen(";"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_IF, Ast_If){ + CASE(IF, If){ For(node->ifs){ if(it[0]->init) gen_ast(it[0]->init); if(node->ifs.is_first(it)){ @@ -243,13 +243,13 @@ gen_ast(Ast *ast){ gen_block(it[0]->block); } } - Ast_End(); + BREAK(); } - Ast_Begin(AST_CONST, Ast_Const){ + CASE(CONST, Const){ Sym *sym = resolved_get(node); - if(sym->type->kind == TYPE_Lambda){ + if(sym->type->kind == TYPE_LAMBDA){ if(node->value->kind == AST_LAMBDA){ Ast_Lambda *lambda = (Ast_Lambda *)node->value; gen("static "); @@ -283,7 +283,7 @@ gen_ast(Ast *ast){ gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str); } else if(sym->type == type_type){ - if(sym->type_val->kind == TYPE_Struct){ + if(sym->type_val->kind == TYPE_STRUCT){ Ast_Struct *agg = const_get_struct(sym->type_val->sym->ast); if(node->value->kind == AST_STRUCT){ gen("struct %s{", node->name.str); @@ -309,7 +309,7 @@ gen_ast(Ast *ast){ parsing_error(node->pos, "C_Codegen: Unhandled type of constant expression"); } - Ast_End(); + BREAK(); } invalid_default_case; diff --git a/main.cpp b/main.cpp index 6735718..11af4a5 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,6 @@ #include "new_lex.cpp" #include "new_ast.cpp" #include "new_parse.cpp" -#include "new_type.cpp" #include "new_resolve.cpp" #include "ccodegen.cpp" diff --git a/new_ast.cpp b/new_ast.cpp index ff49ba1..5626f55 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -226,7 +226,11 @@ struct Ast_Var: Ast_Named{ }; struct Ast_Const: Ast_Named{ - Ast_Expr *value; + union{ + Ast *ast; + Ast_Expr *value; + Ast_Struct *agg; + }; }; struct Ast_Package:Ast{ @@ -460,3 +464,21 @@ ast_package(Token *pos, String name, Array decls){ For(result->decls) it[0]->parent = result; return result; } + +//----------------------------------------------------------------------------- +// Utillities +//----------------------------------------------------------------------------- +function Ast_Struct * +const_get_struct(Ast *ast){ + assert(ast->kind == AST_CONST); + Ast_Const *constant = (Ast_Const *)ast; + assert(constant->value->kind == AST_STRUCT); + return (Ast_Struct *)constant->value; +} + +function Intern_String +ast_get_name(Ast *ast){ + assert(is_flag_set(ast->flags, AST_BINDING)); + auto constant = (Ast_Named *)ast; + return constant->name; +} diff --git a/new_resolve.cpp b/new_resolve.cpp index 1a56e25..e3e1ed2 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -1,5 +1,5 @@ -#define Ast_Begin(kind,type) case kind: { type *node = (type *)ast; -#define Ast_End() } break +#define CASE(kind,type) case AST_##kind: { Ast_##type *node = (Ast_##type *)ast; +#define BREAK() } break enum Sym_Kind{ SYM_NONE, @@ -37,6 +37,14 @@ struct Operand{ INLINE_VALUE_FIELDS; }; +enum{ + AST_CANT_BE_NULL = 0, + AST_CAN_BE_NULL = 1 +}; + +function Sym *resolve_name(Token *pos, Intern_String name); +function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *const_sym = 0); +function Operand resolve_binding(Ast *ast, Sym *sym = 0); global Ast_Named empty_decl = {}; function void @@ -104,6 +112,7 @@ resolved_get(Ast *ast){ assert(result); return result; } +#include "new_type.cpp" function Ast_Resolved_Type * resolved_type_get(Ast_Expr *ast){ @@ -150,18 +159,10 @@ sym_insert_builtins(){ } } -function Sym *resolve_name(Token *pos, Intern_String name); -function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *lambda_to_complete = 0); - -enum{ - AST_CANT_BE_NULL = 0, - AST_CAN_BE_NULL = 1 -}; - function Ast_Resolved_Type * -eval_typespec(Ast_Expr *ast, B32 ast_can_be_null = AST_CANT_BE_NULL){ +resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null = AST_CANT_BE_NULL){ if(ast_can_be_null && ast == 0) return 0; - Operand resolved = eval_expr(ast); + Operand resolved = resolve_expr(ast); if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind); return resolved.type_val; } @@ -173,67 +174,66 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ else if(a && !b) result = a; else if(!a && !b) parsing_error(pos, "Trying to resolve a type pair where both types are [Null]"); else{ // a && b - if(b->kind == TYPE_Null) result = a; - else if(a->kind == TYPE_Null) result = b; + if(b->kind == TYPE_NULL) result = a; + else if(a->kind == TYPE_NULL) result = b; else if(a != b) parsing_error(pos, "Expression and type specification are differing %s %s", type_names[a->kind], type_names[b->kind]); else result = a; // Types are the same } - if(result->kind == TYPE_Null) parsing_error(pos, "Couldn't infer type of null value"); + if(result->kind == TYPE_NULL) parsing_error(pos, "Couldn't infer type of null value"); return result; } -function Operand eval_binding(Ast *ast, Sym *sym = 0); function void -eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ +resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ switch(ast->kind){ - Ast_Begin(AST_RETURN, Ast_Return){ // @todo: need to check if all paths return a value + CASE(RETURN, Return){ // @todo: need to check if all paths return a value Operand op = {}; - if(node->expr) op = eval_expr(node->expr); + if(node->expr) op = resolve_expr(node->expr); if(!op.type && ret != type_void) parsing_error(node->pos, "Function expects a void return value but the returned value is [x]"); if(op.type && op.type != ret) parsing_error(node->pos, "Return statement has different type then returned value"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_VAR, Ast_Var){ - Operand op = eval_binding(node); + CASE(VAR, Var){ + Operand op = resolve_binding(node); Sym *sym = sym_new_resolved(SYM_VAR, node->name, op.type, op.value, node); sym_insert(sym); - Ast_End(); + BREAK(); } - Ast_Begin(AST_CONST, Ast_Const){ - Operand op = eval_binding(node); + CASE(CONST, Const){ + Operand op = resolve_binding(node); Sym *sym = sym_new_resolved(SYM_CONST, node->name, op.type, op.value, node); sym_insert(sym); - Ast_End(); + BREAK(); } - Ast_Begin(AST_INIT, Ast_Init){ + CASE(INIT, Init){ switch(node->op){ case TK_Comma:{ - Operand op = eval_expr(node->expr); + Operand op = resolve_expr(node->expr); Sym *sym = sym_new_resolved(SYM_VAR, node->ident->intern_val, op.type, op.value, node); sym_insert(sym); }break; invalid_default_case; } - Ast_End(); + BREAK(); } - Ast_Begin(AST_IF, Ast_If){ + CASE(IF, If){ For(node->ifs){ - if(it[0]->init) eval_stmt(it[0]->init, ret); - if(it[0]->expr) eval_expr(it[0]->expr); + if(it[0]->init) resolve_stmt(it[0]->init, ret); + if(it[0]->expr) resolve_expr(it[0]->expr); S64 scope_index = scope_open(); For_It(it[0]->block->stmts, jt){ - eval_stmt(jt[0], ret); + resolve_stmt(jt[0], ret); } scope_close(scope_index); } - Ast_End(); + BREAK(); } invalid_default_case; @@ -241,29 +241,29 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ } function Operand -eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){ +resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ switch(ast->kind){ - Ast_Begin(AST_INT, Ast_Atom){ + CASE(INT, Atom){ Operand result = {type_int, true}; result.int_val = node->int_val; return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_STR, Ast_Atom){ + CASE(STR, Atom){ Operand result = {type_string, true}; result.intern_val = node->intern_val; return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_IDENT, Ast_Atom){ + CASE(IDENT, Atom){ Sym *sym = resolve_name(node->pos, node->intern_val); // @cleanup: due to Value being a union this portion probably can get cleaned // @note: check if null and rewrite the expression to match the expected type Operand result = {}; - if(sym->type->kind == TYPE_Null){ + if(sym->type->kind == TYPE_NULL){ if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null"); result.type = expected_type; result.is_const = true; @@ -277,30 +277,30 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple else invalid_codepath; return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_ARRAY, Ast_Array){ - Operand type = eval_expr(node->base); + CASE(ARRAY, Array){ + Operand type = resolve_expr(node->base); if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types"); - Operand expr = eval_expr(node->expr); + Operand expr = resolve_expr(node->expr); if(!expr.is_const) parsing_error(node->pos, "Array operator requires a constant value"); if(expr.type != type_int) parsing_error(node->pos, "Array index requires type [Int]"); type.type_val = type_array(type.type_val, expr.int_val); sym_new_resolved(SYM_CONST, {}, type_type, type.value, node); return type; - Ast_End(); + BREAK(); } - Ast_Begin(AST_LAMBDA, Ast_Lambda){ + CASE(LAMBDA, Lambda){ // @note: first resolve type of lambda Scratch scratch; Ast_Resolved_Type *lambda_type = 0; - Ast_Resolved_Type *ret_type = eval_typespec(node->ret); + Ast_Resolved_Type *ret_type = resolve_typespec(node->ret); Array args = {scratch}; For(node->args){ - Operand type = eval_expr(it[0]->typespec); + Operand type = resolve_expr(it[0]->typespec); if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]"); args.add(type.type_val); } @@ -309,9 +309,9 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple assert(lambda_type); Value val; val.type_val = lambda_type; sym_new_resolved(SYM_CONST, {}, type_type, val, node); - if(lambda_to_complete){ - lambda_to_complete->type = lambda_type; - lambda_to_complete->state = SYM_RESOLVED; + if(const_sym){ + const_sym->type = lambda_type; + const_sym->state = SYM_RESOLVED; } } @@ -329,34 +329,34 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple sym_insert(arg_sym); } For(node->block->stmts){ - eval_stmt(it[0], ret_type); + resolve_stmt(it[0], ret_type); } scope_close(scope_index); result.type = lambda_type; } return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_INDEX, Ast_Index){ - Operand left = eval_expr(node->expr); - Operand index = eval_expr(node->index); - if(left.type->kind != TYPE_Array) parsing_error(node->pos, "Indexing variable that is not an array"); + CASE(INDEX, Index){ + Operand left = resolve_expr(node->expr); + Operand index = resolve_expr(node->index); + if(left.type->kind != TYPE_ARRAY) parsing_error(node->pos, "Indexing variable that is not an array"); if(index.type != type_int) parsing_error(node->pos, "Trying to index the array with invalid type, expected int"); Operand result = {left.type->arr.base}; return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_COMPOUND, Ast_Compound){ - Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL); + CASE(COMPOUND, Compound){ + Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); if(!type && expected_type) type = expected_type; else if(!expected_type && type); else if(expected_type != type) parsing_error(node->pos, "Variable type different from explicit compound type"); node->type = type; - if(type->kind == TYPE_Array){ + if(type->kind == TYPE_ARRAY){ if(node->exprs.len > type->arr.size) parsing_error(node->pos, "compound statement has too many items for this type"); Ast_Resolved_Type *item_type = type->arr.base; @@ -366,12 +366,12 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple assert(i->kind == AST_COMPOUND_ITEM); if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); if(i->index){ - Operand index_op = eval_expr(i->index); + Operand index_op = resolve_expr(i->index); if(!index_op.is_const) parsing_error(i->pos, "Index in a compound expression is not a constant"); if(index_op.type != type_int) parsing_error(i->pos, "Index should be of type int"); if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store"); } - Operand expr = eval_expr(i->item, item_type); + Operand expr = resolve_expr(i->item, item_type); resolve_type_pair(i->pos, expr.type, item_type); } } @@ -379,12 +379,12 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Operand result = {type, false}; return result; - Ast_End(); + BREAK(); } - Ast_Begin(AST_CAST, Ast_Cast){ - Operand expr = eval_expr(node->expr); - Ast_Resolved_Type *type = eval_typespec(node->typespec); + CASE(CAST, Cast){ + Operand expr = resolve_expr(node->expr); + Ast_Resolved_Type *type = resolve_typespec(node->typespec); if(type == expr.type) return expr; @@ -405,18 +405,18 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple else parsing_error(node->pos, "Failed to cast, incompatible types"); - Ast_End(); + BREAK(); } - Ast_Begin(AST_UNARY, Ast_Unary){ - Operand value = eval_expr(node->expr); + CASE(UNARY, Unary){ + Operand value = resolve_expr(node->expr); switch(node->op){ case TK_Pointer:{ - if(value.type->kind == TYPE_Pointer){ + if(value.type->kind == TYPE_POINTER){ Operand result = {value.type->base}; return result; } - else if(value.type->kind == TYPE_Type){ + else if(value.type->kind == TYPE_TYPE){ Operand result = {type_type, true}; result.type_val = type_pointer(value.type_val); return result; @@ -430,12 +430,12 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple invalid_default_case; return {}; } - Ast_End(); + BREAK(); } - Ast_Begin(AST_BINARY, Ast_Binary){ - Operand left = eval_expr(node->left); - Operand right = eval_expr(node->right); + CASE(BINARY, Binary){ + Operand left = resolve_expr(node->left); + Operand right = resolve_expr(node->right); Operand result = {}; result.type = resolve_type_pair(node->pos, left.type, right.type); if(left.is_const && right.is_const){ @@ -453,17 +453,17 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple } return result; - Ast_End(); + BREAK(); } // @todo: add const prepass? expecting only structs, exprs, lambdas - Ast_Begin(AST_STRUCT, Ast_Struct){ - assert(lambda_to_complete); + CASE(STRUCT, Struct){ + assert(const_sym); Scratch scratch; - Array members = {scratch}; + Array members = {scratch}; For(node->members){ - Operand op = eval_binding(it[0]); + Operand op = resolve_binding(it[0]); Intern_String name = {}; if(is_flag_set(it[0]->flags, AST_BINDING)){ @@ -474,11 +474,10 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); members.add({op.type, name}); } - Ast_Resolved_Type *resolved = type_struct(lambda_to_complete, members); + Ast_Resolved_Type *resolved = type_struct(const_sym, members); Operand result = {type_type, true}; result.type_val = resolved; return result; - - Ast_End(); + BREAK(); } invalid_default_case; @@ -488,54 +487,47 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple } function Operand -eval_binding(Ast *ast, Sym *sym){ +resolve_binding(Ast *ast, Sym *sym){ switch(ast->kind){ - - Ast_Begin(AST_VAR, Ast_Var){ - Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL); - Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; + CASE(VAR, Var){ + Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); + Operand expr = node->expr ? resolve_expr(node->expr, type) : Operand{}; expr.type = resolve_type_pair(node->pos, type, expr.type); return expr; - Ast_End(); + BREAK(); } - Ast_Begin(AST_CONST, Ast_Const){ - Operand expr = eval_expr((Ast_Expr *)node->value, 0, sym); - if(!expr.type) parsing_error(node->pos, "Constant value without expression"); + CASE(CONST, Const){ + Operand expr = resolve_expr((Ast_Expr *)node->value, 0, sym); if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression"); + assert(expr.type); return expr; - Ast_End(); + BREAK(); } - invalid_default_case; return {}; } } -function Ast_Struct * -const_get_struct(Ast *ast){ - assert(ast->kind == AST_CONST); - Ast_Const *constant = (Ast_Const *)ast; - assert(constant->value->kind == AST_STRUCT); - return (Ast_Struct *)constant->value; -} - function void resolve_sym(Sym *sym){ - if(sym->state == SYM_RESOLVED) return; - else if(sym->state == SYM_RESOLVING){ parsing_error(sym->ast->pos, "Cyclic dependency"); return; } + if(sym->state == SYM_RESOLVED){ + return; + } + else if(sym->state == SYM_RESOLVING){ + parsing_error(sym->ast->pos, "Cyclic dependency"); + return; + } assert(sym->state == SYM_NOT_RESOLVED); - assert(sym->ast->kind == AST_VAR || sym->ast->kind == AST_CONST); - sym->state = SYM_RESOLVING; - Operand op = eval_binding(sym->ast, sym); - sym->type = op.type; - if(sym->kind == SYM_CONST){ - assert(op.is_const); + sym->state = SYM_RESOLVING; + { + Operand op = resolve_binding(sym->ast, sym); + sym->type = op.type; sym->value = op.value; } - sym->state = SYM_RESOLVED; + pctx->resolving_package->ordered.add((Ast_Named *)sym->ast); } @@ -572,21 +564,18 @@ parse_file(){ Ast_Named *decl = parse_named(true); if(!decl) break; - Sym_Kind kind = SYM_VAR; - if(decl->kind == AST_CONST) kind = SYM_CONST; - else if(decl->kind == AST_VAR) kind = SYM_VAR; - else invalid_codepath; + Sym *sym = sym_new(SYM_VAR, decl->name, decl); + if(decl->kind == AST_CONST) { + sym->kind = SYM_CONST; + auto constant = (Ast_Const *)decl; + if(constant->value->kind == AST_STRUCT){ + sym->type = type_incomplete(sym); + sym->state = SYM_RESOLVED; + } + } + else assert(decl->kind == AST_VAR); - Sym *sym = sym_new(kind, decl->name, decl); - // if(kind == SYM_CONST){ - // auto constant = (Ast_Const *)decl; - // if(constant->value->kind == AST_STRUCT) { - // sym->type = type_incomplete(sym); - // sym->state = SYM_RESOLVED; - // } - // } sym_insert(sym); - decls.add(decl); } Ast_Package *result = ast_package(token, token->file, decls); diff --git a/new_type.cpp b/new_type.cpp index 32f2958..93ce750 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -1,24 +1,26 @@ enum Ast_Resolved_Type_Kind{ - TYPE_None, - TYPE_Null, - TYPE_Incomplete, - TYPE_Int, - TYPE_Bool, - TYPE_Unsigned, - TYPE_String, - TYPE_Void, - TYPE_Pointer, - TYPE_Array, - TYPE_Lambda, - TYPE_Struct, - TYPE_Union, - TYPE_Enum, - TYPE_Type, + TYPE_NONE, + TYPE_NULL, + TYPE_COMPLETING, + TYPE_INCOMPLETE, + TYPE_INT, + TYPE_BOOL, + TYPE_UNSIGNED, + TYPE_STRING, + TYPE_VOID, + TYPE_POINTER, + TYPE_ARRAY, + TYPE_LAMBDA, + TYPE_STRUCT, + TYPE_UNION, + TYPE_ENUM, + TYPE_TYPE, }; const char *type_names[] = { "[Invalid Ast_Resolved_Type]", "[Null]", + "[Completing]", "[Incomplete]", "[Int]", "[Bool]", @@ -34,7 +36,7 @@ const char *type_names[] = { "[Type]", }; -struct Ast_Resolved_Type_Field{ +struct Ast_Resolved_Member{ Ast_Resolved_Type *type; Intern_String name; U64 offset; @@ -53,7 +55,7 @@ struct Ast_Resolved_Type{ SizeU size; }arr; struct{ - Array fields; + Array members; }agg; struct{ Ast_Resolved_Type *ret; @@ -65,13 +67,13 @@ struct Ast_Resolved_Type{ const SizeU pointer_size = sizeof(SizeU); const SizeU pointer_align = __alignof(SizeU); -global Ast_Resolved_Type type__null = {TYPE_Null}; -global Ast_Resolved_Type type__void = {TYPE_Void}; -global Ast_Resolved_Type type__int = {TYPE_Int, sizeof(int), __alignof(int)}; -global Ast_Resolved_Type type__unsigned = {TYPE_Int, sizeof(unsigned), __alignof(unsigned)}; -global Ast_Resolved_Type type__string = {TYPE_String, sizeof(String), __alignof(String)}; -global Ast_Resolved_Type type__bool = {TYPE_Bool, sizeof(bool), __alignof(bool)}; -global Ast_Resolved_Type type__type = {TYPE_Type}; +global Ast_Resolved_Type type__null = {TYPE_NULL}; +global Ast_Resolved_Type type__void = {TYPE_VOID}; +global Ast_Resolved_Type type__int = {TYPE_INT, sizeof(int), __alignof(int)}; +global Ast_Resolved_Type type__unsigned = {TYPE_INT, sizeof(unsigned), __alignof(unsigned)}; +global Ast_Resolved_Type type__string = {TYPE_STRING, sizeof(String), __alignof(String)}; +global Ast_Resolved_Type type__bool = {TYPE_BOOL, sizeof(bool), __alignof(bool)}; +global Ast_Resolved_Type type__type = {TYPE_TYPE}; global Ast_Resolved_Type *type_type = &type__type; global Ast_Resolved_Type *type_void = &type__void; @@ -101,11 +103,11 @@ function Ast_Resolved_Type * type_pointer(Ast_Resolved_Type *base){ Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, (void *)base); if(!result){ - result = type_new(pctx->perm, TYPE_Pointer, pointer_size, pointer_align); + result = type_new(pctx->perm, TYPE_POINTER, pointer_size, pointer_align); result->base = base; map_insert(&pctx->type_map, base, result); } - assert(result->kind == TYPE_Pointer); + assert(result->kind == TYPE_POINTER); return result; } @@ -114,13 +116,13 @@ type_array(Ast_Resolved_Type *base, SizeU size){ U64 hash = hash_mix(hash_ptr(base), hash_u64(size)); Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash); if(result){ - assert(result->kind == TYPE_Array); + assert(result->kind == TYPE_ARRAY); assert(result->arr.size == size); assert(result->arr.base == base); return result; } - result = type_new(pctx->perm, TYPE_Array, pointer_size, pointer_align); + result = type_new(pctx->perm, TYPE_ARRAY, pointer_size, pointer_align); result->arr.base = base; result->arr.size = size; map_insert(&pctx->type_map, hash, result); @@ -134,13 +136,13 @@ type_lambda(Ast_Resolved_Type *ret, Array args){ Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash); if(result){ - assert(result->kind == TYPE_Lambda); + assert(result->kind == TYPE_LAMBDA); assert(result->func.ret == ret); assert(result->func.args.len == args.len); return result; } - result = type_new(pctx->perm, TYPE_Lambda, pointer_size, pointer_align); + result = type_new(pctx->perm, TYPE_LAMBDA, pointer_size, pointer_align); result->func.ret = ret; result->func.args = args.tight_copy(pctx->perm); map_insert(&pctx->type_map, hash, result); @@ -150,21 +152,45 @@ type_lambda(Ast_Resolved_Type *ret, Array args){ function Ast_Resolved_Type * type_incomplete(Sym *sym){ - Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Incomplete, 0, 0); + Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_INCOMPLETE, 0, 0); result->sym = sym; return result; } +//Array members function void -type_complete_struct(Ast_Resolved_Type *type, Array fields){ - type->agg.fields = fields.tight_copy(pctx->perm); - type->kind = TYPE_Struct; +type_complete(Ast_Resolved_Type *type){ + if(type->kind == TYPE_COMPLETING){ + parsing_error(0, "Cyclic type dependency"); + } + else if(type->kind != TYPE_INCOMPLETE){ + return; + } + Ast_Struct *node = const_get_struct(type->sym->ast); + + // @note: resolve all the struct members + type->kind = TYPE_COMPLETING; + { + Scratch scratch; + Array members = {scratch}; + For(node->members){ + Operand op = resolve_binding(it[0]); + Intern_String name = ast_get_name(it[0]); + sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); + members.add({op.type, name}); + } + type->agg.members = members.tight_copy(pctx->perm); + } + + // @note: complete struct + type->kind = TYPE_STRUCT; + // @todo: compute size, alignement, offset } function Ast_Resolved_Type * -type_struct(Sym *sym, Array fields){ - Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Struct, 0, 0); // @todo: align,size - result->agg.fields = fields.tight_copy(pctx->perm); +type_struct(Sym *sym, Array members){ + Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_STRUCT, 0, 0); // @todo: align,size + result->agg.members = members.tight_copy(pctx->perm); result->sym = sym; return result; }