WOO YEE Basic polymorphism for untyped values, not working for typed expressions yet

This commit is contained in:
Krzosa Karol
2023-04-02 14:14:30 +02:00
parent 7203589915
commit c4b27bf604
4 changed files with 122 additions and 19 deletions

View File

@@ -47,12 +47,16 @@ MakeArray :: (a: *int, count: int): Array(int)
// @todo: maybe disallow multiple arguments in current form // @todo: maybe disallow multiple arguments in current form
// and use polimorphism. Then we could make var unpacking, // and use polimorphism. Then we could make var unpacking,
// unpack structs making it more powerful // unpack structs making it more powerful
// a,b := MultipleArgs() // @todo var unpacking
MultipleArgs :: (): Tuple(int, F32) MultipleArgs :: (): Tuple(int, F32)
return {32, 32} return {32, 32}
PolyLambda :: ($T: Type = *int): T PolyLambda :: ($T: Type = *int): T
return 32 return 32
PolyType :: (a: $T): T
return a
GetCount :: (a: int): int GetCount :: (a: int): int
return a return a
@@ -78,7 +82,7 @@ main :: (argc: int, argv: **char): int
// c := MakeArray(buff, GetCount(GetCount(32))) // c := MakeArray(buff, GetCount(GetCount(32)))
// a,b := MultipleArgs()
a := MultipleArgs() a := MultipleArgs()
Test(10) Test(10)
@@ -89,5 +93,10 @@ main :: (argc: int, argv: **char): int
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_r2 := PolyType(int)
// PolyType_r3 := PolyType(array)
// PolyType_r4 := PolyType(seventh)
// PolyType_r5 := PolyType(sixth)
return 0 return 0

View File

@@ -14,6 +14,69 @@ get_unique_name_for_decl(Ast_Decl *decl) {
return pctx->internf("%c%u_%Q", char_counter++, decl->di, decl->name); return pctx->internf("%c%u_%Q", char_counter++, decl->di, decl->name);
} }
CORE_Static String core_type_to_string(Ast_Type *type);
Ast_Expr *create_typespec_from_type(Token *pos, Ast_Scope *parent_scope, Ast_Type *type) {
Ast_Expr *result = 0;
switch (type->kind) {
case TYPE_NONE:
case TYPE_TUPLE:
case TYPE_COMPLETING:
case TYPE_INCOMPLETE:
case TYPE_POLYMORPH:
case TYPE_UNTYPED_BOOL:
case TYPE_UNTYPED_INT:
case TYPE_UNTYPED_FLOAT:
case TYPE_UNTYPED_STRING: {
invalid_codepath;
} break;
case TYPE_TYPE:
case TYPE_S64:
case TYPE_S32:
case TYPE_S16:
case TYPE_S8:
case TYPE_INT:
case TYPE_CHAR:
case TYPE_U64:
case TYPE_U32:
case TYPE_U16:
case TYPE_U8:
case TYPE_F32:
case TYPE_F64:
case TYPE_BOOL:
case TYPE_STRING:
case TYPE_VOID: {
String s = core_type_to_string(type);
result = ast_ident(pos, pctx->intern(s));
} break;
case TYPE_POINTER: {
result = ast_expr_unary(pos, TK_Pointer, create_typespec_from_type(pos, parent_scope, type->base));
} break;
case TYPE_ARRAY: {
Ast_Array *arr = ast_array(pos, create_typespec_from_type(pos, parent_scope, type->arr.base));
arr->expr = ast_int(pos, type->arr.size);
arr->expr->parent_scope = parent_scope;
result = arr;
} break;
case TYPE_SLICE: {
Ast_Array *arr = ast_array(pos, create_typespec_from_type(pos, parent_scope, type->arr.base));
result = arr;
} break;
case TYPE_LAMBDA: {
invalid_codepath;
} break;
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_ENUM: {
Ast_Decl *decl = (Ast_Decl *)type->ast;
result = ast_ident(pos, decl->name);
} break;
}
result->parent_scope = parent_scope;
return result;
}
#define ast_create_copy(parent_scope, T, ast) (T *)ast__create_copy(parent_scope, sizeof(T), ast) #define ast_create_copy(parent_scope, T, ast) (T *)ast__create_copy(parent_scope, sizeof(T), ast)
Ast *ast__create_copy(Ast_Scope *parent_scope, size_t size, Ast *ast) { Ast *ast__create_copy(Ast_Scope *parent_scope, size_t size, Ast *ast) {
if (ast == 0) return 0; if (ast == 0) return 0;
@@ -57,12 +120,32 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Ast_Decl *> *replace, Arr
if (replace && with) { if (replace && with) {
// @todo: IF ITS STRUCT we only want to replace TYPESPECS // @todo: IF ITS STRUCT we only want to replace TYPESPECS
For(*replace) { For(*replace) {
assert(it->type == pctx->type_type); if (it->flags & AST_IDENT_POLYMORPH) {
if (it->name == dst->intern_val) { assert(it->type == pctx->type_type);
S64 it_index = replace->get_index(it); if (it->name == dst->intern_val) {
Ast_Call_Item *replacement = with[0][it_index]; S64 it_index = replace->get_index(it);
Ast *replacement_v = replacement->item; Ast_Call_Item *replacement = with[0][it_index];
dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0); Ast *replacement_v = replacement->item;
dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0);
}
}
else if (it->flags & AST_TYPE_POLYMORPH) {
Ast_Expr *typespec = it->typespec;
assert(typespec);
assert(typespec->kind == AST_IDENT);
Ast_Atom *t = (Ast_Atom *)typespec;
if (t->intern_val == dst->intern_val) {
S64 it_index = replace->get_index(it);
// @todo: This probably should be resolved
// before calling the ast_copy function
// or something
Ast_Call_Item *replacement = with[0][it_index];
Ast_Type *type_to_replace = replacement->item->resolved_type;
dst = (Ast_Atom *)create_typespec_from_type(dst->pos, parent_scope, type_to_replace);
// dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0);
}
} }
} }
} }
@@ -333,19 +416,30 @@ Ast_Decl *get_or_instantiate_polymorph_type(Token *pos, Ast_Decl *poly, Array<As
Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<Ast_Call_Item *> params, Ast_Scope *field_access_scope) { Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<Ast_Call_Item *> params, Ast_Scope *field_access_scope) {
if (params.len != poly->polymorph_parameters.len) compiler_error(pos, "Invalid count of polymorphic arguments"); if (params.len != poly->polymorph_parameters.len) compiler_error(pos, "Invalid count of polymorphic arguments");
Scoped_Arena scratch(pctx->scratch);
int i = 0; int i = 0;
uint64_t hash = 91; uint64_t hash = 91;
For(params) { For(params) {
Ast_Decl *poly_decl = poly->polymorph_parameters[i++]; Ast_Decl *poly_decl = poly->polymorph_parameters[i++];
resolve_decl(poly_decl); if (poly_decl->flags & AST_IDENT_POLYMORPH) {
if (poly_decl->type != pctx->type_type) compiler_error(poly_decl->pos, "Invalid type of polymorphic struct argument"); resolve_decl(poly_decl);
if (poly_decl->type != pctx->type_type) compiler_error(poly_decl->pos, "Invalid type of polymorphic struct argument");
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);
if (!op.is_const) compiler_error(it->pos, "Argument is required to be compile time known"); if (!op.is_const) compiler_error(it->pos, "Argument is required to be compile time known");
if (op.type != pctx->type_type) compiler_error(it->pos, "Struct argument required to be a type"); if (op.type != pctx->type_type) compiler_error(it->pos, "Struct argument required to be a type");
hash = hash_mix(hash, hash_ptr(op.type_val)); hash = hash_mix(hash, hash_ptr(op.type_val));
}
else {
Operand op = resolve_expr(it->item, AST_CANT_BE_NULL, 0, field_access_scope);
try_converting_untyped_to_default_type(&op);
try_propagating_resolved_type_to_untyped_literals(it->item, op.type);
assert(it->item->resolved_type == op.type);
hash = hash_mix(hash, hash_ptr(op.type));
}
} }
Ast_Decl *result = 0; Ast_Decl *result = 0;

