mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Separate out logic for checking mixture of named and unnamed parameters
This commit is contained in:
+38
-29
@@ -6849,6 +6849,34 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// returns true on failure
|
||||||
|
gb_internal bool check_call_parameter_mixture(Operand *operand, Slice<Ast *> const &args, char const *context) {
|
||||||
|
bool failure = false;
|
||||||
|
if (args.count > 0) {
|
||||||
|
bool first_is_field_value = (args[0]->kind == Ast_FieldValue);
|
||||||
|
for (Ast *arg : args) {
|
||||||
|
bool mix = false;
|
||||||
|
if (first_is_field_value) {
|
||||||
|
mix = arg->kind != Ast_FieldValue;
|
||||||
|
} else {
|
||||||
|
mix = arg->kind == Ast_FieldValue;
|
||||||
|
}
|
||||||
|
if (mix) {
|
||||||
|
error(arg, "Mixture of 'field = value' and value elements in a %s is not allowed", context);
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN(context_) if (check_call_parameter_mixture(operand, args, "procedure call")) { \
|
||||||
|
operand->mode = Addressing_Invalid; \
|
||||||
|
operand->expr = call; \
|
||||||
|
return Expr_Stmt; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice<Ast *> const &args, ProcInlining inlining, Type *type_hint) {
|
gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice<Ast *> const &args, ProcInlining inlining, Type *type_hint) {
|
||||||
if (proc != nullptr &&
|
if (proc != nullptr &&
|
||||||
@@ -6888,30 +6916,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.count > 0) {
|
|
||||||
bool fail = false;
|
|
||||||
bool first_is_field_value = (args[0]->kind == Ast_FieldValue);
|
|
||||||
for (Ast *arg : args) {
|
|
||||||
bool mix = false;
|
|
||||||
if (first_is_field_value) {
|
|
||||||
mix = arg->kind != Ast_FieldValue;
|
|
||||||
} else {
|
|
||||||
mix = arg->kind == Ast_FieldValue;
|
|
||||||
}
|
|
||||||
if (mix) {
|
|
||||||
error(arg, "Mixture of 'field = value' and value elements in a procedure call is not allowed");
|
|
||||||
fail = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fail) {
|
|
||||||
operand->mode = Addressing_Invalid;
|
|
||||||
operand->expr = call;
|
|
||||||
return Expr_Stmt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operand->mode == Addressing_Invalid) {
|
if (operand->mode == Addressing_Invalid) {
|
||||||
|
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
|
||||||
for (Ast *arg : args) {
|
for (Ast *arg : args) {
|
||||||
if (arg->kind == Ast_FieldValue) {
|
if (arg->kind == Ast_FieldValue) {
|
||||||
arg = arg->FieldValue.value;
|
arg = arg->FieldValue.value;
|
||||||
@@ -6926,6 +6932,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
if (operand->mode == Addressing_Type) {
|
if (operand->mode == Addressing_Type) {
|
||||||
Type *t = operand->type;
|
Type *t = operand->type;
|
||||||
if (is_type_polymorphic_record(t)) {
|
if (is_type_polymorphic_record(t)) {
|
||||||
|
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("polymorphic type construction");
|
||||||
|
|
||||||
if (!is_type_named(t)) {
|
if (!is_type_named(t)) {
|
||||||
gbString s = expr_to_string(operand->expr);
|
gbString s = expr_to_string(operand->expr);
|
||||||
error(call, "Illegal use of an unnamed polymorphic record, %s", s);
|
error(call, "Illegal use of an unnamed polymorphic record, %s", s);
|
||||||
@@ -6951,6 +6959,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
operand->type = t_invalid;
|
operand->type = t_invalid;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("type conversion");
|
||||||
|
|
||||||
operand->mode = Addressing_Invalid;
|
operand->mode = Addressing_Invalid;
|
||||||
isize arg_count = args.count;
|
isize arg_count = args.count;
|
||||||
switch (arg_count) {
|
switch (arg_count) {
|
||||||
@@ -6996,6 +7006,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (operand->mode == Addressing_Builtin) {
|
if (operand->mode == Addressing_Builtin) {
|
||||||
|
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("builtin call");
|
||||||
|
|
||||||
i32 id = operand->builtin_id;
|
i32 id = operand->builtin_id;
|
||||||
Entity *e = entity_of_node(operand->expr);
|
Entity *e = entity_of_node(operand->expr);
|
||||||
if (e != nullptr && e->token.string == "expand_to_tuple") {
|
if (e != nullptr && e->token.string == "expand_to_tuple") {
|
||||||
@@ -7009,6 +7021,8 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
return builtin_procs[id].kind;
|
return builtin_procs[id].kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
|
||||||
|
|
||||||
Entity *initial_entity = entity_of_node(operand->expr);
|
Entity *initial_entity = entity_of_node(operand->expr);
|
||||||
|
|
||||||
if (initial_entity != nullptr && initial_entity->kind == Entity_Procedure) {
|
if (initial_entity != nullptr && initial_entity->kind == Entity_Procedure) {
|
||||||
@@ -7095,7 +7109,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
if (decl->proc_lit) {
|
if (decl->proc_lit) {
|
||||||
ast_node(pl, ProcLit, decl->proc_lit);
|
ast_node(pl, ProcLit, decl->proc_lit);
|
||||||
if (pl->inlining == ProcInlining_no_inline) {
|
if (pl->inlining == ProcInlining_no_inline) {
|
||||||
error(call, "'inline' cannot be applied to a procedure that has be marked as 'no_inline'");
|
error(call, "'#force_inline' cannot be applied to a procedure that has be marked as '#force_no_inline'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7108,9 +7122,6 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
operand->expr = call;
|
operand->expr = call;
|
||||||
|
|
||||||
{
|
{
|
||||||
if (proc_type == t_invalid) {
|
|
||||||
// gb_printf_err("%s\n", expr_to_string(operand->expr));
|
|
||||||
}
|
|
||||||
Type *type = nullptr;
|
Type *type = nullptr;
|
||||||
if (operand->expr != nullptr && operand->expr->kind == Ast_CallExpr) {
|
if (operand->expr != nullptr && operand->expr->kind == Ast_CallExpr) {
|
||||||
type = type_of_expr(operand->expr->CallExpr.proc);
|
type = type_of_expr(operand->expr->CallExpr.proc);
|
||||||
@@ -7128,8 +7139,6 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add_type_and_value(c, operand->expr, operand->mode, operand->type, operand->value);
|
|
||||||
|
|
||||||
return Expr_Expr;
|
return Expr_Expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2777,8 +2777,6 @@ gb_internal Ast *parse_call_expr(AstFile *f, Ast *operand) {
|
|||||||
|
|
||||||
Ast *value = parse_value(f);
|
Ast *value = parse_value(f);
|
||||||
arg = ast_field_value(f, arg, value, eq);
|
arg = ast_field_value(f, arg, value, eq);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
array_add(&args, arg);
|
array_add(&args, arg);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user