aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.cpp
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-24 22:58:50 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-24 22:58:50 +0100
commit1d81b73df9922f0d3006a2d8031bf44f88573224 (patch)
tree73d0a4686a0cb8bf20cdb385a9729ff8a09902fa /src/check_expr.cpp
parent18f885efabb98fb91ab0c6e9586a8b66eab511d9 (diff)
Basic command line flags: e.g. `-opt=0`
Diffstat (limited to 'src/check_expr.cpp')
-rw-r--r--src/check_expr.cpp53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 33e323644..af2f2ad4c 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -4840,6 +4840,7 @@ enum CallArgumentError {
CallArgumentError_ParameterNotFound,
CallArgumentError_ParameterMissing,
CallArgumentError_DuplicateParameter,
+ CallArgumentError_GenericProcedureNotSupported,
};
enum CallArgumentErrorMode {
@@ -5010,6 +5011,8 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
} else if (o.mode != Addressing_Type) {
error(o.expr, "Expected a type for the argument");
}
+
+ score += assign_score_function(1);
continue;
}
if (variadic) {
@@ -5150,7 +5153,7 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
} else if (o->mode != Addressing_Type) {
error(o->expr, "Expected a type for the argument");
}
- score += 1;
+ score += assign_score_function(1);
} else {
i64 s = 0;
if (!check_is_assignable_to_with_score(c, o, e->type, &s)) {
@@ -5197,6 +5200,13 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
}
#endif
+ if (pt->is_generic) {
+ if (show_error) {
+ error(call, "Generic procedures do not yet support named arguments");
+ }
+ err = CallArgumentError_GenericProcedureNotSupported;
+ }
+
if (score_) *score_ = score;
return err;
@@ -5210,6 +5220,8 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
Array<Operand> operands = {};
defer (array_free(&operands));
+ Type *result_type = t_invalid;
+
if (is_call_expr_field_value(ce)) {
call_checker = check_named_call_arguments;
@@ -5252,10 +5264,10 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
for (isize i = 0; i < overload_count; i++) {
Entity *p = procs[i];
- Type *proc_type = base_type(p->type);
- if (proc_type != NULL && is_type_proc(proc_type)) {
+ Type *pt = base_type(p->type);
+ if (pt != NULL && is_type_proc(pt)) {
i64 score = 0;
- CallArgumentError err = call_checker(c, call, proc_type, operands, CallArgumentMode_NoErrors, &score);
+ CallArgumentError err = call_checker(c, call, pt, operands, CallArgumentMode_NoErrors, &score);
if (err == CallArgumentError_None) {
valids[valid_count].index = i;
valids[valid_count].score = score;
@@ -5279,7 +5291,7 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
if (valid_count == 0) {
error(operand->expr, "No overloads for `%.*s` that match with the given arguments", LIT(name));
- proc_type = t_invalid;
+ result_type = t_invalid;
} else if (valid_count > 1) {
error(operand->expr, "Ambiguous procedure call `%.*s`, could be:", LIT(name));
for (isize i = 0; i < valid_count; i++) {
@@ -5289,7 +5301,7 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
gb_printf_err("\t%.*s of type %s at %.*s(%td:%td) with score %lld\n", LIT(name), pt, LIT(pos.file), pos.line, pos.column, cast(long long)valids[i].score);
gb_string_free(pt);
}
- proc_type = t_invalid;
+ result_type = t_invalid;
} else {
AstNode *expr = operand->expr;
while (expr->kind == AstNode_SelectorExpr) {
@@ -5301,14 +5313,20 @@ Type *check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNod
proc_type = e->type;
i64 score = 0;
CallArgumentError err = call_checker(c, call, proc_type, operands, CallArgumentMode_ShowErrors, &score);
+
+ if (proc_type != NULL && is_type_proc(proc_type)) {
+ result_type = base_type(proc_type)->Proc.results;
+ }
}
} else {
i64 score = 0;
CallArgumentError err = call_checker(c, call, proc_type, operands, CallArgumentMode_ShowErrors, &score);
+ if (proc_type != NULL && is_type_proc(proc_type)) {
+ result_type = base_type(proc_type)->Proc.results;
+ }
}
-
- return proc_type;
+ return result_type;
}
@@ -5443,36 +5461,39 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
}
}
- proc_type = check_call_arguments(c, operand, proc_type, call);
+ Type *result_type = check_call_arguments(c, operand, proc_type, call);
gb_zero_item(operand);
+ operand->expr = call;
- Type *pt = base_type(proc_type);
- if (pt == NULL || !is_type_proc(pt)) {
+ if (result_type == t_invalid) {
operand->mode = Addressing_Invalid;
operand->type = t_invalid;
- operand->expr = call;
return Expr_Stmt;
}
+ Type *pt = base_type(proc_type);
bool results_are_generic = false;
- if (pt->Proc.results != NULL) {
+ if (is_type_proc(pt) && pt->Proc.results != NULL) {
results_are_generic = is_type_generic(pt->Proc.results);
}
if (results_are_generic) {
operand->mode = Addressing_NoValue;
+ } else if (result_type == NULL) {
+ operand->mode = Addressing_NoValue;
} else {
- switch (pt->Proc.result_count) {
+ GB_ASSERT(is_type_tuple(result_type));
+ switch (result_type->Tuple.variable_count) {
case 0:
operand->mode = Addressing_NoValue;
break;
case 1:
operand->mode = Addressing_Value;
- operand->type = pt->Proc.results->Tuple.variables[0]->type;
+ operand->type = result_type->Tuple.variables[0]->type;
break;
default:
operand->mode = Addressing_Value;
- operand->type = pt->Proc.results;
+ operand->type = result_type;
break;
}
}