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) {
|
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)) {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user