aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-06-14 14:56:33 +0100
committergingerBill <bill@gingerbill.org>2023-06-14 14:56:33 +0100
commitc66ac9725ee89df82b70a1109ee1988360d5ab6d (patch)
treea955bec2d28a28d6adf1916098da89f2c7c41697 /src/check_expr.cpp
parentfeacc5cd1176f93fc4b52c081d8ad93ed391df00 (diff)
Separate out logic for checking mixture of named and unnamed parameters
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp67
1 files changed, 38 insertions, 29 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index c6b332cde..d3e287ba4 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -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) {
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) {
+ CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
for (Ast *arg : args) {
if (arg->kind == Ast_FieldValue) {
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) {
Type *t = operand->type;
if (is_type_polymorphic_record(t)) {
+ CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("polymorphic type construction");
+
if (!is_type_named(t)) {
gbString s = expr_to_string(operand->expr);
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;
}
} else {
+ CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("type conversion");
+
operand->mode = Addressing_Invalid;
isize arg_count = args.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) {
+ CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("builtin call");
+
i32 id = operand->builtin_id;
Entity *e = entity_of_node(operand->expr);
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;
}
+ CHECK_CALL_PARAMETER_MIXTURE_OR_RETURN("procedure call");
+
Entity *initial_entity = entity_of_node(operand->expr);
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) {
ast_node(pl, ProcLit, decl->proc_lit);
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;
{
- if (proc_type == t_invalid) {
- // gb_printf_err("%s\n", expr_to_string(operand->expr));
- }
Type *type = nullptr;
if (operand->expr != nullptr && operand->expr->kind == Ast_CallExpr) {
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;
}