Constant polymorphic names

This commit is contained in:
gingerBill
2018-09-10 14:21:19 +01:00
parent 4c4de1d6c4
commit 46b1868185
2 changed files with 46 additions and 5 deletions

View File

@@ -489,6 +489,23 @@ parametric_polymorphism :: proc() {
r = Error.Foo0;
fmt.println(r);
}
{ // Polymorphic names
foo :: proc($N: $I, $T: typeid) -> (res: [N]T) {
fmt.printf("Generating an array of type %v from the value %v of type %v\n",
typeid_of(type_of(res)), N, typeid_of(I));
for i in 0..N-1 {
res[i] = i*i;
}
return;
}
T :: int;
array := foo(4, T);
for v, i in array {
assert(v == T(i*i));
}
}
}
@@ -794,7 +811,6 @@ diverging_procedures :: proc() {
foo();
}
main :: proc() {
when true {
general_stuff();

View File

@@ -1467,7 +1467,10 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
if (type != nullptr && type_expr->kind == Ast_TypeidType) {
is_type_param = true;
} else {
error(name, "Polymorphic names are not yet supported for non-typeid parameters");
if (param_value.kind != ParameterValue_Invalid) {
error(default_value, "Constant parameters cannot have a default value");
param_value.kind = ParameterValue_Invalid;
}
}
}
@@ -1514,9 +1517,12 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
param = alloc_entity_type_name(scope, name->Ident.token, type, EntityState_Resolved);
param->TypeName.is_type_alias = true;
} else {
ExactValue poly_const = {};
if (operands != nullptr && variables.count < operands->count) {
Operand op = (*operands)[variables.count];
if (is_type_polymorphic_type) {
Operand op = (*operands)[variables.count];
type = determine_type_from_polymorphic(ctx, type, op);
if (type == t_invalid) {
success = false;
@@ -1525,6 +1531,13 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
is_type_polymorphic_type = false;
}
}
if (is_poly_name) {
if (op.mode == Addressing_Constant) {
poly_const = op.value;
} else {
success = false;
}
}
}
if (p->flags&FieldFlag_no_alias) {
@@ -1533,9 +1546,21 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
p->flags &= ~FieldFlag_no_alias; // Remove the flag
}
}
if (is_poly_name) {
if (p->flags&FieldFlag_no_alias) {
error(name, "'#no_alias' can only be applied to non constant values");
p->flags &= ~FieldFlag_no_alias; // Remove the flag
}
if (p->flags&FieldFlag_auto_cast) {
error(name, "'auto_cast' can only be applied to variable fields");
p->flags &= ~FieldFlag_auto_cast;
}
param = alloc_entity_param(scope, name->Ident.token, type, is_using, is_in);
param->Variable.param_value = param_value;
param = alloc_entity_const_param(scope, name->Ident.token, type, poly_const, is_type_polymorphic(type));
} else {
param = alloc_entity_param(scope, name->Ident.token, type, is_using, is_in);
param->Variable.param_value = param_value;
}
}
if (p->flags&FieldFlag_no_alias) {
param->flags |= EntityFlag_NoAlias;