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) {
result->polymorph_parameters = polymorph_parameters;
set_flag(result->flags, AST_POLYMORPH);
set_flag(result->flags, AST_PARENT_POLYMORPH);
result->polymorphs.allocator = pctx->heap;
}
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
is_typespec_polymorphic(Ast *ast) {
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();
For_Named(module->all_loaded_files, file) {
For_Named(file->decls, decl) {
bool is_polymorph = decl->flags & AST_POLYMORPH;
if (is_polymorph) continue;
if (decl->flags & AST_POLYMORPH) continue;
// @cleanup: Why I'm not calling resolve_decl here?
resolve_name(file, decl->pos, decl->name);
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_OPERATOR_OVERLOAD = 1 << 13,
AST_IS_LVALUE = 1 << 14,
AST_IDENT_POLYMORPH = 1 << 15,
AST_TYPE_POLYMORPH = 1 << 16,
AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH,
AST_PARENT_POLYMORPH = 1 << 17,
AST_TYPESPEC = 1 << 17,
AST_TYPESPEC = 1 << 18,
};
struct Ast {

View File

@@ -927,8 +927,10 @@ parse_decl(B32 is_global) {
auto a = (Ast_Lambda *)expr;
if (a->scope || is_flag_set(flags, AST_FOREIGN)) {
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_PARENT_POLYMORPH);
}
if (is_flag_set(flags, AST_FOREIGN))
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 *dst = ast_create_copy(parent_scope, Ast_Atom, ast);
if ((dst->flags & AST_TYPESPEC)) {
if (replace && with && (dst->flags & AST_TYPESPEC)) {
For(*replace) {
assert(it->type == pctx->type_type);
if (it->name == dst->intern_val) {
int it_index = replace->get_index(&it);
Ast_Call_Item *replacement = with[0][it_index];
Ast_Atom *replacement_v = (Ast_Atom *)replacement->item;
assert(replacement_v->resolved_type == pctx->type_type);
dst = ast_create_copy(parent_scope, Ast_Atom, replacement_v);
Ast *replacement_v = replacement->item;
// assert(replacement_v->resolved_type == pctx->type_type);
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->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);
dst->exprs.add(copy);
}

View File

@@ -1128,7 +1128,7 @@ unpack_ast_call_expr_for_builtin(Ast_Call *call) {
CORE_Static bool
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) {
Ast_Atom *atom = (Ast_Atom *)expr;
if (atom->intern_val == intern) {
@@ -1565,22 +1565,27 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
else {
Operand name = resolve_expr(node->name, inherit_flag(flags, AST_CANT_BE_NULL), 0, field_access_scope);
//
// Polymorphic instantiation
//
// @cleanup: polymorphic structs probably shouldnt have types, not sure?
if (name.type == pctx->type_type) {
if (name.type_val->kind != TYPE_POLYMORPH) {
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);
resolve_decl(instance);
type_complete(instance->type_val);
return operand_type(instance->type_val);
}
}
/* @todo:
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);
return;
}
if (ast->flags & AST_PARENT_POLYMORPH) return;
assert(ast->state == DECL_NOT_RESOLVED);
ast->state = DECL_RESOLVING;

View File

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