We are working! POLYMORPHS There was an error where we have to reconstruct exact

typespec from type. This means we will probably have problems with namespaces!!
This commit is contained in:
Krzosa Karol
2023-04-02 15:07:47 +02:00
parent c4b27bf604
commit 41d2baa56b
5 changed files with 30 additions and 10 deletions

View File

@@ -52,7 +52,7 @@ MultipleArgs :: (): Tuple(int, F32)
return {32, 32} return {32, 32}
PolyLambda :: ($T: Type = *int): T PolyLambda :: ($T: Type = *int): T
return 32 return 0
PolyType :: (a: $T): T PolyType :: (a: $T): T
return a return a
@@ -92,11 +92,12 @@ main :: (argc: int, argv: **char): int
Test(10, b = 10, c = 20) Test(10, b = 10, c = 20)
Test(a = 10, b = 10, c = 20) Test(a = 10, b = 10, c = 20)
value := PolyLambda(**int) // value := PolyLambda(**int)
PolyType_r1 := PolyType(10) // PolyType_r1 := PolyType(10)
PolyType_r2 := PolyType(int) // PolyType_r2 := PolyType(int)
// PolyType_r3 := PolyType(array) PolyType_r5 := PolyType(seventh)
// PolyType_r4 := PolyType(seventh) // PolyType_r3 := PolyType(test)
// PolyType_r4 := PolyType(test_a)
// PolyType_r5 := PolyType(sixth) // PolyType_r5 := PolyType(sixth)
return 0 return 0

View File

@@ -363,6 +363,7 @@ enum {
AST_TYPE_POLYMORPH = 1 << 16, AST_TYPE_POLYMORPH = 1 << 16,
AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH, AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH,
AST_PARENT_POLYMORPH = 1 << 17, AST_PARENT_POLYMORPH = 1 << 17,
AST_POLYMORPH_INSTANCE = 1 << 18,
AST_TYPESPEC = 1 << 18, AST_TYPESPEC = 1 << 18,
}; };
@@ -614,6 +615,7 @@ struct Ast_Decl : Ast {
Ast_Operator_Info *overload_op_info; Ast_Operator_Info *overload_op_info;
uint64_t polymorph_hash; uint64_t polymorph_hash;
Array<Ast_Call_Item *> instantiation_call_items;
Array<Ast_Decl *> polymorph_parameters; Array<Ast_Decl *> polymorph_parameters;
Array<Ast_Decl *> polymorphs; // instantiated polymorphs Array<Ast_Decl *> polymorphs; // instantiated polymorphs

View File

@@ -70,7 +70,16 @@ Ast_Expr *create_typespec_from_type(Token *pos, Ast_Scope *parent_scope, Ast_Typ
case TYPE_UNION: case TYPE_UNION:
case TYPE_ENUM: { case TYPE_ENUM: {
Ast_Decl *decl = (Ast_Decl *)type->ast; Ast_Decl *decl = (Ast_Decl *)type->ast;
result = ast_ident(pos, decl->name);
// @warning:
// Can we do this differently?
// WE MIGHT HAVE PROBLEM WITH NAMESPACES in the future!!!
if (decl->flags & AST_POLYMORPH_INSTANCE) {
Ast_Atom *ident = ast_ident(pos, decl->name);
ident->parent_scope = parent_scope;
result = ast_call(pos, ident, decl->instantiation_call_items);
}
else result = ast_ident(pos, decl->name);
} break; } break;
} }
result->parent_scope = parent_scope; result->parent_scope = parent_scope;
@@ -362,6 +371,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Ast_Decl *> *replace, Arr
assert(result); assert(result);
unset_flag(result->flags, AST_POLYMORPH | AST_PARENT_POLYMORPH); unset_flag(result->flags, AST_POLYMORPH | AST_PARENT_POLYMORPH);
set_flag(result->flags, AST_POLYMORPH_INSTANCE);
return result; return result;
} }
@@ -399,8 +409,9 @@ Ast_Decl *get_or_instantiate_polymorph_type(Token *pos, Ast_Decl *poly, Array<As
if (!result) { if (!result) {
result = (Ast_Decl *)ast_copy(poly, poly->parent_scope, &poly->polymorph_parameters, &params); result = (Ast_Decl *)ast_copy(poly, poly->parent_scope, &poly->polymorph_parameters, &params);
if (poly->kind == AST_STRUCT || poly->kind == AST_UNION) result->type_val = type_incomplete(result); result->type_val = type_incomplete(result);
result->polymorph_hash = hash; result->polymorph_hash = hash;
result->instantiation_call_items = params.tight_copy(pctx->perm);
assert(result->di != poly->di); assert(result->di != poly->di);
result->unique_name = get_unique_name_for_decl(result); result->unique_name = get_unique_name_for_decl(result);
@@ -410,7 +421,7 @@ Ast_Decl *get_or_instantiate_polymorph_type(Token *pos, Ast_Decl *poly, Array<As
} }
resolve_decl(result); resolve_decl(result);
if (poly->kind == AST_STRUCT || poly->kind == AST_UNION) type_complete(result->type_val); type_complete(result->type_val);
return result; return result;
} }
@@ -436,6 +447,7 @@ Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<
Operand op = resolve_expr(it->item, AST_CANT_BE_NULL, 0, field_access_scope); Operand op = resolve_expr(it->item, AST_CANT_BE_NULL, 0, field_access_scope);
try_converting_untyped_to_default_type(&op); try_converting_untyped_to_default_type(&op);
try_propagating_resolved_type_to_untyped_literals(it->item, op.type); try_propagating_resolved_type_to_untyped_literals(it->item, op.type);
// type_complete(op.type);
assert(it->item->resolved_type == op.type); assert(it->item->resolved_type == op.type);
hash = hash_mix(hash, hash_ptr(op.type)); hash = hash_mix(hash, hash_ptr(op.type));

