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); } }
static void initOverload(OverloadPtr x) { EnvPtr env = new Env(x->env); const vector<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()); } } PatternPtr pattern = evaluateOnePattern(x->target, env); ObjectPtr y = derefDeep(pattern); if (!y) { addTypeOverload(x); } else { switch (y->objKind) { case PROCEDURE : { Procedure *z = (Procedure *)y.ptr(); z->overloads.insert(z->overloads.begin(), x); break; } case RECORD : { Record *z = (Record *)y.ptr(); z->overloads.insert(z->overloads.begin(), x); break; } case VARIANT : { Variant *z = (Variant *)y.ptr(); z->overloads.insert(z->overloads.begin(), x); break; } case TYPE : { addTypeOverload(x); break; } case PRIM_OP : { if (isOverloadablePrimOp(y)) addPrimOpOverload((PrimOp *)y.ptr(), x); else error(x->target, "invalid overload target"); break; } default : { error(x->target, "invalid overload target"); } } } }
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 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()); } } }
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; }