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

@@ -14,6 +14,69 @@ get_unique_name_for_decl(Ast_Decl *decl) {
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)
Ast *ast__create_copy(Ast_Scope *parent_scope, size_t size, Ast *ast) {
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) {
// @todo: IF ITS STRUCT we only want to replace TYPESPECS
For(*replace) {
assert(it->type == pctx->type_type);
if (it->name == dst->intern_val) {
S64 it_index = replace->get_index(it);
Ast_Call_Item *replacement = with[0][it_index];
Ast *replacement_v = replacement->item;
dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0);
if (it->flags & AST_IDENT_POLYMORPH) {
assert(it->type == pctx->type_type);
if (it->name == dst->intern_val) {
S64 it_index = replace->get_index(it);
Ast_Call_Item *replacement = with[0][it_index];
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) {
if (params.len != poly->polymorph_parameters.len) compiler_error(pos, "Invalid count of polymorphic arguments");
Scoped_Arena scratch(pctx->scratch);
int i = 0;
uint64_t hash = 91;
For(params) {
Ast_Decl *poly_decl = poly->polymorph_parameters[i++];
resolve_decl(poly_decl);
if (poly_decl->type != pctx->type_type) compiler_error(poly_decl->pos, "Invalid type of polymorphic struct argument");
if (poly_decl->flags & AST_IDENT_POLYMORPH) {
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);
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");
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.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;