View File

@@ -1155,6 +1155,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
} }
Ast_Decl *decl = resolve_name(scope, node->pos, node->intern_val, flag | RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED); Ast_Decl *decl = resolve_name(scope, node->pos, node->intern_val, flag | RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED);
// if (decl->type_val && decl->type_val->kind == TYPE_POLYMORPH) {
// compiler_error(ast->pos, "Trying to use a polymorphic in an invalid way");
// }
// Substitute lambda alias // Substitute lambda alias
if (decl->kind == AST_CONST && decl->resolved_decl && decl->resolved_decl->kind == AST_LAMBDA) { if (decl->kind == AST_CONST && decl->resolved_decl && decl->resolved_decl->kind == AST_LAMBDA) {

View File

@@ -19,6 +19,8 @@ get_name_of_type(Ast_Type *type) {
case TYPE_TUPLE: return "Tuple"; case TYPE_TUPLE: return "Tuple";
case TYPE_TYPE: case TYPE_TYPE:
return "Type"; return "Type";
case TYPE_POLYMORPH:
return "<Polymorph>";
invalid_default_case; invalid_default_case;
} }
return "<unknown_type>"; return "<unknown_type>";
@@ -219,8 +221,8 @@ type_enum(Ast_Decl *ast, Ast_Type *type) {
CORE_Static Ast_Type * CORE_Static Ast_Type *
type_incomplete(Ast *ast) { type_incomplete(Ast *ast) {
if (is_flag_set(ast->flags, AST_POLYMORPH)) return 0;
Ast_Type_Kind kind = TYPE_INCOMPLETE; Ast_Type_Kind kind = TYPE_INCOMPLETE;
if (is_flag_set(ast->flags, AST_POLYMORPH)) kind = TYPE_POLYMORPH;
Ast_Type *result = type_new(pctx->perm, kind, 0, 0); Ast_Type *result = type_new(pctx->perm, kind, 0, 0);
result->ast = ast; result->ast = ast;
return result; return result;