View File

@@ -625,7 +625,7 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl) {
// need to propagate int to untyped_int // need to propagate int to untyped_int
// //
CORE_Static void CORE_Static void
try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type = 0) { try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type) {
if (!type) compiler_error(ast->pos, "Internal compiler error: Type passed to try_propagating_resolved_type_to_untyped_literals is null"); if (!type) compiler_error(ast->pos, "Internal compiler error: Type passed to try_propagating_resolved_type_to_untyped_literals is null");
if (!ast) return; if (!ast) return;
if (is_untyped(type)) return; if (is_untyped(type)) return;
@@ -1699,11 +1699,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
Array<Ast_Call_Item *> replacements = {scratch.arena}; Array<Ast_Call_Item *> replacements = {scratch.arena};
ForArrayRemovable(matches) { ForArrayRemovable(matches) {
ForArrayRemovablePrepare(matches); ForArrayRemovablePrepare(matches);
if (it.lambda_arg->flags & AST_POLYMORPH) replacements.add(it.call_arg);
if (it.lambda_arg->flags & AST_POLYMORPH) { if (it.lambda_arg->flags & AST_IDENT_POLYMORPH) ForArrayRemovableDeclare();
replacements.add(it.call_arg);
ForArrayRemovableDeclare();
}
} }
Ast_Decl *poly = name.resolved_decl; Ast_Decl *poly = name.resolved_decl;

View File

@@ -57,6 +57,9 @@ enum {
RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED = bit_flag(2), RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED = bit_flag(2),
}; };
CORE_Static void try_converting_untyped_to_default_type(Operand *op);
CORE_Static void try_propagating_resolved_type_to_untyped_literals(Ast *ast, Ast_Type *type, Ast_Type *additional_not_bool_type = 0);
CORE_Static Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope); CORE_Static Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context, Ast_Scope *field_access_scope);
CORE_Static void resolve_decl(Ast_Decl *ast); CORE_Static void resolve_decl(Ast_Decl *ast);
CORE_Static Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0); CORE_Static Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0);