Environment[] olds = new Environment[size];
int i = 0;
if (!hasVarArgs && size != this.formals.size()) {
throw new MatchFailed();
}
if (size == 0) {
try {
bindKeywordArgs(keyArgValues);
result = runBody();
storeMemoizedResult(actuals,keyArgValues, result);
return result;
}
catch (Return e) {
result = computeReturn(e);
storeMemoizedResult(actuals,keyArgValues, result);
return result;
}
}
matchers[0].initMatch(makeResult(actualTypesTuple.getFieldType(0), actuals[0], ctx));
olds[0] = ctx.getCurrentEnvt();
ctx.pushEnv();
// pattern matching requires backtracking due to list, set and map matching and
// non-linear use of variables between formal parameters of a function...
while (i >= 0 && i < size) {
if (ctx.isInterrupted()) {
throw new InterruptException(ctx.getStackTrace(), currentAST.getLocation());
}
if (matchers[i].hasNext() && matchers[i].next()) {
if (i == size - 1) {
// formals are now bound by side effect of the pattern matcher
try {
bindKeywordArgs(keyArgValues);
result = runBody();
storeMemoizedResult(actuals,keyArgValues, result);
return result;
}
catch (Failure e) {
// backtrack current pattern assignment
if (!e.hasLabel() || e.hasLabel() && e.getLabel().equals(getName())) {
continue;
}
else {
throw new UnguardedFail(getAst(), e);
}
}
}
else {
i++;
matchers[i].initMatch(makeResult(actualTypesTuple.getFieldType(i), actuals[i], ctx));
olds[i] = ctx.getCurrentEnvt();
ctx.pushEnv();
}
} else {
ctx.unwind(olds[i]);
i--;
ctx.pushEnv();
}
}
// backtrack to other function body
throw new MatchFailed();
}
catch (Return e) {
result = computeReturn(e);
storeMemoizedResult(actuals,keyArgValues, result);
return result;