WOO YEE Basic polymorphism for untyped values, not working for typed expressions yet
This commit is contained in:
@@ -47,12 +47,16 @@ MakeArray :: (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
|
||||
// a,b := MultipleArgs() // @todo var unpacking
|
||||
MultipleArgs :: (): Tuple(int, F32)
|
||||
return {32, 32}
|
||||
|
||||
PolyLambda :: ($T: Type = *int): T
|
||||
return 32
|
||||
|
||||
PolyType :: (a: $T): T
|
||||
return a
|
||||
|
||||
GetCount :: (a: int): int
|
||||
return a
|
||||
|
||||
@@ -78,7 +82,7 @@ main :: (argc: int, argv: **char): int
|
||||
|
||||
// c := MakeArray(buff, GetCount(GetCount(32)))
|
||||
|
||||
// a,b := MultipleArgs()
|
||||
|
||||
a := MultipleArgs()
|
||||
|
||||
Test(10)
|
||||
@@ -89,5 +93,10 @@ main :: (argc: int, argv: **char): int
|
||||
Test(a = 10, b = 10, c = 20)
|
||||
|
||||
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
|
||||
@@ -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,6 +120,7 @@ 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) {
|
||||
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);
|
||||
@@ -65,6 +129,25 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Ast_Decl *> *replace, Arr
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = dst;
|
||||
@@ -333,11 +416,13 @@ 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++];
|
||||
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");
|
||||
|
||||
@@ -347,6 +432,15 @@ Ast_Decl *get_or_instantiate_polymorph_lambda(Token *pos, Ast_Decl *poly, Array<
|
||||
|
||||
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;
|
||||
For(poly->polymorphs) {
|
||||
|
||||
@@ -625,7 +625,7 @@ insert_into_scope(Ast_Scope *scope, Ast_Decl *decl) {
|
||||
// need to propagate int to untyped_int
|
||||
//
|
||||
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 (!ast) 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};
|
||||
ForArrayRemovable(matches) {
|
||||
ForArrayRemovablePrepare(matches);
|
||||
|
||||
if (it.lambda_arg->flags & AST_POLYMORPH) {
|
||||
replacements.add(it.call_arg);
|
||||
ForArrayRemovableDeclare();
|
||||
}
|
||||
if (it.lambda_arg->flags & AST_POLYMORPH) replacements.add(it.call_arg);
|
||||
if (it.lambda_arg->flags & AST_IDENT_POLYMORPH) ForArrayRemovableDeclare();
|
||||
}
|
||||
|
||||
Ast_Decl *poly = name.resolved_decl;
|
||||
|
||||
@@ -57,6 +57,9 @@ enum {
|
||||
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 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);
|
||||
|
||||
Reference in New Issue
Block a user