MatchResultPtr matchInvoke(OverloadPtr overload, ObjectPtr callable, llvm::ArrayRef<TypePtr> argsKey) { initializePatterns(overload); PatternReseter reseter(overload); if (!unifyPatternObj(overload->callablePattern, callable)) return new MatchCallableError(overload->target, callable); CodePtr code = overload->code; if (code->hasVarArg) { if (argsKey.size() < code->formalArgs.size()-1) return new MatchArityError(unsigned(code->formalArgs.size()), unsigned(argsKey.size()), true); } else { if (code->formalArgs.size() != argsKey.size()) return new MatchArityError(unsigned(code->formalArgs.size()), unsigned(argsKey.size()), false); } llvm::ArrayRef<FormalArgPtr> formalArgs = code->formalArgs; unsigned varArgSize = unsigned(argsKey.size()-formalArgs.size()+1); for (unsigned i = 0, j = 0; i < formalArgs.size(); ++i) { FormalArgPtr x = formalArgs[i]; if (x->varArg) { if (x->type.ptr()) { MultiStaticPtr types = new MultiStatic(); for (; j < varArgSize; ++j) types->add(argsKey[i+j].ptr()); --j; MultiPatternPtr pattern = overload->varArgPattern; if (!unifyMulti(pattern, types)) return new MatchMultiArgumentError(unsigned(formalArgs.size()), types, x); } else { j = varArgSize-1; } } else { if (x->type.ptr()) { PatternPtr pattern = overload->argPatterns[i]; if (!unifyPatternObj(pattern, argsKey[i+j].ptr())) return new MatchArgumentError(i+j, argsKey[i+j], x); } } } EnvPtr staticEnv = new Env(overload->env); llvm::ArrayRef<PatternVar> pvars = code->patternVars; for (size_t i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiStaticPtr ms = derefDeep(overload->multiCells[i].ptr()); if (!ms) error(pvars[i].name, "unbound pattern variable"); addLocal(staticEnv, pvars[i].name, ms.ptr()); } else { ObjectPtr v = derefDeep(overload->cells[i].ptr()); if (!v) error(pvars[i].name, "unbound pattern variable"); addLocal(staticEnv, pvars[i].name, v.ptr()); } } reseter.reset(); if (code->predicate.ptr()) if (!evaluateBool(code->predicate, staticEnv)) return new MatchPredicateError(code->predicate); MatchSuccessPtr result = new MatchSuccess( overload, staticEnv, callable, argsKey ); for (unsigned i = 0, j = 0; i < formalArgs.size(); ++i) { FormalArgPtr x = formalArgs[i]; if (x->varArg) { result->varArgName = x->name; result->varArgPosition = i; for (; j < varArgSize; ++j) { result->varArgTypes.push_back(argsKey[i+j]); } --j; } else { result->fixedArgNames.push_back(x->name); result->fixedArgTypes.push_back(argsKey[i+j]); } } if(!code->hasVarArg) result->varArgPosition = unsigned(result->fixedArgNames.size()); return result.ptr(); }
MatchResultPtr matchInvoke(OverloadPtr overload, ObjectPtr callable, const vector<TypePtr> &argsKey) { initializePatterns(overload); PatternReseter reseter(overload); if (!unifyPatternObj(overload->callablePattern, callable)) return new MatchCallableError(overload->target, callable); CodePtr code = overload->code; if (code->formalVarArg.ptr()) { if (argsKey.size() < code->formalArgs.size()) return new MatchArityError(code->formalArgs.size(), argsKey.size(), true); } else { if (code->formalArgs.size() != argsKey.size()) return new MatchArityError(code->formalArgs.size(), argsKey.size(), false); } const vector<FormalArgPtr> &formalArgs = code->formalArgs; for (unsigned i = 0; i < formalArgs.size(); ++i) { FormalArgPtr x = formalArgs[i]; if (x->type.ptr()) { PatternPtr pattern = overload->argPatterns[i]; if (!unifyPatternObj(pattern, argsKey[i].ptr())) return new MatchArgumentError(i, argsKey[i], x); } } if (code->formalVarArg.ptr() && code->formalVarArg->type.ptr()) { MultiStaticPtr types = new MultiStatic(); for (unsigned i = formalArgs.size(); i < argsKey.size(); ++i) types->add(argsKey[i].ptr()); if (!unifyMulti(overload->varArgPattern, types)) return new MatchMultiArgumentError(formalArgs.size(), types, code->formalVarArg); } EnvPtr staticEnv = new Env(overload->env); const vector<PatternVar> &pvars = code->patternVars; for (unsigned i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiStaticPtr ms = derefDeep(overload->multiCells[i].ptr()); if (!ms) error(pvars[i].name, "unbound pattern variable"); addLocal(staticEnv, pvars[i].name, ms.ptr()); } else { ObjectPtr v = derefDeep(overload->cells[i].ptr()); if (!v) error(pvars[i].name, "unbound pattern variable"); addLocal(staticEnv, pvars[i].name, v.ptr()); } } reseter.reset(); if (code->predicate.ptr()) { if (!evaluateBool(code->predicate, staticEnv)) return new MatchPredicateError(code->predicate); } MatchSuccessPtr result = new MatchSuccess( overload->callByName, overload->isInline, code, staticEnv, callable, argsKey ); for (unsigned i = 0; i < formalArgs.size(); ++i) { FormalArgPtr x = formalArgs[i]; result->fixedArgNames.push_back(x->name); result->fixedArgTypes.push_back(argsKey[i]); } if (code->formalVarArg.ptr()) { result->varArgName = code->formalVarArg->name; for (unsigned i = formalArgs.size(); i < argsKey.size(); ++i) { result->varArgTypes.push_back(argsKey[i]); } } return result.ptr(); }