Polymorphs nested structs
This commit is contained in:
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,21 +1565,26 @@ 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
|
||||
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);
|
||||
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:
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user