WOO YEE Basic polymorphism for untyped values, not working for typed expressions yet
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user