Beispiel #1
0
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();
}
Beispiel #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();
}
Beispiel #3
0
    static void jitStatements(llvm::ArrayRef<StatementPtr> statements)
    {
        if (statements.empty()) {
            return;
        }

        if (printAST) {
            for (size_t i = 0; i < statements.size(); ++i) {
                llvm::errs() << statements[i] << "\n";
            }
        }

        IdentifierPtr fun = Identifier::get(newFunctionName());

        BlockPtr funBody = new Block(statements);
        ExternalProcedurePtr entryProc =
                new ExternalProcedure(NULL,
                                      fun,
                                      PRIVATE,
                                      vector<ExternalArgPtr>(),
                                      false,
                                      NULL,
                                      funBody.ptr(),
                                      new ExprList());

        entryProc->env = module->env;

        codegenBeforeRepl(module);
        try {
            codegenExternalProcedure(entryProc, true);
        }
        catch (std::exception) {
            return;
        }

        llvm::Function* ctor;
        llvm::Function* dtor;
        codegenAfterRepl(ctor, dtor);

        engine->runFunction(ctor, std::vector<llvm::GenericValue>());

        void* dtorLlvmFun = engine->getPointerToFunction(dtor);
        typedef void (*PFN)();
        atexit((PFN)(uintptr_t)dtorLlvmFun);
        engine->runFunction(entryProc->llvmFunc, std::vector<llvm::GenericValue>());
    }
Beispiel #4
0
StatementPtr clone(StatementPtr x)
{
    StatementPtr out;

    switch (x->stmtKind) {

    case BLOCK : {
        Block *y = (Block *)x.ptr();
        BlockPtr z = new Block();
        clone(y->statements, z->statements);
        out = z.ptr();
        break;
    }

    case LABEL : {
        Label *y = (Label *)x.ptr();
        out = new Label(y->name);
        break;
    }

    case BINDING : {
        Binding *y = (Binding *)x.ptr();
        vector<FormalArgPtr> args;
        vector<PatternVar> patternVars;
        vector<ObjectPtr> patternTypes;
        clone(y->args, args);
        clone(y->patternVars, patternVars);
        clone(y->patternTypes, patternTypes);
        out = new Binding(y->bindingKind, patternVars, patternTypes, cloneOpt(y->predicate),
            args, clone(y->values), y->hasVarArg);
        break;
    }

    case ASSIGNMENT : {
        Assignment *y = (Assignment *)x.ptr();
        out = new Assignment(clone(y->left), clone(y->right));
        break;
    }

    case INIT_ASSIGNMENT : {
        InitAssignment *y = (InitAssignment *)x.ptr();
        out = new InitAssignment(clone(y->left), clone(y->right));
        break;
    }

    case VARIADIC_ASSIGNMENT : {
        VariadicAssignment *y = (VariadicAssignment *)x.ptr();
        out = new VariadicAssignment(y->op, clone(y->exprs));
        break;
    }

    case GOTO : {
        Goto *y = (Goto *)x.ptr();
        out = new Goto(y->labelName);
        break;
    }

    case RETURN : {
        Return *y = (Return *)x.ptr();
        out = new Return(y->returnKind, clone(y->values));
        break;
    }

    case IF : {
        If *y = (If *)x.ptr();
        vector<StatementPtr> conditionStatements;
        clone(y->conditionStatements, conditionStatements);
        out = new If(conditionStatements, clone(y->condition), clone(y->thenPart),
                     cloneOpt(y->elsePart));
        break;
    }

    case SWITCH : {
        Switch *y = (Switch *)x.ptr();
        vector<StatementPtr> exprStatements;
        clone(y->exprStatements, exprStatements);
        vector<CaseBlockPtr> caseBlocks;
        clone(y->caseBlocks, caseBlocks);
        out = new Switch(exprStatements,
                         clone(y->expr),
                         caseBlocks,
                         cloneOpt(y->defaultCase));
        break;
    }

    case EXPR_STATEMENT : {
        ExprStatement *y = (ExprStatement *)x.ptr();
        out = new ExprStatement(clone(y->expr));
        break;
    }

    case WHILE : {
        While *y = (While *)x.ptr();
        vector<StatementPtr> conditionStatements;
        clone(y->conditionStatements, conditionStatements);
        out = new While(conditionStatements, clone(y->condition), clone(y->body));
        break;
    }

    case BREAK : {
        out = new Break();
        break;
    }

    case CONTINUE : {
        out = new Continue();
        break;
    }

    case FOR : {
        For *y = (For *)x.ptr();
        vector<IdentifierPtr> variables;
        clone(y->variables, variables);
        out = new For(variables, clone(y->expr), clone(y->body));
        break;
    }

    case FOREIGN_STATEMENT : {
        out = x;
        break;
    }

    case TRY : {
        Try *y = (Try *)x.ptr();
        vector<CatchPtr> catchBlocks;
        clone(y->catchBlocks, catchBlocks);
        out = new Try(clone(y->tryBlock), catchBlocks);
        break;
    }

    case THROW : {
        Throw *y = (Throw *)x.ptr();
        Throw *outThrow = new Throw(cloneOpt(y->expr), cloneOpt(y->context));
        // this is weird part: in certain situations
        // clone is called after desugar, and desugaredExpr is modified after desugar
        outThrow->desugaredExpr = cloneOpt(y->desugaredExpr);
        outThrow->desugaredContext = cloneOpt(y->desugaredContext);
        out = outThrow;
        break;
    }

    case STATIC_FOR : {
        StaticFor *y = (StaticFor *)x.ptr();
        out = new StaticFor(y->variable, clone(y->values), clone(y->body));
        break;
    }

    case FINALLY : {
        Finally *y = (Finally *)x.ptr();
        out = new Finally(clone(y->body));
        break;
    }

    case ONERROR : {
        OnError *y = (OnError *)x.ptr();
        out = new OnError(clone(y->body));
        break;
    }

    case UNREACHABLE : {
        out = new Unreachable();
        break;
    }

    case EVAL_STATEMENT : {
        EvalStatement *eval = (EvalStatement *)x.ptr();
        out = new EvalStatement(eval->args);
        break;
    }

    case STATIC_ASSERT_STATEMENT : {
        StaticAssertStatement *staticAssert = (StaticAssertStatement *)x.ptr();
        out = new StaticAssertStatement(clone(staticAssert->cond), clone(staticAssert->message));
        break;
    }

    default :
        assert(false);

    }

    out->location = x->location;
    return out;
}
Beispiel #5
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();
}