diff --git a/core_ast.cpp b/core_ast.cpp index 284d473..1f0edc3 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -223,6 +223,7 @@ ast_struct(Token *pos, Ast_Scope *scope, Ast_Kind kind, Array polymo if (polymorph_parameters.len) { result->polymorph_parameters = polymorph_parameters; set_flag(result->flags, AST_POLYMORPH); + set_flag(result->flags, AST_PARENT_POLYMORPH); result->polymorphs.allocator = pctx->heap; } return result; @@ -631,6 +632,13 @@ set_flag_typespec(Ast_Expr *expr) { } } +CORE_Static void +unset_polymorph(Ast *ast) { + for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) { + unset_flag(iter.ast->flags, AST_POLYMORPH); + } +} + CORE_Static bool is_typespec_polymorphic(Ast *ast) { for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) { diff --git a/core_compiler.cpp b/core_compiler.cpp index f3d9463..4a300dd 100644 --- a/core_compiler.cpp +++ b/core_compiler.cpp @@ -289,11 +289,10 @@ resolve_everything_in_module(Ast_Module *module) { pctx->time.typechecking = os_time(); For_Named(module->all_loaded_files, file) { For_Named(file->decls, decl) { - bool is_polymorph = decl->flags & AST_POLYMORPH; - if (is_polymorph) continue; + if (decl->flags & AST_POLYMORPH) continue; + // @cleanup: Why I'm not calling resolve_decl here? resolve_name(file, decl->pos, decl->name); - if (decl->kind == AST_STRUCT || decl->kind == AST_UNION) type_complete(decl->type_val); } } diff --git a/core_compiler_interface.hpp b/core_compiler_interface.hpp index 584cbc1..8437d2b 100644 --- a/core_compiler_interface.hpp +++ b/core_compiler_interface.hpp @@ -358,11 +358,13 @@ enum { AST_VAR_IS_CONST = 1 << 12, AST_OPERATOR_OVERLOAD = 1 << 13, AST_IS_LVALUE = 1 << 14, + AST_IDENT_POLYMORPH = 1 << 15, AST_TYPE_POLYMORPH = 1 << 16, AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH, + AST_PARENT_POLYMORPH = 1 << 17, - AST_TYPESPEC = 1 << 17, + AST_TYPESPEC = 1 << 18, }; struct Ast { @@ -509,7 +511,7 @@ struct Ast_For : Ast { struct Ast_Lambda : Ast_Expr { Array args; - + // :Multiple arguments // @todo: maybe disallow multiple arguments in current form // and use polimorphism. Then we could make var unpacking, diff --git a/core_parsing.cpp b/core_parsing.cpp index 0436fe8..318f768 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -927,8 +927,10 @@ parse_decl(B32 is_global) { auto a = (Ast_Lambda *)expr; if (a->scope || is_flag_set(flags, AST_FOREIGN)) { result->kind = AST_LAMBDA; - if (is_flag_set(a->flags, AST_POLYMORPH)) + if (is_flag_set(a->flags, AST_POLYMORPH)) { set_flag(result->flags, AST_POLYMORPH); + set_flag(result->flags, AST_PARENT_POLYMORPH); + } if (is_flag_set(flags, AST_FOREIGN)) set_flag(expr->flags, flags); } diff --git a/core_polymorph.cpp b/core_polymorph.cpp index 94323c6..c9472a7 100644 --- a/core_polymorph.cpp +++ b/core_polymorph.cpp @@ -53,15 +53,15 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *replace, Arr Ast_Atom *src = (Ast_Atom *)ast; Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast); - if ((dst->flags & AST_TYPESPEC)) { + if (replace && with && (dst->flags & AST_TYPESPEC)) { For(*replace) { assert(it->type == pctx->type_type); if (it->name == dst->intern_val) { int it_index = replace->get_index(&it); Ast_Call_Item *replacement = with[0][it_index]; - Ast_Atom *replacement_v = (Ast_Atom *)replacement->item; - assert(replacement_v->resolved_type == pctx->type_type); - dst = ast_create_copy(parent_scope, Ast_Atom, replacement_v); + Ast *replacement_v = replacement->item; + // assert(replacement_v->resolved_type == pctx->type_type); + dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0); } } } @@ -117,7 +117,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array *replace, Arr dst->name = (Ast_Expr *)ast_copy(src->name, parent_scope, replace, with); dst->exprs.init(pctx->perm, src->exprs.len); - For(dst->exprs) { + For(src->exprs) { auto copy = (Ast_Call_Item *)ast_copy(it, parent_scope, replace, with); dst->exprs.add(copy); } diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 1645513..b78e232 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1128,7 +1128,7 @@ unpack_ast_call_expr_for_builtin(Ast_Call *call) { CORE_Static bool expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern) { - assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY); + assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY || expr->kind == AST_VALUE); if (expr->kind == AST_IDENT) { Ast_Atom *atom = (Ast_Atom *)expr; if (atom->intern_val == intern) { @@ -1565,21 +1565,26 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str else { Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); - // - // Polymorphic instantiation - // + // @cleanup: polymorphic structs probably shouldnt have types, not sure? if (name.type == pctx->type_type) { if (name.type_val->kind != TYPE_POLYMORPH) { compiler_error(node->pos, "Parenthesis are not valid for types that are not polymorphic"); } - Ast_Decl *poly = name.resolved_decl; - assert(poly->flags & AST_POLYMORPH); + } - // node->exprs = params - Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope); - resolve_decl(instance); - type_complete(instance->type_val); - return operand_type(instance->type_val); + if (name.resolved_decl->flags & AST_POLYMORPH) { + assert(name.resolved_decl->flags & AST_PARENT_POLYMORPH); + Ast_Decl *poly = name.resolved_decl; + + if (poly->kind == AST_LAMBDA) { + // Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope); + } + else { + Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope); + resolve_decl(instance); + type_complete(instance->type_val); + return operand_type(instance->type_val); + } } /* @todo: @@ -1729,6 +1734,7 @@ resolve_decl(Ast_Decl *ast) { compiler_error(ast->pos, "Cyclic dependency of %s", ast->name.str); return; } + if (ast->flags & AST_PARENT_POLYMORPH) return; assert(ast->state == DECL_NOT_RESOLVED); ast->state = DECL_RESOLVING; diff --git a/examples/_polymorphism.core b/examples/_polymorphism.core index e9ed8d5..8d7cb3b 100644 --- a/examples/_polymorphism.core +++ b/examples/_polymorphism.core @@ -47,9 +47,12 @@ MultipleArgs :: (): Tuple(int, F32) return {32, 32} PolyLambda :: (value: $T): T - pass + return value +GetCount :: (a: int): int + return a + main :: (argc: int, argv: **char): int buff: *int array: Array(int) = {len = 10, cap = 10, data = buff} @@ -57,8 +60,13 @@ main :: (argc: int, argv: **char): int third_array: Array(int) fourth: Array(F32) fifth: Array(F32) + sixth: Array(Array(F32)) + + // c := MakeArray(buff, GetCount(GetCount(32))) // a,b := MultipleArgs() a := MultipleArgs() + // value := PolyLambda(32) + return 0 \ No newline at end of file