Пример #1
0
ExprListPtr clone(ExprListPtr x)
{
    ExprListPtr out = new ExprList();
    for (unsigned i = 0; i < x->size(); ++i)
        out->add(clone(x->exprs[i]));
    return out;
}
Пример #2
0
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
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();
}
Пример #4
0
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
static ExprPtr convertStaticObjectToExpr(TypePtr t) {
    if (t->typeKind == STATIC_TYPE) {
        StaticType *st = (StaticType *)t.ptr();
        return new ObjectExpr(st->obj);
    }
    else if (t->typeKind == TUPLE_TYPE) {
        TupleType *tt = (TupleType *)t.ptr();
        ExprListPtr exprs = new ExprList();
        for (unsigned i = 0; i < tt->elementTypes.size(); ++i)
            exprs->add(convertStaticObjectToExpr(tt->elementTypes[i]));
        return new Tuple(exprs);
    }
    else {
        error("non-static value found in object property");
        return NULL;
    }
}
Пример #6
0
ExprPtr foreignExpr(EnvPtr env, ExprPtr expr)
{
    if (expr->exprKind == UNPACK) {
        Unpack *y = (Unpack *)expr.ptr();
        if (y->expr->exprKind == TUPLE) {
            Tuple *y2 = (Tuple *)y->expr.ptr();
            ExprListPtr out = new ExprList();
            for (unsigned i = 0; i < y2->args->size(); ++i)
                out->add(foreignExpr(env, y2->args->exprs[i]));
            return new Unpack(new Tuple(out));
        }
        else {
            return new Unpack(foreignExpr(env, y->expr));
        }
    }
    return new ForeignExpr(env, expr);
}
Пример #7
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);
}
Пример #8
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;
    }
}
Пример #9
0
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();
}