Polymorphs nested structs

This commit is contained in:
Krzosa Karol
2023-04-01 14:31:41 +02:00
parent 2c19658115
commit 3d438645a0
7 changed files with 48 additions and 23 deletions

View File

@@ -223,6 +223,7 @@ ast_struct(Token *pos, Ast_Scope *scope, Ast_Kind kind, Array<Ast_Decl *> polymo
if (polymorph_parameters.len) { if (polymorph_parameters.len) {
result->polymorph_parameters = polymorph_parameters; result->polymorph_parameters = polymorph_parameters;
set_flag(result->flags, AST_POLYMORPH); set_flag(result->flags, AST_POLYMORPH);
set_flag(result->flags, AST_PARENT_POLYMORPH);
result->polymorphs.allocator = pctx->heap; result->polymorphs.allocator = pctx->heap;
} }
return result; return result;
@@ -631,6 +632,13 @@ set_flag_typespec(Ast_Expr *expr) {
} }
} }
CORE_Static void
unset_polymorph(Ast *ast) {
for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) {
unset_flag(iter.ast->flags, AST_POLYMORPH);
}
}
CORE_Static bool CORE_Static bool
is_typespec_polymorphic(Ast *ast) { is_typespec_polymorphic(Ast *ast) {
for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) { for (Ast_Iter iter = iterate_depth_first(pctx->heap, ast, true); iter.ast; next(&iter)) {

View File

@@ -289,11 +289,10 @@ resolve_everything_in_module(Ast_Module *module) {
pctx->time.typechecking = os_time(); pctx->time.typechecking = os_time();
For_Named(module->all_loaded_files, file) { For_Named(module->all_loaded_files, file) {
For_Named(file->decls, decl) { For_Named(file->decls, decl) {
bool is_polymorph = decl->flags & AST_POLYMORPH; if (decl->flags & AST_POLYMORPH) continue;
if (is_polymorph) continue;
// @cleanup: Why I'm not calling resolve_decl here?
resolve_name(file, decl->pos, decl->name); resolve_name(file, decl->pos, decl->name);
if (decl->kind == AST_STRUCT || decl->kind == AST_UNION) type_complete(decl->type_val); if (decl->kind == AST_STRUCT || decl->kind == AST_UNION) type_complete(decl->type_val);
} }
} }

View File

@@ -358,11 +358,13 @@ enum {
AST_VAR_IS_CONST = 1 << 12, AST_VAR_IS_CONST = 1 << 12,
AST_OPERATOR_OVERLOAD = 1 << 13, AST_OPERATOR_OVERLOAD = 1 << 13,
AST_IS_LVALUE = 1 << 14, AST_IS_LVALUE = 1 << 14,
AST_IDENT_POLYMORPH = 1 << 15, AST_IDENT_POLYMORPH = 1 << 15,
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_TYPESPEC = 1 << 17, AST_TYPESPEC = 1 << 18,
}; };
struct Ast { struct Ast {

View File

@@ -927,8 +927,10 @@ parse_decl(B32 is_global) {
auto a = (Ast_Lambda *)expr; auto a = (Ast_Lambda *)expr;
if (a->scope || is_flag_set(flags, AST_FOREIGN)) { if (a->scope || is_flag_set(flags, AST_FOREIGN)) {
result->kind = AST_LAMBDA; result->kind = AST_LAMBDA;
if (is_flag_set(a->flags, AST_POLYMORPH)) if (is_flag_set(a->flags, AST_POLYMORPH)) {
set_flag(result->flags, AST_POLYMORPH); set_flag(result->flags, AST_POLYMORPH);
set_flag(result->flags, AST_PARENT_POLYMORPH);
}
if (is_flag_set(flags, AST_FOREIGN)) if (is_flag_set(flags, AST_FOREIGN))
set_flag(expr->flags, flags); set_flag(expr->flags, flags);
} }

View File

@@ -53,15 +53,15 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Ast_Decl *> *replace, Arr
Ast_Atom *src = (Ast_Atom *)ast; Ast_Atom *src = (Ast_Atom *)ast;
Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast); Ast_Atom *dst = ast_create_copy(parent_scope, Ast_Atom, ast);
if ((dst->flags & AST_TYPESPEC)) { if (replace && with && (dst->flags & AST_TYPESPEC)) {
For(*replace) { For(*replace) {
assert(it->type == pctx->type_type); assert(it->type == pctx->type_type);
if (it->name == dst->intern_val) { if (it->name == dst->intern_val) {
int it_index = replace->get_index(&it); int it_index = replace->get_index(&it);
Ast_Call_Item *replacement = with[0][it_index]; Ast_Call_Item *replacement = with[0][it_index];
Ast_Atom *replacement_v = (Ast_Atom *)replacement->item; Ast *replacement_v = replacement->item;
assert(replacement_v->resolved_type == pctx->type_type); // assert(replacement_v->resolved_type == pctx->type_type);
dst = ast_create_copy(parent_scope, Ast_Atom, replacement_v); dst = (Ast_Atom *)ast_copy(replacement_v, parent_scope, 0, 0);
} }
} }
} }
@@ -117,7 +117,7 @@ Ast *ast_copy(Ast *ast, Ast_Scope *parent_scope, Array<Ast_Decl *> *replace, Arr
dst->name = (Ast_Expr *)ast_copy(src->name, parent_scope, replace, with); dst->name = (Ast_Expr *)ast_copy(src->name, parent_scope, replace, with);
dst->exprs.init(pctx->perm, src->exprs.len); dst->exprs.init(pctx->perm, src->exprs.len);
For(dst->exprs) { For(src->exprs) {
auto copy = (Ast_Call_Item *)ast_copy(it, parent_scope, replace, with); auto copy = (Ast_Call_Item *)ast_copy(it, parent_scope, replace, with);
dst->exprs.add(copy); dst->exprs.add(copy);
} }

View File

@@ -1128,7 +1128,7 @@ unpack_ast_call_expr_for_builtin(Ast_Call *call) {
CORE_Static bool CORE_Static bool
expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern) { expr_atom_is_equal_intern(Ast_Expr *expr, Intern_String intern) {
assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY); assert(expr->kind == AST_IDENT || expr->kind == AST_BINARY || expr->kind == AST_VALUE);
if (expr->kind == AST_IDENT) { if (expr->kind == AST_IDENT) {
Ast_Atom *atom = (Ast_Atom *)expr; Ast_Atom *atom = (Ast_Atom *)expr;
if (atom->intern_val == intern) { if (atom->intern_val == intern) {
@@ -1565,22 +1565,27 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
else { else {
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope); Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
// // @cleanup: polymorphic structs probably shouldnt have types, not sure?
// Polymorphic instantiation
//
if (name.type == pctx->type_type) { if (name.type == pctx->type_type) {
if (name.type_val->kind != TYPE_POLYMORPH) { if (name.type_val->kind != TYPE_POLYMORPH) {
compiler_error(node->pos, "Parenthesis are not valid for types that are not polymorphic"); compiler_error(node->pos, "Parenthesis are not valid for types that are not polymorphic");
} }
Ast_Decl *poly = name.resolved_decl; }
assert(poly->flags & AST_POLYMORPH);
// node->exprs = params if (name.resolved_decl->flags & AST_POLYMORPH) {
assert(name.resolved_decl->flags & AST_PARENT_POLYMORPH);
Ast_Decl *poly = name.resolved_decl;
if (poly->kind == AST_LAMBDA) {
// Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope);
}
else {
Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope); Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope);
resolve_decl(instance); resolve_decl(instance);
type_complete(instance->type_val); type_complete(instance->type_val);
return operand_type(instance->type_val); return operand_type(instance->type_val);
} }
}
/* @todo: /* @todo:
We need an algorithm and other concretes for correct matching of arrays, var args and others. We need an algorithm and other concretes for correct matching of arrays, var args and others.
@@ -1729,6 +1734,7 @@ resolve_decl(Ast_Decl *ast) {
compiler_error(ast->pos, "Cyclic dependency of %s", ast->name.str); compiler_error(ast->pos, "Cyclic dependency of %s", ast->name.str);
return; return;
} }
if (ast->flags & AST_PARENT_POLYMORPH) return;
assert(ast->state == DECL_NOT_RESOLVED); assert(ast->state == DECL_NOT_RESOLVED);
ast->state = DECL_RESOLVING; ast->state = DECL_RESOLVING;

View File

@@ -47,9 +47,12 @@ MultipleArgs :: (): Tuple(int, F32)
return {32, 32} return {32, 32}
PolyLambda :: (value: $T): T PolyLambda :: (value: $T): T
pass return value
GetCount :: (a: int): int
return a
main :: (argc: int, argv: **char): int main :: (argc: int, argv: **char): int
buff: *int buff: *int
array: Array(int) = {len = 10, cap = 10, data = buff} array: Array(int) = {len = 10, cap = 10, data = buff}
@@ -57,8 +60,13 @@ main :: (argc: int, argv: **char): int
third_array: Array(int) third_array: Array(int)
fourth: Array(F32) fourth: Array(F32)
fifth: Array(F32) fifth: Array(F32)
sixth: Array(Array(F32))
// c := MakeArray(buff, GetCount(GetCount(32)))
// a,b := MultipleArgs() // a,b := MultipleArgs()
a := MultipleArgs() a := MultipleArgs()
// value := PolyLambda(32)
return 0 return 0