diff --git a/ccodegen.cpp b/ccodegen.cpp index ae3b4d6..5a692fd 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -379,10 +379,12 @@ compile_string(String filecontent, String filename = "default_name"_s){ sym_insert_builtins(); pctx->resolving_package = result; - gen(R"==(//------------------------------- + gen(R"==( +//------------------------------- #define NULL_POINTER 0 #define NULL_LAMBDA 0 -//-------------------------------)=="); +//------------------------------- + )=="); resolve_package(result); // eval_decl(result); diff --git a/main.cpp b/main.cpp index 9c931be..cadbaef 100644 --- a/main.cpp +++ b/main.cpp @@ -88,9 +88,13 @@ int main(){ String result = {}; result = compile_file("globals.kl"_s); + printf("%s", result.str); result = compile_file("enums.kl"_s); + printf("%s", result.str); result = compile_file("lambdas.kl"_s); + printf("%s", result.str); result = compile_file("order1.kl"_s); + printf("%s", result.str); result = compile_file("order2.kl"_s); printf("%s", result.str); diff --git a/new_type.cpp b/new_type.cpp index f34eebe..6c29166 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -179,30 +179,19 @@ type_incomplete(Ast *ast){ } function void -type_complete(Ast_Resolved_Type *type){ - if(type->kind == TYPE_COMPLETING){ - parsing_error(type->ast->pos, "Cyclic type dependency"); - } - else if(type->kind != TYPE_INCOMPLETE){ - return; - } - Ast_Struct *node = (Ast_Struct *)type->ast; - +type_struct_complete(Ast_Resolved_Type *type, Ast_Struct *node){ // @todo: compute size, alignement, offset !!! - // @note: resolve all the struct members + // @note: resolve all the struct members first type->kind = TYPE_COMPLETING; - { - Scratch scratch; - Array members = {scratch}; - For(node->members){ - Operand op = resolve_binding(it); - Intern_String name = ast_get_name(it); - sym_new_resolved(SYM_VAR, name, op.type, {}, it); - members.add({op.type, name}); - } - type->agg.members = members.tight_copy(pctx->perm); + Scratch scratch; + Array members = {scratch}; + For(node->members){ + Operand op = resolve_binding(it); + Intern_String name = ast_get_name(it); + sym_new_resolved(SYM_VAR, name, op.type, {}, it); + members.add({op.type, name}); } - + type->agg.members = members.tight_copy(pctx->perm); type->kind = TYPE_STRUCT; // @note: resolve constant members after the struct got resolved @@ -215,7 +204,27 @@ type_complete(Ast_Resolved_Type *type){ Intern_String name = ast_get_name(it); sym_new_resolved(SYM_CONST, name, op.type, op.value, it); } +} +function Ast_Resolved_Type * +type_struct(Ast_Struct *agg){ + Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_STRUCT, 0, 0); + result->ast = agg; + type_struct_complete(result, agg); + return result; +} + +function void +type_complete(Ast_Resolved_Type *type){ + if(type->kind == TYPE_COMPLETING){ + parsing_error(type->ast->pos, "Cyclic type dependency"); + } + else if(type->kind != TYPE_INCOMPLETE){ + return; + } + + Ast_Struct *node = (Ast_Struct *)type->ast; + type_struct_complete(type, node); pctx->resolving_package->ordered.add((Ast_Named *)node->parent); } diff --git a/order2.kl b/order2.kl index 4629b40..9c1d6c1 100644 --- a/order2.kl +++ b/order2.kl @@ -21,6 +21,9 @@ Arena :: struct len : int cap : int + Sub :: struct + len: int + get_len :: (s: *Arena): int // @todo return s.next.len diff --git a/typechecking.cpp b/typechecking.cpp index 182e3b1..6c85eb8 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -306,7 +306,7 @@ _rewrite_into_const(Ast *node, U64 ast_size, Sym *sym){ #define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym) function Operand -resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ +resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){ if(!ast) return {}; // @todo: add option for better error prevention switch(ast->kind){ @@ -326,6 +326,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ CASE(IDENT, Atom){ Sym *sym = resolve_name(node->pos, node->intern_val); + Operand result = {}; // @note: check if null and rewrite the expression to match the expected type if(sym->type->kind == TYPE_NULL){ @@ -382,7 +383,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ } CASE(LAMBDA, Lambda){ - // @note: first resolve type of lambda + // @note: first resolve type of lambda so recursive lambdas work Scratch scratch; Ast_Resolved_Type *lambda_type = 0; Ast_Resolved_Type *ret_type = resolve_typespec(node->ret); @@ -395,17 +396,16 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ args.add(type.type_val); } lambda_type = type_lambda(node, ret_type, args); - { sym_type(node, lambda_type); - if(const_sym){ - const_sym->type = lambda_type; - const_sym->state = SYM_RESOLVED; + if(lambda_to_resolve){ + lambda_to_resolve->type = lambda_type; + lambda_to_resolve->state = SYM_RESOLVED; } } - Operand result = {type_type, true}; - result.type_val = lambda_type; + + Operand result = operand_type(lambda_type); // @todo: We also need to make sure there is a return value when ret type is not void // @note: then try resolving the block of lambda if(node->block){ @@ -455,9 +455,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ assert(i->kind == AST_CALL_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 = 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"); + Operand index_op = require_const_int(i->index, AST_CANT_BE_NULL); 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 = resolve_expr(i->item, item_type); @@ -503,9 +501,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ } // @note: cleanup, required? - For(agg->members){ - it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED); - } + For(agg->members) it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED); } else if(type->kind == TYPE_LAMBDA){ Scratch scratch; @@ -580,12 +576,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ expr.type = type_bool; return expr; } - else if(expr.type == type_bool && type == type_int){ expr.type = type_int; return expr; } - else if(expr.type == type_null){ expr.type = type; return expr; @@ -726,6 +720,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ BREAK(); } + CASE(STRUCT, Struct){ + Ast_Resolved_Type *type = type_struct(node); + return operand_type(type); + BREAK(); + } + + invalid_default_case; }