Пример #1
0
 static void jitAndPrintExpr(ExprPtr expr) {
     //expr -> println(expr);
     NameRefPtr println = new NameRef(Identifier::get("println"));
     ExprPtr call = new Call(println.ptr(), new ExprList(expr));
     ExprStatementPtr callStmt = new ExprStatement(call);
     jitStatements(vector<StatementPtr>(1, callStmt.ptr()));
 }
Пример #2
0
StatementPtr desugarSwitchStatement(SwitchPtr x, CompilerState* cst) {
    BlockPtr block = new Block();
    block->location = x->location;

    block->statements.insert(block->statements.end(),
        x->exprStatements.begin(), x->exprStatements.end());

    // %thing is the value being switched on
    IdentifierPtr thing = Identifier::get("%case", x->expr->location);
    NameRefPtr thingRef = new NameRef(thing);
    thingRef->location = x->expr->location;

    // initialize %case
    {
        BindingPtr b = new Binding(FORWARD, identV(thing), new ExprList(x->expr));
        b->location = x->expr->location;
        block->statements.push_back(b.ptr());
    }

    ExprPtr caseCallable = operator_expr_caseP(cst);

    StatementPtr root;
    StatementPtr *nextPtr = &root;

    // dispatch logic
    for (size_t i = 0; i < x->caseBlocks.size(); ++i) {
        CaseBlockPtr caseBlock = x->caseBlocks[i];

        ExprListPtr caseArgs = new ExprList(thingRef.ptr());
        ExprPtr caseCompareArgs = new Paren(caseBlock->caseLabels);
        caseCompareArgs->location = caseBlock->location;
        caseArgs->add(caseCompareArgs);

        ExprPtr condition = new Call(caseCallable, caseArgs);
        condition->location = caseBlock->location;

        IfPtr ifStmt = new If(condition, caseBlock->body);
        ifStmt->location = caseBlock->location;
        *nextPtr = ifStmt.ptr();
        nextPtr = &(ifStmt->elsePart);
    }

    if (x->defaultCase.ptr())
        *nextPtr = x->defaultCase;
    else
        *nextPtr = NULL;

    block->statements.push_back(root);

    return block.ptr();
}
Пример #3
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;
    }
}
Пример #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);
}