Пример #1
0
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);
    }
}
Пример #2
0
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");
        }
        }
    }
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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());
        }
    }
}
Пример #6
0
static void initializeVariantType(VariantTypePtr t) {
    assert(!t->initialized);

    EnvPtr variantEnv = new Env(t->variant->env);
    {
        const vector<IdentifierPtr> &params = 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;
}