diff --git a/ccodegen.cpp b/ccodegen.cpp index 4c29102..3ca799b 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -314,6 +314,11 @@ gen_ast(Ast *ast){ genln(""); gen_ast(it); } + + For(agg->const_members){ + genln(""); + gen_ast(it); + } global_indent--; genln("};"); } diff --git a/new_ast.cpp b/new_ast.cpp index 7dd5f1a..8e6754e 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -554,19 +554,15 @@ is_atom(Ast *ast){ function Ast * query_struct(Ast_Struct *agg, Intern_String string){ - For(agg->members){ if(it->name == string){ return it; } } - For(agg->const_members){ if(it->name == string){ return it; } } - return 0; -} - +} \ No newline at end of file diff --git a/new_type.cpp b/new_type.cpp index 9e53f44..9eadbb9 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -181,6 +181,7 @@ type_complete(Ast_Resolved_Type *type){ } Ast_Struct *node = (Ast_Struct *)type->ast; + // @todo: compute size, alignement, offset !!! // @note: resolve all the struct members type->kind = TYPE_COMPLETING; { @@ -195,18 +196,20 @@ type_complete(Ast_Resolved_Type *type){ type->agg.members = members.tight_copy(pctx->perm); } - // @note: complete struct type->kind = TYPE_STRUCT; - // @todo: compute size, alignement, offset - pctx->resolving_package->ordered.add((Ast_Named *)node->parent); -} -function Ast_Resolved_Type * -type_struct(Ast *ast, 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->ast = ast; - return result; + // @note: resolve constant members after the struct got resolved + // this way we avoid a problem where we start resolving the function + // and this function has parameter of type parent struct + // which is being resolved right now, cyclic dependency happens. + // constants arent required to make struct work + For(node->const_members){ + Operand op = resolve_binding(it); + Intern_String name = ast_get_name(it); + sym_new_resolved(SYM_CONST, name, op.type, op.value, it); + } + + pctx->resolving_package->ordered.add((Ast_Named *)node->parent); } function void diff --git a/order2.kl b/order2.kl index 477a92f..e8b1691 100644 --- a/order2.kl +++ b/order2.kl @@ -23,7 +23,7 @@ Arena :: struct constant_outside :: 10000 get_len :: (s: *Arena): int - return s.next.len + return s.next.constant_inside string16: Str16 diff --git a/typechecking.cpp b/typechecking.cpp index 41f16d2..8079a86 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -246,6 +246,15 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } +function Operand +operand(Sym *sym){ + Operand result = {}; + result.type = sym->type; + result.is_const = sym->kind == SYM_CONST ? true : false; + result.value = sym->value; + return result; +} + function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ if(!ast) return {}; // @todo: add option for better error prevention @@ -277,9 +286,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ result.is_const = true; } else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){ - result.type = sym->type; - result.is_const = sym->kind == SYM_CONST ? true : false; - result.value = sym->value; + result = operand(sym); sym_new_resolved(SYM_CONST, sym->name, sym->type, sym->value, node); } else invalid_codepath; @@ -598,10 +605,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast *query = query_struct(agg, ident->intern_val); if(query){ Sym *sym = resolved_get(query); - result.type = sym->type; + result = operand(sym); sym_new_resolved(SYM_VAR, {}, sym->type, {}, ident); } else parsing_error(ident->pos, "No such member in struct"); - + } else{ Operand left = resolve_expr(node->left); @@ -627,30 +634,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ BREAK(); } - // @todo: add const first level function? expecting only structs, exprs, lambdas - CASE(STRUCT, Struct){ - assert(const_sym); - - Scratch scratch; - Array members = {scratch}; - For(node->members){ - Operand op = resolve_binding(it); - - Intern_String name = {}; - if(is_flag_set(it->flags, AST_BINDING)){ - Ast_Named *named = (Ast_Named *)it; - name = named->name; - } - - sym_new_resolved(SYM_VAR, name, op.type, {}, it); - members.add({op.type, name}); - } - Ast_Resolved_Type *resolved = type_struct(node, members); - Operand result = {type_type, true}; result.type_val = resolved; - return result; - BREAK(); - } - invalid_default_case; }