Exemplo n.º 1
0
static void initializeLambdaWithoutFreeVars(LambdaPtr x, EnvPtr env)
{
    IdentifierPtr name = new Identifier("LambdaProcedure");
    name->location = x->location;
    x->lambdaProc = new Procedure(name, PRIVATE);

    CodePtr code = new Code();
    code->location = x->location;
    for (unsigned i = 0; i < x->formalArgs.size(); ++i) {
        FormalArgPtr y = new FormalArg(x->formalArgs[i], NULL);
        y->location = x->formalArgs[i]->location;
        code->formalArgs.push_back(y.ptr());
    }
    if (x->formalVarArg.ptr()) {
        FormalArgPtr y = new FormalArg(x->formalVarArg, NULL);
        y->location = x->formalVarArg->location;
        code->formalVarArg = y;
    }
    code->body = x->body;

    ExprPtr procRef = new ObjectExpr(x->lambdaProc.ptr());
    procRef->location = x->location;
    OverloadPtr overload = new Overload(procRef, code, false, false);
    overload->env = env;
    overload->location = x->location;
    x->lambdaProc->overloads.push_back(overload);

    x->converted = procRef;
}
Exemplo n.º 2
0
static bool matchTempness(CodePtr code,
                          const vector<ValueTempness> &argsTempness,
                          bool callByName,
                          vector<ValueTempness> &tempnessKey,
                          vector<bool> &forwardedRValueFlags)
{
    const vector<FormalArgPtr> &fargs = code->formalArgs;
    FormalArgPtr fvarArg = code->formalVarArg;

    if (fvarArg.ptr())
        assert(fargs.size() <= argsTempness.size());
    else
        assert(fargs.size() == argsTempness.size());

    tempnessKey.clear();
    forwardedRValueFlags.clear();
    for (unsigned i = 0; i < fargs.size(); ++i) {
        if (callByName && (fargs[i]->tempness == TEMPNESS_FORWARD)) {
            error(fargs[i], "forwarded arguments are not allowed "
                  "in call-by-name procedures");
        }
        if (!tempnessMatches(argsTempness[i], fargs[i]->tempness))
            return false;
        tempnessKey.push_back(
            tempnessKeyItem(fargs[i]->tempness,
                            argsTempness[i]));
        bool forwardedRValue = 
            (fargs[i]->tempness == TEMPNESS_FORWARD) &&
            (argsTempness[i] == TEMPNESS_RVALUE);
        forwardedRValueFlags.push_back(forwardedRValue);
    }
    if (fvarArg.ptr()) {
        if (callByName && (fvarArg->tempness == TEMPNESS_FORWARD)) {
            error(fvarArg, "forwarded arguments are not allowed "
                  "in call-by-name procedures");
        }
        for (unsigned i = fargs.size(); i < argsTempness.size(); ++i) {
            if (!tempnessMatches(argsTempness[i], fvarArg->tempness))
                return false;
            tempnessKey.push_back(
                tempnessKeyItem(fvarArg->tempness,
                                argsTempness[i]));
            bool forwardedRValue =
                (fvarArg->tempness == TEMPNESS_FORWARD) &&
                (argsTempness[i] == TEMPNESS_RVALUE);
            forwardedRValueFlags.push_back(forwardedRValue);
        }
    }
    return true;
}
Exemplo n.º 3
0
static void setProperty(TypePtr type,
                        ProcedurePtr proc,
                        const vector<ExprPtr> &exprs) {
    CodePtr code = new Code();

    TypePtr typeType = staticType(type.ptr());
    ExprPtr argType = new ObjectExpr(typeType.ptr());
    FormalArgPtr arg = new FormalArg(new Identifier("x"), argType);
    code->formalArgs.push_back(arg.ptr());

    ExprListPtr returnExprs = new ExprList();
    for (unsigned i = 0; i < exprs.size(); ++i)
        returnExprs->add(exprs[i]);
    code->body = new Return(RETURN_VALUE, returnExprs);

    ExprPtr target = new ObjectExpr(proc.ptr());
    OverloadPtr overload = new Overload(target, code, false, false);
    overload->env = new Env();
    proc->overloads.insert(proc->overloads.begin(), overload);
}
Exemplo n.º 4
0
static void initializeLambdaWithFreeVars(LambdaPtr x, EnvPtr env,
    string const &closureDataName, string const &lname)
{
    RecordPtr r = new Record(PRIVATE);
    r->location = x->location;
    r->name = new Identifier(lname);
    r->env = env;
    x->lambdaRecord = r;
    r->lambda = x;
    vector<RecordFieldPtr> fields;

    CallPtr converted = new Call(NULL, new ExprList());
    for (unsigned i = 0; i < x->freeVars.size(); ++i) {
        IdentifierPtr ident = new Identifier(x->freeVars[i]);
        NameRefPtr nameRef = new NameRef(ident);

        TypePtr type;
        ObjectPtr obj = safeLookupEnv(env, ident);
        switch (obj->objKind) {
        case PVALUE :
        case CVALUE : {
            type = typeOfValue(obj);
            if (x->captureByRef) {
                type = pointerType(type);
                vector<int> ops;
                ops.push_back(ADDRESS_OF);
                ExprPtr addr = new VariadicOp(ops, new ExprList(nameRef.ptr()));
                converted->parenArgs->add(addr);
            }
            else {
                converted->parenArgs->add(nameRef.ptr());
            }
            break;
        }
        case MULTI_PVALUE :
        case MULTI_CVALUE : {
            vector<TypePtr> types = typesOfValues(obj);
            vector<TypePtr> elementTypes;
            for (unsigned j = 0; j < types.size(); ++j) {
                TypePtr t = types[j];
                if (x->captureByRef)
                    t = pointerType(t);
                elementTypes.push_back(t);
            }
            type = tupleType(elementTypes);
            if (x->captureByRef) {
                ExprPtr e = operator_expr_packMultiValuedFreeVarByRef();
                CallPtr call = new Call(e, new ExprList());
                call->parenArgs->add(new Unpack(nameRef.ptr()));
                converted->parenArgs->add(call.ptr());
            }
            else {
                ExprPtr e = operator_expr_packMultiValuedFreeVar();
                CallPtr call = new Call(e, new ExprList());
                call->parenArgs->add(new Unpack(nameRef.ptr()));
                converted->parenArgs->add(call.ptr());
            }
            break;
        }
        default :
            assert(false);
        }

        ExprPtr fieldType = new ObjectExpr(type.ptr());
        RecordFieldPtr field = new RecordField(ident, fieldType);
        fields.push_back(field);
    }
    r->body = new RecordBody(fields);

    TypePtr t = recordType(r, vector<ObjectPtr>());
    x->lambdaType = t;
    ExprPtr typeExpr = new ObjectExpr(t.ptr());
    converted->expr = typeExpr;
    x->converted = converted.ptr();

    CodePtr code = new Code();
    code->location = x->location;
    IdentifierPtr closureDataIdent = new Identifier(closureDataName);
    FormalArgPtr closureDataArg = new FormalArg(closureDataIdent, typeExpr);
    code->formalArgs.push_back(closureDataArg.ptr());
    for (unsigned i = 0; i < x->formalArgs.size(); ++i) {
        code->formalArgs.push_back(x->formalArgs[i]);
    }
    if (x->formalVarArg.ptr()) {
        code->formalVarArg = x->formalVarArg;
    }
    code->body = x->body;

    OverloadPtr overload = new Overload(
        operator_expr_call(), code, false, false
    );
    overload->env = env;
    overload->location = x->location;
    ObjectPtr obj = operator_call();
    if (obj->objKind != PROCEDURE)
        error("'call' operator not found!");
    Procedure *callObj = (Procedure *)obj.ptr();
    callObj->overloads.insert(callObj->overloads.begin(), overload);
}
Exemplo n.º 5
0
OverloadPtr desugarAsOverload(OverloadPtr &x, CompilerState* cst) {
    assert(x->hasAsConversion);

    //Generate specialised overload
    CodePtr code = new Code();
    code->location = x->location;
    clone(x->code->patternVars, code->patternVars);
    
    //Generate stub body
    CallPtr returnExpr = new Call(x->target.ptr(), new ExprList());
    returnExpr->location = x->code->body->location;

    //Add patterns as static args
    for (unsigned i = 0; i < x->code->patternVars.size(); ++i) {
        llvm::SmallString<128> buf;
        llvm::raw_svector_ostream sout(buf);
        sout << "%asArg" << i;
        IdentifierPtr argName = Identifier::get(sout.str());

        ExprPtr staticName =
            new ForeignExpr("prelude",
                            new NameRef(Identifier::get("Static")));

        IndexingPtr indexing = new Indexing(staticName, new ExprList(new NameRef(x->code->patternVars[i].name)));
        indexing->startLocation = code->patternVars[i].name->location;
        indexing->endLocation = code->patternVars[i].name->location;

        FormalArgPtr arg = new FormalArg(argName, indexing.ptr());
        arg->location = x->code->patternVars[i].name->location;
        code->formalArgs.insert(code->formalArgs.begin(), arg);

        //Add patterns as static call args
        ExprPtr callArg = new NameRef(x->code->patternVars[i].name);
        returnExpr->parenArgs->add(callArg);
    }

    //Add args
    for (unsigned i = 0; i < x->code->formalArgs.size(); ++i) {
        FormalArgPtr arg = clone(x->code->formalArgs[i]);
        arg->tempness = TEMPNESS_FORWARD;
        if (x->code->formalArgs[i]->asArg) {
            arg->type = x->code->formalArgs[i]->asType;
            ExprPtr typeArg = x->code->formalArgs[i]->asType;
            CallPtr callArg = new Call(operator_expr_asExpression(cst), new ExprList());
            callArg->parenArgs->add(new NameRef(x->code->formalArgs[i]->name));
            callArg->parenArgs->add(x->code->formalArgs[i]->asType);
            callArg->location = x->code->formalArgs[i]->location;
            returnExpr->parenArgs->add(callArg.ptr());
        } else {
            ExprPtr arg0 = new NameRef(x->code->formalArgs[i]->name);
            arg0->location = x->code->formalArgs[i]->location;
            returnExpr->parenArgs->add(arg0);
        }
        code->formalArgs.push_back(arg.ptr());
    }

    code->body = x->code->body;
    OverloadPtr spec = new Overload(x->module, x->target, code, x->callByName, x->isInline);
    spec->location = x->location;
    spec->env = x->env;

    x->code->body = new Return(RETURN_FORWARD, new ExprList(new Unpack(returnExpr.ptr())), true);
    x->isInline = FORCE_INLINE;
    return spec;
}