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; llvm::ArrayRef<PatternVar> pvars = code->patternVars; EnvPtr patternEnv = new Env(x->env); initializePatternEnv(patternEnv, pvars, x->cells, x->multiCells); assert(x->target.ptr()); x->callablePattern = evaluateOnePattern(x->target, patternEnv); llvm::ArrayRef<FormalArgPtr> formalArgs = code->formalArgs; for (size_t i = 0; i < formalArgs.size(); ++i) { FormalArgPtr y = formalArgs[i]; PatternPtr pattern; if (y->type.ptr()) { if (y->varArg) { ExprPtr unpack = new Unpack(y->type.ptr()); unpack->location = y->type->location; x->varArgPattern = evaluateMultiPattern(new ExprList(unpack), patternEnv); pattern = NULL; } else { pattern = evaluateOnePattern(y->type, patternEnv); } } x->argPatterns.push_back(pattern); } x->patternsInitializedState = 1; }
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 getProcedureMonoTypes(ProcedureMono &mono, EnvPtr env, llvm::ArrayRef<FormalArgPtr> formalArgs, bool hasVarArg) { if (mono.monoState == Procedure_NoOverloads && !hasVarArg) { assert(mono.monoTypes.empty()); mono.monoState = Procedure_MonoOverload; for (size_t i = 0; i < formalArgs.size(); ++i) { if (formalArgs[i]->type == NULL) goto poly; LocationContext loc(formalArgs[i]->type->location); PatternPtr argPattern = evaluateOnePattern(formalArgs[i]->type, env); ObjectPtr argTypeObj = derefDeep(argPattern); if (argTypeObj == NULL) goto poly; TypePtr argType; if (!staticToType(argTypeObj, argType)) error(formalArgs[i], "expecting a type"); mono.monoTypes.push_back(argType); } } else goto poly; return; poly: mono.monoTypes.clear(); mono.monoState = Procedure_PolyOverload; return; }
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 getProcedureMonoTypes(ProcedureMono &mono, EnvPtr env, vector<FormalArgPtr> const &formalArgs, FormalArgPtr formalVarArg) { if (mono.monoState == Procedure_NoOverloads && formalVarArg == NULL) { assert(mono.monoTypes.empty()); mono.monoState = Procedure_MonoOverload; for (size_t i = 0; i < formalArgs.size(); ++i) { if (formalArgs[i]->type == NULL) goto poly; PatternPtr argPattern = evaluateOnePattern(formalArgs[i]->type, env); ObjectPtr argType = derefDeep(argPattern); if (argType == NULL) goto poly; if (argType->objKind != TYPE) error(formalArgs[i], "expecting a type"); mono.monoTypes.push_back((Type*)argType.ptr()); } } else goto poly; return; poly: mono.monoTypes.clear(); mono.monoState = Procedure_PolyOverload; return; }
static void initOverload(OverloadPtr x) { EnvPtr env = overloadPatternEnv(x); PatternPtr pattern = evaluateOnePattern(x->target, env); ObjectPtr obj = derefDeep(pattern); if (obj == NULL) { x->nameIsPattern = true; addPatternOverload(x); } else { switch (obj->objKind) { case PROCEDURE : { Procedure *proc = (Procedure *)obj.ptr(); addProcedureOverload(proc, env, x); break; } case RECORD_DECL : { RecordDecl *r = (RecordDecl *)obj.ptr(); r->overloads.insert(r->overloads.begin(), x); break; } case VARIANT_DECL : { VariantDecl *v = (VariantDecl *)obj.ptr(); v->overloads.insert(v->overloads.begin(), x); break; } case TYPE : { Type *t = (Type *)obj.ptr(); t->overloads.insert(t->overloads.begin(), x); break; } case PRIM_OP : { if (isOverloadablePrimOp(obj)) addPrimOpOverload((PrimOp *)obj.ptr(), x); else error(x->target, "invalid overload target"); break; } case GLOBAL_ALIAS : { GlobalAlias *a = (GlobalAlias*)obj.ptr(); if (!a->hasParams()) error(x->target, "invalid overload target"); a->overloads.insert(a->overloads.begin(), x); break; } case INTRINSIC : { error(x->target, "invalid overload target"); } default : { error(x->target, "invalid overload target"); } } } }
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; }