static void initVariantInstance(InstancePtr x) { EnvPtr env = new Env(x->env); const vector<PatternVar> &pvars = x->patternVars; for (unsigned i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiPatternCellPtr cell = new MultiPatternCell(NULL); addLocal(env, pvars[i].name, cell.ptr()); } else { PatternCellPtr cell = new PatternCell(NULL); addLocal(env, pvars[i].name, cell.ptr()); } } PatternPtr pattern = evaluateOnePattern(x->target, env); ObjectPtr y = derefDeep(pattern); if (y.ptr()) { if (y->objKind != TYPE) error(x->target, "not a variant type"); Type *z = (Type *)y.ptr(); if (z->typeKind != VARIANT_TYPE) error(x->target, "not a variant type"); VariantType *vt = (VariantType *)z; vt->variant->instances.push_back(x); } else { if (pattern->kind != PATTERN_STRUCT) error(x->target, "not a variant type"); PatternStruct *ps = (PatternStruct *)pattern.ptr(); if ((!ps->head) || (ps->head->objKind != VARIANT)) error(x->target, "not a variant type"); Variant *v = (Variant *)ps->head.ptr(); v->instances.push_back(x); } }
void convertFreeVars(LambdaPtr x, EnvPtr env, const string &closureDataName, vector<string> &freeVars) { EnvPtr env2 = new Env(env); for (unsigned i = 0; i < x->formalArgs.size(); ++i) { FormalArgPtr arg = x->formalArgs[i]; addLocal(env2, arg->name, arg->name.ptr()); } if (x->formalVarArg.ptr()) { addLocal(env2, x->formalVarArg->name, x->formalVarArg->name.ptr()); } LambdaContext ctx(x->captureByRef, env, closureDataName, freeVars); convertFreeVars(x->body, env2, ctx); }
static EnvPtr overloadPatternEnv(OverloadPtr x) { EnvPtr env = new Env(x->env); llvm::ArrayRef<PatternVar> pvars = x->code->patternVars; for (unsigned i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiPatternCellPtr cell = new MultiPatternCell(NULL); addLocal(env, pvars[i].name, cell.ptr()); } else { PatternCellPtr cell = new PatternCell(NULL); addLocal(env, pvars[i].name, cell.ptr()); } } return env; }
static void initializePatterns(OverloadPtr x) { if (x->patternsInitializedState == 1) return; if (x->patternsInitializedState == -1) error("unholy recursion detected"); assert(x->patternsInitializedState == 0); x->patternsInitializedState = -1; CodePtr code = x->code; const vector<PatternVar> &pvars = code->patternVars; x->patternEnv = new Env(x->env); for (unsigned i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiPatternCellPtr multiCell = new MultiPatternCell(NULL); x->multiCells.push_back(multiCell); x->cells.push_back(NULL); addLocal(x->patternEnv, pvars[i].name, multiCell.ptr()); } else { PatternCellPtr cell = new PatternCell(NULL); x->cells.push_back(cell); x->multiCells.push_back(NULL); addLocal(x->patternEnv, pvars[i].name, cell.ptr()); } } assert(x->target.ptr()); x->callablePattern = evaluateOnePattern(x->target, x->patternEnv); const vector<FormalArgPtr> &formalArgs = code->formalArgs; for (unsigned i = 0; i < formalArgs.size(); ++i) { FormalArgPtr y = formalArgs[i]; PatternPtr pattern; if (y->type.ptr()) pattern = evaluateOnePattern(y->type, x->patternEnv); x->argPatterns.push_back(pattern); } if (code->formalVarArg.ptr() && code->formalVarArg->type.ptr()) { ExprPtr unpack = new Unpack(code->formalVarArg->type.ptr()); unpack->location = code->formalVarArg->type->location; x->varArgPattern = evaluateMultiPattern(new ExprList(unpack), x->patternEnv); } x->patternsInitializedState = 1; }
void ClosureExpression::analyzeVarsForClosureExpression( AnalysisResultConstRawPtr /*ar*/) { auto const containing = getFunctionScope(); for (auto const& var : *m_vars) { auto const param = dynamic_pointer_cast<ParameterExpression>(var); containing->addLocal(param->getName()); } }
void initializePatternEnv(EnvPtr patternEnv, llvm::ArrayRef<PatternVar> pvars, vector<PatternCellPtr> &cells, vector<MultiPatternCellPtr> &multiCells) { for (size_t i = 0; i < pvars.size(); ++i) { if (pvars[i].isMulti) { MultiPatternCellPtr multiCell = new MultiPatternCell(NULL); multiCells.push_back(multiCell); cells.push_back(NULL); addLocal(patternEnv, pvars[i].name, multiCell.ptr()); } else { PatternCellPtr cell = new PatternCell(NULL); cells.push_back(cell); multiCells.push_back(NULL); addLocal(patternEnv, pvars[i].name, cell.ptr()); } } }
Info & Block::addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp) { addLocal(Lsym, Rtype, /* isIntIterator */ false); Info & Linfo = putAndClear(Lsym, exp); Info & Rinfo = putSymsInScope(Rsym); Linfo.cleared = false; Linfo.type = Rtype; Linfo.data = Rinfo.data; Linfo.isint = Rinfo.isint; Linfo.data->add(Lsym); Linfo.exists = true; return Linfo; }
Info & Block::addDefine(const symbol::Symbol & sym, const TIType & Rtype, const bool isIntIterator, ast::Exp * exp) { /* DEFINE: - if associated data is shared then we need to clone it */ addLocal(sym, Rtype, isIntIterator); Info & info = putAndClear(sym, exp); info.cleared = false; info.data = new Data(true, sym); info.type = Rtype; info.exists = true; dm->registerData(info.data);//, __LINE__, __FILE__); return info; }
static void initializeVariantType(VariantTypePtr t) { assert(!t->initialized); EnvPtr variantEnv = new Env(t->variant->env); { const vector<IdentifierPtr> ¶ms = t->variant->params; IdentifierPtr varParam = t->variant->varParam; assert(params.size() <= t->params.size()); for (unsigned j = 0; j < params.size(); ++j) addLocal(variantEnv, params[j], t->params[j]); if (varParam.ptr()) { MultiStaticPtr ms = new MultiStatic(); for (unsigned j = params.size(); j < t->params.size(); ++j) ms->add(t->params[j]); addLocal(variantEnv, varParam, ms.ptr()); } else { assert(params.size() == t->params.size()); } } ExprListPtr defaultInstances = t->variant->defaultInstances; for (unsigned i = 0; i < defaultInstances->size(); ++i) { ExprPtr x = defaultInstances->exprs[i]; TypePtr memberType = evaluateType(x, variantEnv); t->memberTypes.push_back(memberType); } const vector<InstancePtr> &instances = t->variant->instances; for (unsigned i = 0; i < instances.size(); ++i) { InstancePtr x = instances[i]; vector<PatternCellPtr> cells; vector<MultiPatternCellPtr> multiCells; const vector<PatternVar> &pvars = x->patternVars; EnvPtr patternEnv = new Env(x->env); for (unsigned j = 0; j < pvars.size(); ++j) { if (pvars[j].isMulti) { MultiPatternCellPtr multiCell = new MultiPatternCell(NULL); multiCells.push_back(multiCell); cells.push_back(NULL); addLocal(patternEnv, pvars[j].name, multiCell.ptr()); } else { PatternCellPtr cell = new PatternCell(NULL); cells.push_back(cell); multiCells.push_back(NULL); addLocal(patternEnv, pvars[j].name, cell.ptr()); } } PatternPtr pattern = evaluateOnePattern(x->target, patternEnv); if (!unifyPatternObj(pattern, t.ptr())) continue; EnvPtr staticEnv = new Env(x->env); for (unsigned j = 0; j < pvars.size(); ++j) { if (pvars[j].isMulti) { MultiStaticPtr ms = derefDeep(multiCells[j].ptr()); if (!ms) error(pvars[j].name, "unbound pattern variable"); addLocal(staticEnv, pvars[j].name, ms.ptr()); } else { ObjectPtr v = derefDeep(cells[j].ptr()); if (!v) error(pvars[j].name, "unbound pattern variable"); addLocal(staticEnv, pvars[j].name, v.ptr()); } } if (x->predicate.ptr()) if (!evaluateBool(x->predicate, staticEnv)) continue; TypePtr memberType = evaluateType(x->member, staticEnv); t->memberTypes.push_back(memberType); } RecordPtr reprRecord = getVariantReprRecord(); vector<ObjectPtr> params; for (unsigned i = 0; i < t->memberTypes.size(); ++i) params.push_back(t->memberTypes[i].ptr()); t->reprType = recordType(reprRecord, params); t->initialized = true; }
void initializeRecordFields(RecordTypePtr t) { assert(!t->fieldsInitialized); t->fieldsInitialized = true; RecordPtr r = t->record; if (r->varParam.ptr()) assert(t->params.size() >= r->params.size()); else assert(t->params.size() == r->params.size()); EnvPtr env = new Env(r->env); for (unsigned i = 0; i < r->params.size(); ++i) addLocal(env, r->params[i], t->params[i].ptr()); if (r->varParam.ptr()) { MultiStaticPtr rest = new MultiStatic(); for (unsigned i = r->params.size(); i < t->params.size(); ++i) rest->add(t->params[i]); addLocal(env, r->varParam, rest.ptr()); } RecordBodyPtr body = r->body; if (body->isComputed) { LocationContext loc(body->location); AnalysisCachingDisabler disabler; MultiPValuePtr mpv = analyzeMulti(body->computed, env); vector<TypePtr> fieldInfoTypes; if ((mpv->size() == 1) && (mpv->values[0]->type->typeKind == RECORD_TYPE) && (((RecordType *)mpv->values[0]->type.ptr())->record.ptr() == prelude_RecordWithProperties().ptr())) { const vector<ObjectPtr> ¶ms = ((RecordType *)mpv->values[0]->type.ptr())->params; assert(params.size() == 2); if (params[0]->objKind != TYPE) argumentError(0, "expecting a tuple of properties"); TypePtr param0 = (Type *)params[0].ptr(); if (param0->typeKind != TUPLE_TYPE) argumentError(0, "expecting a tuple of properties"); TupleTypePtr props = (TupleType *)param0.ptr(); if (params[1]->objKind != TYPE) argumentError(1, "expecting a tuple of fields"); TypePtr param1 = (Type *)params[1].ptr(); if (param1->typeKind != TUPLE_TYPE) argumentError(1, "expecting a tuple of fields"); TupleTypePtr fields = (TupleType *)param1.ptr(); fieldInfoTypes = fields->elementTypes; setProperties(t.ptr(), props->elementTypes); } else { for (unsigned i = 0; i < mpv->size(); ++i) fieldInfoTypes.push_back(mpv->values[i]->type); } for (unsigned i = 0; i < fieldInfoTypes.size(); ++i) { TypePtr x = fieldInfoTypes[i]; IdentifierPtr name; TypePtr type; if (!unpackField(x, name, type)) argumentError(i, "each field should be a " "tuple of (name,type)"); t->fieldIndexMap[name->str] = i; t->fieldTypes.push_back(type); t->fieldNames.push_back(name); } } else { for (unsigned i = 0; i < body->fields.size(); ++i) { RecordField *x = body->fields[i].ptr(); t->fieldIndexMap[x->name->str] = i; TypePtr ftype = evaluateType(x->type, env); t->fieldTypes.push_back(ftype); t->fieldNames.push_back(x->name); } } }
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(); }
void convertFreeVars(ExprPtr &x, EnvPtr env, LambdaContext &ctx) { switch (x->exprKind) { case BOOL_LITERAL : case INT_LITERAL : case FLOAT_LITERAL : case CHAR_LITERAL : case STRING_LITERAL : case IDENTIFIER_LITERAL : break; case NAME_REF : { NameRef *y = (NameRef *)x.ptr(); bool isNonLocal = false; bool isGlobal = false; ObjectPtr z = lookupEnvEx(env, y->name, ctx.nonLocalEnv, isNonLocal, isGlobal); if (isNonLocal && !isGlobal) { if ((z->objKind == PVALUE) || (z->objKind == CVALUE)) { TypePtr t = typeOfValue(z); if (isStaticOrTupleOfStatics(t)) { ExprListPtr args = new ExprList(); args->add(new ObjectExpr(t.ptr())); CallPtr call = new Call(operator_expr_typeToRValue(), args); call->location = y->location; x = call.ptr(); } else { addFreeVar(ctx, y->name->str); IdentifierPtr a = new Identifier(ctx.closureDataName); a->location = y->location; NameRefPtr b = new NameRef(a); b->location = y->location; FieldRefPtr c = new FieldRef(b.ptr(), y->name); c->location = y->location; if (ctx.captureByRef) { vector<int> ops; ops.push_back(DEREFERENCE); ExprPtr d = new VariadicOp(ops, new ExprList(c.ptr())); d->location = y->location; x = d.ptr(); } else { x = c.ptr(); } } } else if ((z->objKind == MULTI_PVALUE) || (z->objKind == MULTI_CVALUE)) { vector<TypePtr> types = typesOfValues(z); bool allStatic = true; for (unsigned i = 0; i < types.size(); ++i) { if (!isStaticOrTupleOfStatics(types[i])) { allStatic = false; break; } } if (allStatic) { ExprListPtr args = new ExprList(); for (unsigned i = 0; i < types.size(); ++i) args->add(new ObjectExpr(types[i].ptr())); CallPtr call = new Call(operator_expr_typesToRValues(), args); call->location = y->location; x = call.ptr(); } else { addFreeVar(ctx, y->name->str); IdentifierPtr a = new Identifier(ctx.closureDataName); a->location = y->location; NameRefPtr b = new NameRef(a); b->location = y->location; FieldRefPtr c = new FieldRef(b.ptr(), y->name); c->location = y->location; if (ctx.captureByRef) { ExprPtr f = operator_expr_unpackMultiValuedFreeVarAndDereference(); CallPtr d = new Call(f, new ExprList()); d->parenArgs->add(c.ptr()); x = d.ptr(); } else { ExprPtr f = operator_expr_unpackMultiValuedFreeVar(); CallPtr d = new Call(f, new ExprList()); d->parenArgs->add(c.ptr()); x = d.ptr(); } } } } break; } case TUPLE : { Tuple *y = (Tuple *)x.ptr(); convertFreeVars(y->args, env, ctx); break; } case PAREN : { Paren *y = (Paren *)x.ptr(); convertFreeVars(y->args, env, ctx); break; } case INDEXING : { Indexing *y = (Indexing *)x.ptr(); convertFreeVars(y->expr, env, ctx); convertFreeVars(y->args, env, ctx); break; } case CALL : { Call *y = (Call *)x.ptr(); convertFreeVars(y->expr, env, ctx); convertFreeVars(y->parenArgs, env, ctx); convertFreeVars(y->lambdaArgs, env, ctx); break; } case FIELD_REF : { FieldRef *y = (FieldRef *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case STATIC_INDEXING : { StaticIndexing *y = (StaticIndexing *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case VARIADIC_OP : { VariadicOp *y = (VariadicOp *)x.ptr(); convertFreeVars(y->exprs, env, ctx); break; } case AND : { And *y = (And *)x.ptr(); convertFreeVars(y->expr1, env, ctx); convertFreeVars(y->expr2, env, ctx); break; } case OR : { Or *y = (Or *)x.ptr(); convertFreeVars(y->expr1, env, ctx); convertFreeVars(y->expr2, env, ctx); break; } case LAMBDA : { Lambda *y = (Lambda *)x.ptr(); EnvPtr env2 = new Env(env); for (unsigned i = 0; i < y->formalArgs.size(); ++i) addLocal(env2, y->formalArgs[i]->name, y->formalArgs[i]->name.ptr()); if (y->formalVarArg.ptr()) addLocal(env2, y->formalVarArg->name, y->formalVarArg->name.ptr()); convertFreeVars(y->body, env2, ctx); break; } case UNPACK : { Unpack *y = (Unpack *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case STATIC_EXPR : { StaticExpr *y = (StaticExpr *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case DISPATCH_EXPR : { DispatchExpr *y = (DispatchExpr *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case EVAL_EXPR : { EvalExpr *eval = (EvalExpr *)x.ptr(); convertFreeVars(eval->args, env, ctx); break; } case FOREIGN_EXPR : case OBJECT_EXPR : case FILE_EXPR : case LINE_EXPR : case COLUMN_EXPR : case ARG_EXPR : break; } }
void convertFreeVars(StatementPtr x, EnvPtr env, LambdaContext &ctx) { switch (x->stmtKind) { case BLOCK : { Block *y = (Block *)x.ptr(); if (!y->desugared) y->desugared = desugarBlock(y); for (unsigned i = 0; i < y->desugared->statements.size(); ++i) { StatementPtr z = y->desugared->statements[i]; if (z->stmtKind == BINDING) { Binding *a = (Binding *)z.ptr(); convertFreeVars(a->values, env, ctx); EnvPtr env2 = new Env(env); for (unsigned j = 0; j < a->names.size(); ++j) addLocal(env2, a->names[j], a->names[j].ptr()); env = env2; } else { convertFreeVars(z, env, ctx); } } break; } case LABEL : case BINDING : { break; } case ASSIGNMENT : { Assignment *y = (Assignment *)x.ptr(); convertFreeVars(y->left, env, ctx); convertFreeVars(y->right, env, ctx); break; } case INIT_ASSIGNMENT : { InitAssignment *y = (InitAssignment *)x.ptr(); convertFreeVars(y->left, env, ctx); convertFreeVars(y->right, env, ctx); break; } case UPDATE_ASSIGNMENT : { UpdateAssignment *y = (UpdateAssignment *)x.ptr(); convertFreeVars(y->left, env, ctx); convertFreeVars(y->right, env, ctx); break; } case GOTO : { break; } case RETURN : { Return *y = (Return *)x.ptr(); convertFreeVars(y->values, env, ctx); break; } case IF : { If *y = (If *)x.ptr(); convertFreeVars(y->condition, env, ctx); convertFreeVars(y->thenPart, env, ctx); if (y->elsePart.ptr()) convertFreeVars(y->elsePart, env, ctx); break; } case SWITCH : { Switch *y = (Switch *)x.ptr(); convertFreeVars(y->expr, env, ctx); for (unsigned i = 0; i < y->caseBlocks.size(); ++i) { CaseBlockPtr z = y->caseBlocks[i]; convertFreeVars(z->caseLabels, env, ctx); convertFreeVars(z->body, env, ctx); } if (y->defaultCase.ptr()) convertFreeVars(y->defaultCase, env, ctx); break; } case EVAL_STATEMENT : { EvalStatement *eval = (EvalStatement *)x.ptr(); convertFreeVars(eval->args, env, ctx); break; } case EXPR_STATEMENT : { ExprStatement *y = (ExprStatement *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case WHILE : { While *y = (While *)x.ptr(); convertFreeVars(y->condition, env, ctx); convertFreeVars(y->body, env, ctx); break; } case BREAK : case CONTINUE : { break; } case FOR : { For *y = (For *)x.ptr(); convertFreeVars(y->expr, env, ctx); EnvPtr env2 = new Env(env); for (unsigned j = 0; j < y->variables.size(); ++j) addLocal(env2, y->variables[j], y->variables[j].ptr()); convertFreeVars(y->body, env2, ctx); break; } case FOREIGN_STATEMENT : { break; } case TRY : { Try *y = (Try *)x.ptr(); convertFreeVars(y->tryBlock, env, ctx); for (unsigned i = 0; i < y->catchBlocks.size(); ++i) { EnvPtr env2 = new Env(env); addLocal(env2, y->catchBlocks[i]->exceptionVar, y->catchBlocks[i]->exceptionVar.ptr() ); if (y->catchBlocks[i]->exceptionType.ptr()) convertFreeVars(y->catchBlocks[i]->exceptionType, env, ctx); convertFreeVars(y->catchBlocks[i]->body, env2, ctx); } break; } case THROW : { Throw *y = (Throw *)x.ptr(); convertFreeVars(y->expr, env, ctx); break; } case STATIC_FOR : { StaticFor *y = (StaticFor *)x.ptr(); convertFreeVars(y->values, env, ctx); EnvPtr env2 = new Env(env); addLocal(env2, y->variable, y->variable.ptr()); convertFreeVars(y->body, env2, ctx); break; } case FINALLY : { Finally *y = (Finally *)x.ptr(); convertFreeVars(y->body, env, ctx); break; } case ONERROR : { OnError *y = (OnError *)x.ptr(); convertFreeVars(y->body, env, ctx); break; } case UNREACHABLE : break; default : assert(false); } }
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(); }