예제 #1
0
파일: desugar.cpp 프로젝트: galchinsky/clay
ExprPtr desugarVariadicOp(VariadicOpPtr x, CompilerState* cst) {
    ExprPtr callable = lookupCallable(x->op, cst);
    CallPtr call = new Call(callable, new ExprList());
    call->parenArgs->add(x->exprs);  
    call->location = x->location;
    return call.ptr();
}
예제 #2
0
파일: desugar.cpp 프로젝트: galchinsky/clay
ExprPtr desugarStaticIndexing(StaticIndexingPtr x, CompilerState* cst) {
    ExprListPtr args = new ExprList(x->expr);
    ValueHolderPtr vh = sizeTToValueHolder(x->index, cst);
    args->add(new StaticExpr(new ObjectExpr(vh.ptr())));
    CallPtr call = new Call(operator_expr_staticIndex(cst), args);
    call->location = x->location;
    return call.ptr();
}
예제 #3
0
파일: desugar.cpp 프로젝트: galchinsky/clay
ExprPtr desugarCharLiteral(char c, CompilerState* cst) {
    ExprPtr nameRef = operator_expr_charLiteral(cst);
    CallPtr call = new Call(nameRef, new ExprList());
    llvm::SmallString<128> buf;
    llvm::raw_svector_ostream out(buf);
    out << (int)c;
    call->parenArgs->add(new IntLiteral(out.str(), "ss"));
    return call.ptr();
}
예제 #4
0
파일: desugar.cpp 프로젝트: galchinsky/clay
void desugarFieldRef(FieldRefPtr x, ModulePtr module) {
    if (x->expr->exprKind == FIELD_REF || x->expr->exprKind == NAME_REF) {
        ModulePtr m = dottedImportedModule(x.ptr(), module.ptr());
        if (m.ptr()) {
            x->isDottedModuleName = true;
            x->desugared = new ObjectExpr(m.ptr());
            return;
        }
    }
    
    ExprListPtr args = new ExprList(x->expr);
    args->add(new ObjectExpr(x->name.ptr()));
    CallPtr call = new Call(operator_expr_fieldRef(module->cst), args);
    call->location = x->location;
    x->desugared = call.ptr();
}
예제 #5
0
파일: desugar.cpp 프로젝트: galchinsky/clay
StatementPtr desugarForStatement(ForPtr x, CompilerState* cst) {
    IdentifierPtr exprVar = Identifier::get("%expr", x->location);
    IdentifierPtr iterVar = Identifier::get("%iter", x->location);
    IdentifierPtr valueVar = Identifier::get("%value", x->location);

    BlockPtr block = new Block();
    block->location = x->body->location;
    vector<StatementPtr> &bs = block->statements;
    BindingPtr exprBinding = new Binding(FORWARD, identV(exprVar), new ExprList(x->expr));
    exprBinding->location = x->body->location;
    bs.push_back(exprBinding.ptr());

    CallPtr iteratorCall = new Call(operator_expr_iterator(cst), new ExprList());
    iteratorCall->location = x->body->location;
    ExprPtr exprName = new NameRef(exprVar);
    exprName->location = x->location;
    iteratorCall->parenArgs->add(exprName);
    BindingPtr iteratorBinding = new Binding(FORWARD,
        identV(iterVar),
        new ExprList(iteratorCall.ptr()));
    iteratorBinding->location = x->body->location;
    bs.push_back(iteratorBinding.ptr());

    vector<StatementPtr> valueStatements;
    CallPtr nextValueCall = new Call(operator_expr_nextValue(cst), new ExprList());
    nextValueCall->location = x->body->location;
    ExprPtr iterName = new NameRef(iterVar);
    iterName->location = x->body->location;
    nextValueCall->parenArgs->add(iterName);
    BindingPtr nextValueBinding = new Binding(VAR,
        identV(valueVar),
        new ExprList(nextValueCall.ptr()));
    nextValueBinding->location = x->body->location;
    valueStatements.push_back(nextValueBinding.ptr());

    CallPtr hasValueCall = new Call(operator_expr_hasValueP(cst), new ExprList());
    hasValueCall->location = x->body->location;
    ExprPtr valueName = new NameRef(valueVar);
    valueName->location = x->body->location;
    hasValueCall->parenArgs->add(valueName);

    CallPtr getValueCall = new Call(operator_expr_getValue(cst), new ExprList());
    getValueCall->location = x->body->location;
    getValueCall->parenArgs->add(valueName);
    BlockPtr whileBody = new Block();
    whileBody->location = x->body->location;
    vector<StatementPtr> &ws = whileBody->statements;
    ws.push_back(new Binding(FORWARD, identVtoFormalV(x->variables), new ExprList(getValueCall.ptr())));
    ws.push_back(x->body);

    StatementPtr whileStmt = new While(valueStatements, hasValueCall.ptr(), whileBody.ptr());
    whileStmt->location = x->location;
    bs.push_back(whileStmt);
    return block.ptr();
}
예제 #6
0
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;
    }
}
예제 #7
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);
}
예제 #8
0
파일: desugar.cpp 프로젝트: galchinsky/clay
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;
}
예제 #9
0
파일: desugar.cpp 프로젝트: galchinsky/clay
StatementPtr desugarCatchBlocks(llvm::ArrayRef<CatchPtr> catchBlocks,
                                CompilerState* cst) {
    assert(!catchBlocks.empty());
    Location firstCatchLocation = catchBlocks.front()->location;
    IdentifierPtr expVar = Identifier::get("%exp", firstCatchLocation);

    CallPtr activeException = new Call(primitive_expr_activeException(cst), new ExprList());
    activeException->location = firstCatchLocation;

    BindingPtr expBinding =
        new Binding(VAR,
                    identVtoFormalV(vector<IdentifierPtr>(1, expVar)),
                    new ExprList(activeException.ptr()));
    expBinding->location = firstCatchLocation;

    bool lastWasAny = false;
    IfPtr lastIf;
    StatementPtr result;
    for (size_t i = 0; i < catchBlocks.size(); ++i) {
        CatchPtr x = catchBlocks[i];
        if (lastWasAny)
            error(x, "unreachable catch block");
        if (x->exceptionType.ptr()) {
            ExprListPtr asTypeArgs = new ExprList(x->exceptionType);
            ExprPtr expVarName = new NameRef(expVar);
            expVarName->location = x->exceptionVar->location;
            asTypeArgs->add(expVarName);
            CallPtr cond = new Call(operator_expr_exceptionIsP(cst), asTypeArgs);
            cond->location = x->exceptionType->location;

            BlockPtr block = new Block();
            block->location = x->location;

            vector<IdentifierPtr> identifiers;
            makeExceptionVars(identifiers, x);

            CallPtr getter = new Call(operator_expr_exceptionAs(cst), asTypeArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            identVtoFormalV(identifiers),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            BindingPtr exceptionVarForRethrow =
                new Binding(REF,
                            identVtoFormalV(vector<IdentifierPtr>(1, Identifier::get("%exception", x->location))),
                            new ExprList(new NameRef(Identifier::get(x->exceptionVar->str, x->location))));
            exceptionVarForRethrow->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(exceptionVarForRethrow.ptr());
            block->statements.push_back(x->body);

            IfPtr ifStatement = new If(cond.ptr(), block.ptr());
            ifStatement->location = x->location;
            if (!result)
                result = ifStatement.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = ifStatement.ptr();
            lastIf = ifStatement;
        }
        else {
            BlockPtr block = new Block();
            block->location = x->location;

            vector<IdentifierPtr> identifiers;
            makeExceptionVars(identifiers, x);

            ExprListPtr asAnyArgs = new ExprList(new NameRef(expVar));
            CallPtr getter = new Call(operator_expr_exceptionAsAny(cst),
                                      asAnyArgs);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            identVtoFormalV(identifiers),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            BindingPtr exceptionVarForRethrow =
                new Binding(REF,
                            identVtoFormalV(vector<IdentifierPtr>(1, Identifier::get("%exception", x->location))),
                            new ExprList(new NameRef(Identifier::get(x->exceptionVar->str, x->location))));
            exceptionVarForRethrow->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(exceptionVarForRethrow.ptr());
            block->statements.push_back(x->body);

            if (!result)
                result = block.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = block.ptr();

            lastWasAny = true;
            lastIf = NULL;
        }
    }
    assert(result.ptr());
    if (!lastWasAny) {
        assert(lastIf.ptr());
        BlockPtr block = new Block();
        block->location = firstCatchLocation;
        ExprPtr expVarName = new NameRef(expVar);
        expVarName->location = firstCatchLocation;
        ExprListPtr continueArgs = new ExprList(expVarName);
        CallPtr continueException = new Call(operator_expr_continueException(cst),
                                             continueArgs);
        continueException->location = firstCatchLocation;
        StatementPtr stmt = new ExprStatement(continueException.ptr());
        stmt->location = firstCatchLocation;
        block->statements.push_back(stmt);
        block->statements.push_back(new Unreachable());
        lastIf->elsePart = block.ptr();
    }

    BlockPtr block = new Block();
    block->location = firstCatchLocation;
    block->statements.push_back(expBinding.ptr());
    block->statements.push_back(result.ptr());

    return block.ptr();
}