Ejemplo n.º 1
0
void convertFreeVars(LambdaPtr x, EnvPtr env,
                     const string &closureDataName,
                     vector<string> &freeVars)
{
    EnvPtr env2 = new Env(env);
    for (unsigned i = 0; i < x->formalArgs.size(); ++i) {
        FormalArgPtr arg = x->formalArgs[i];
        addLocal(env2, arg->name, arg->name.ptr());
    }
    if (x->formalVarArg.ptr()) {
        addLocal(env2, x->formalVarArg->name, x->formalVarArg->name.ptr());
    }
    LambdaContext ctx(x->captureByRef, env, closureDataName, freeVars);
    convertFreeVars(x->body, env2, ctx);
}
Ejemplo n.º 2
0
void initializeLambda(LambdaPtr x, EnvPtr env)
{
    assert(!x->initialized);
    x->initialized = true;

    string lname = lambdaName(x);

    ostringstream ostr;
    ostr << "%closureData:" << lname;
    string closureDataName = ostr.str();

    convertFreeVars(x, env, closureDataName, x->freeVars);
    getProcedureMonoTypes(x->mono, env, x->formalArgs, x->formalVarArg);
    if (x->freeVars.empty()) {
        initializeLambdaWithoutFreeVars(x, env, closureDataName, lname);
    }
    else {
        initializeLambdaWithFreeVars(x, env, closureDataName, lname);
    }
}
Ejemplo n.º 3
0
void initializeLambda(LambdaPtr x, EnvPtr env)
{
    assert(!x->initialized);
    x->initialized = true;

    int lambdaObjectIndex = nextLambdaObjectIndex();

    ostringstream ostr;
    ostr << "%closureData" << lambdaObjectIndex;
    string closureDataName = ostr.str();

    convertFreeVars(x, env, closureDataName, x->freeVars);
    if (x->freeVars.empty()) {
        initializeLambdaWithoutFreeVars(x, env);
    }
    else {
        initializeLambdaWithFreeVars(
            x, env, closureDataName, lambdaObjectIndex);
    }
}
Ejemplo n.º 4
0
void convertFreeVars(ExprListPtr x, EnvPtr env, LambdaContext &ctx)
{
    for (unsigned i = 0; i < x->size(); ++i)
        convertFreeVars(x->exprs[i], env, ctx);
}
Ejemplo n.º 5
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;
    }
}
Ejemplo n.º 6
0
void convertFreeVars(StatementPtr x, EnvPtr env, LambdaContext &ctx)
{
    switch (x->stmtKind) {

    case BLOCK : {
        Block *y = (Block *)x.ptr();
        if (!y->desugared)
            y->desugared = desugarBlock(y);
        for (unsigned i = 0; i < y->desugared->statements.size(); ++i) {
            StatementPtr z = y->desugared->statements[i];
            if (z->stmtKind == BINDING) {
                Binding *a = (Binding *)z.ptr();
                convertFreeVars(a->values, env, ctx);
                EnvPtr env2 = new Env(env);
                for (unsigned j = 0; j < a->names.size(); ++j)
                    addLocal(env2, a->names[j], a->names[j].ptr());
                env = env2;
            }
            else {
                convertFreeVars(z, env, ctx);
            }
        }
        break;
    }

    case LABEL :
    case BINDING : {
        break;
    }

    case ASSIGNMENT : {
        Assignment *y = (Assignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case INIT_ASSIGNMENT : {
        InitAssignment *y = (InitAssignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case UPDATE_ASSIGNMENT : {
        UpdateAssignment *y = (UpdateAssignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case GOTO : {
        break;
    }

    case RETURN : {
        Return *y = (Return *)x.ptr();
        convertFreeVars(y->values, env, ctx);
        break;
    }

    case IF : {
        If *y = (If *)x.ptr();
        convertFreeVars(y->condition, env, ctx);
        convertFreeVars(y->thenPart, env, ctx);
        if (y->elsePart.ptr())
            convertFreeVars(y->elsePart, env, ctx);
        break;
    }

    case SWITCH : {
        Switch *y = (Switch *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        for (unsigned i = 0; i < y->caseBlocks.size(); ++i) {
            CaseBlockPtr z = y->caseBlocks[i];
            convertFreeVars(z->caseLabels, env, ctx);
            convertFreeVars(z->body, env, ctx);
        }
        if (y->defaultCase.ptr())
            convertFreeVars(y->defaultCase, env, ctx);
        break;
    }

    case EVAL_STATEMENT : {
        EvalStatement *eval = (EvalStatement *)x.ptr();
        convertFreeVars(eval->args, env, ctx);
        break;
    }

    case EXPR_STATEMENT : {
        ExprStatement *y = (ExprStatement *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case WHILE : {
        While *y = (While *)x.ptr();
        convertFreeVars(y->condition, env, ctx);
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case BREAK :
    case CONTINUE : {
        break;
    }

    case FOR : {
        For *y = (For *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        EnvPtr env2 = new Env(env);
        for (unsigned j = 0; j < y->variables.size(); ++j)
            addLocal(env2, y->variables[j], y->variables[j].ptr());
        convertFreeVars(y->body, env2, ctx);
        break;
    }

    case FOREIGN_STATEMENT : {
        break;
    }

    case TRY : {
        Try *y = (Try *)x.ptr();
        convertFreeVars(y->tryBlock, env, ctx);
        for (unsigned i = 0; i < y->catchBlocks.size(); ++i) {
            EnvPtr env2 = new Env(env);
            addLocal(env2,
                y->catchBlocks[i]->exceptionVar,
                y->catchBlocks[i]->exceptionVar.ptr()
            );
            if (y->catchBlocks[i]->exceptionType.ptr())
                convertFreeVars(y->catchBlocks[i]->exceptionType, env, ctx);
            convertFreeVars(y->catchBlocks[i]->body, env2, ctx);
        }

        break;
    }

    case THROW : {
        Throw *y = (Throw *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case STATIC_FOR : {
        StaticFor *y = (StaticFor *)x.ptr();
        convertFreeVars(y->values, env, ctx);
        EnvPtr env2 = new Env(env);
        addLocal(env2, y->variable, y->variable.ptr());
        convertFreeVars(y->body, env2, ctx);
        break;
    }

    case FINALLY : {
        Finally *y = (Finally *)x.ptr();
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case ONERROR : {
        OnError *y = (OnError *)x.ptr();
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case UNREACHABLE :
        break;

    default :
        assert(false);

    }
}