diff --git a/core_ast.cpp b/core_ast.cpp index b2634f2..284d473 100644 --- a/core_ast.cpp +++ b/core_ast.cpp @@ -20,17 +20,6 @@ _ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0) { return result; } -CORE_Static void -propagate_polymorphic(Ast *to, Ast *from) { - if (is_flag_set(from->flags, AST_IDENT_POLYMORPH)) set_flag(to->flags, AST_IDENT_POLYMORPH); - if (is_flag_set(from->flags, AST_TYPE_POLYMORPH)) set_flag(to->flags, AST_TYPE_POLYMORPH); -} - -CORE_Static void -propagate_polymorphic(Ast *to, Token *from) { - if (from->kind == TK_Polymorph) set_flag(to->flags, AST_IDENT_POLYMORPH); -} - CORE_Static Ast_Atom * ast_str(Token *pos, Intern_String string) { AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM); @@ -127,6 +116,7 @@ ast_lambda(Token *pos, Array params, Array ret, Ast_Scop result->args = params.tight_copy(pctx->perm); result->ret = ret.tight_copy(pctx->perm); result->scope = scope; + For(params) if (is_flag_set(it->flags, AST_POLYMORPH)) set_flag(result->flags, AST_POLYMORPH); return result; } @@ -640,3 +630,14 @@ set_flag_typespec(Ast_Expr *expr) { set_flag(iter.ast->flags, AST_TYPESPEC); } } + +CORE_Static bool +is_typespec_polymorphic(Ast *ast) { + for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) { + assert(iter.kind == AST_UNARY || iter.kind == AST_ARRAY || iter.kind == AST_CALL || iter.kind == AST_CALL_ITEM || iter.kind == AST_IDENT); + if (is_flag_set(iter.ast->flags, AST_POLYMORPH)) { + return true; + } + } + return false; +} diff --git a/core_parsing.cpp b/core_parsing.cpp index bb81467..b44a725 100644 --- a/core_parsing.cpp +++ b/core_parsing.cpp @@ -477,9 +477,12 @@ parse_parameter_list(Arena *arena) { param->name = name->intern_val; param->typespec = parse_expr(); set_flag_typespec(param->typespec); - - propagate_polymorphic(param, param->typespec); - propagate_polymorphic(param, name); + if (is_typespec_polymorphic(param->typespec)) { + set_flag(param->flags, AST_TYPE_POLYMORPH); + } + if (name->kind == TK_Polymorph) { + set_flag(param->flags, AST_IDENT_POLYMORPH); + } if (token_match(TK_Assign)) { param->expr = parse_expr(); @@ -608,7 +611,10 @@ parse_expr(S64 min_bp) { switch (token->kind) { case TK_StringLit: left = ast_str(token, token->intern_val); break; case TK_Identifier: left = ast_ident(token, token->intern_val); break; - case TK_Polymorph: left = ast_ident(token, token->intern_val); break; + case TK_Polymorph: { + left = ast_ident(token, token->intern_val); + set_flag(left->flags, AST_POLYMORPH); + } break; case TK_Integer: left = ast_int(token, token->int_val); break; case TK_UnicodeLit: left = ast_int(token, token->unicode); break; case TK_Float: left = ast_float(token, token->f64_val); break; @@ -624,7 +630,6 @@ parse_expr(S64 min_bp) { case TK_Pointer: { left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right)); auto unary = (Ast_Unary *)left; - propagate_polymorphic(unary, unary->expr); } break; // Array subscript -> [32]int @@ -636,7 +641,6 @@ parse_expr(S64 min_bp) { Ast_Array *result = ast_array(token, expr); token_expect(TK_CloseBracket); result->base = parse_expr(prefix_bp.right); - propagate_polymorphic(result, result->base); left = result; } break; diff --git a/examples/_polymorphism.core b/examples/_polymorphism.core index 93a9c6d..e9ed8d5 100644 --- a/examples/_polymorphism.core +++ b/examples/_polymorphism.core @@ -26,8 +26,12 @@ Array :: struct($T: Type) Tuple :: struct($A: Type, $B: Type) a: A b: B +Triple :: struct($A: Type, $B: Type, $C: Type) + a: A + b: B + c: C -make_array :: (a: *int, count: int): Array(int) +MakeArray :: (a: *int, count: int): Array(int) result := Array(int) { data = a, len = count, @@ -39,9 +43,13 @@ make_array :: (a: *int, count: int): Array(int) // @todo: maybe disallow multiple arguments in current form // and use polimorphism. Then we could make var unpacking, // unpack structs making it more powerful -multiple_args :: (): Tuple(int, F32) +MultipleArgs :: (): Tuple(int, F32) return {32, 32} +PolyLambda :: (value: $T): T + pass + + main :: (argc: int, argv: **char): int buff: *int array: Array(int) = {len = 10, cap = 10, data = buff} @@ -50,6 +58,7 @@ main :: (argc: int, argv: **char): int fourth: Array(F32) fifth: Array(F32) - a,b := multiple_args() + // a,b := MultipleArgs() + a := MultipleArgs() return 0 \ No newline at end of file