mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-02 03:02:37 +00:00
Basic polymorphic named procedure parameters for procedures and records
This commit is contained in:
@@ -1117,6 +1117,9 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
|
||||
e->flags |= EntityFlag_Used;
|
||||
|
||||
Type *type = e->type;
|
||||
|
||||
o->type = type;
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_Constant:
|
||||
if (type == t_invalid) {
|
||||
@@ -1127,6 +1130,14 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
|
||||
if (o->value.kind == ExactValue_Invalid) {
|
||||
return e;
|
||||
}
|
||||
if (o->value.kind == ExactValue_Procedure) {
|
||||
Entity *proc = strip_entity_wrapping(o->value.value_procedure);
|
||||
if (proc != nullptr) {
|
||||
o->mode = Addressing_Value;
|
||||
o->type = proc->type;
|
||||
return proc;
|
||||
}
|
||||
}
|
||||
o->mode = Addressing_Constant;
|
||||
break;
|
||||
|
||||
@@ -1144,6 +1155,7 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
|
||||
|
||||
case Entity_Procedure:
|
||||
o->mode = Addressing_Value;
|
||||
o->value = exact_value_procedure(n);
|
||||
break;
|
||||
|
||||
case Entity_Builtin:
|
||||
@@ -1180,7 +1192,6 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ
|
||||
break;
|
||||
}
|
||||
|
||||
o->type = type;
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -3602,10 +3613,20 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
|
||||
|
||||
add_entity_use(c, selector, entity);
|
||||
|
||||
operand->type = entity->type;
|
||||
operand->expr = node;
|
||||
|
||||
switch (entity->kind) {
|
||||
case Entity_Constant:
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = entity->Constant.value;
|
||||
operand->mode = Addressing_Constant;
|
||||
if (operand->value.kind == ExactValue_Procedure) {
|
||||
Entity *proc = strip_entity_wrapping(operand->value.value_procedure);
|
||||
if (proc != nullptr) {
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = proc->type;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Entity_Variable:
|
||||
// TODO(bill): Is this the rule I need?
|
||||
@@ -3628,6 +3649,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
|
||||
break;
|
||||
case Entity_Procedure:
|
||||
operand->mode = Addressing_Value;
|
||||
operand->value = exact_value_procedure(node);
|
||||
break;
|
||||
case Entity_Builtin:
|
||||
operand->mode = Addressing_Builtin;
|
||||
@@ -3645,8 +3667,7 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
|
||||
break;
|
||||
}
|
||||
|
||||
operand->type = entity->type;
|
||||
operand->expr = node;
|
||||
add_type_and_value(c->info, operand->expr, operand->mode, operand->type, operand->value);
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -7044,10 +7065,17 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper
|
||||
}
|
||||
o->type = e->type;
|
||||
if (o->mode != Addressing_Constant) {
|
||||
if (show_error) {
|
||||
error(o->expr, "Expected a constant value for this polymorphic type argument");
|
||||
bool valid = false;
|
||||
if (is_type_proc(o->type)) {
|
||||
Entity *proc_entity = entity_from_expr(o->expr);
|
||||
valid = proc_entity != nullptr;
|
||||
}
|
||||
if (!valid) {
|
||||
if (show_error) {
|
||||
error(o->expr, "Expected a constant value for this polymorphic type argument");
|
||||
}
|
||||
err = CallArgumentError_NoneConstantParameter;
|
||||
}
|
||||
err = CallArgumentError_NoneConstantParameter;
|
||||
}
|
||||
score += s;
|
||||
}
|
||||
@@ -9257,29 +9285,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
|
||||
ExprKind check_expr_base(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) {
|
||||
ExprKind kind = check_expr_base_internal(c, o, node, type_hint);
|
||||
Type *type = nullptr;
|
||||
ExactValue value = {ExactValue_Invalid};
|
||||
switch (o->mode) {
|
||||
case Addressing_Invalid:
|
||||
type = t_invalid;
|
||||
break;
|
||||
case Addressing_NoValue:
|
||||
type = nullptr;
|
||||
break;
|
||||
case Addressing_Constant:
|
||||
value = o->value;
|
||||
type = o->type;
|
||||
break;
|
||||
default:
|
||||
type = o->type;
|
||||
break;
|
||||
if (o->type != nullptr && is_type_untyped(o->type)) {
|
||||
add_untyped(&c->checker->info, node, false, o->mode, o->type, o->value);
|
||||
}
|
||||
|
||||
if (type != nullptr && is_type_untyped(type)) {
|
||||
add_untyped(&c->checker->info, node, false, o->mode, type, value);
|
||||
}
|
||||
add_type_and_value(&c->checker->info, node, o->mode, type, value);
|
||||
|
||||
add_type_and_value(&c->checker->info, node, o->mode, o->type, o->value);
|
||||
return kind;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user