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 {
@@ -509,7 +511,7 @@ struct Ast_For : Ast {
struct Ast_Lambda : Ast_Expr { struct Ast_Lambda : Ast_Expr {
Array<Ast_Decl *> args; Array<Ast_Decl *> args;
// :Multiple arguments // :Multiple arguments
// @todo: maybe disallow multiple arguments in current form // @todo: maybe disallow multiple arguments in current form
// and use polimorphism. Then we could make var unpacking, // and use polimorphism. Then we could make var unpacking,

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,21 +1565,26 @@ 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) {
Ast_Decl *instance = get_or_instantiate_polymorph_type(node->pos, poly, node->exprs, field_access_scope); assert(name.resolved_decl->flags & AST_PARENT_POLYMORPH);
resolve_decl(instance); Ast_Decl *poly = name.resolved_decl;
type_complete(instance->type_val);
return operand_type(instance->type_val); 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: /* @todo:
@@ -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