Example #1
0
File: cfg.cpp Project: h87kg/pyston
    AST_expr* remapBoolOp(AST_BoolOp* node) {
        std::string name = nodeName(node);

        CFGBlock *starting_block = curblock;
        CFGBlock *exit_block = cfg->addDeferredBlock();

        for (int i = 0; i < node->values.size() - 1; i++) {
            AST_expr* val = remapExpr(node->values[i]);
            push_back(makeAssign(name, val));

            AST_Branch *br = new AST_Branch();
            br->test = val;
            push_back(br);

            CFGBlock *was_block = curblock;
            CFGBlock *next_block = cfg->addBlock();
            CFGBlock *crit_break_block = cfg->addBlock();
            was_block->connectTo(next_block);
            was_block->connectTo(crit_break_block);

            if (node->op_type == AST_TYPE::Or) {
                br->iftrue = crit_break_block;
                br->iffalse = next_block;
            } else {
                br->iffalse = crit_break_block;
                br->iftrue = next_block;
            }

            curblock = crit_break_block;
            AST_Jump* j = new AST_Jump();
            j->target = exit_block;
            push_back(j);
            crit_break_block->connectTo(exit_block);

            curblock = next_block;
        }

        AST_expr* final_val = remapExpr(node->values[node->values.size()-1]);
        push_back(makeAssign(name, final_val));

        AST_Jump* j = new AST_Jump();
        push_back(j);
        j->target = exit_block;
        curblock->connectTo(exit_block);

        cfg->placeBlock(exit_block);
        curblock = exit_block;

        return makeName(name, AST_TYPE::Load);
    }
Example #2
0
/*
	Create and return a list that is ready for use with the sentence forms. For
	each node in the settings.wordFiles list, create a node whose left is the
	settings left (for example, %m) and whose right is the associated word list.
*/
list_t *loadWords(settings_t settings)
{
	/* Variables used to create the list */
	list_t *wordList = createList();
	assignment_t *wordAssignment;
	list_t *wordFile;
	FILE *f;

	/* Variables from settings */
	node_t *settingNode = settings.wordFiles->head;
	assignment_t *settingAssignment;
	char *settingFile;

	/* Load every node in settings.wordFiles */
	while (settingNode != NULL)
	{
		settingAssignment = settingNode->datum;
		settingFile = settingAssignment->right;

		f = locateFile(settings, settingFile);
		wordFile = loadWordFile(f);
		fclose(f);

		wordAssignment = makeAssign(settingAssignment->left, wordFile);
		addDatum(wordList, wordAssignment);

		settingNode = settingNode->next;
		printf("Loaded %s\n", settingFile);
	}

	printf("Loaded the word files.\n\n");
	return wordList;
}
Example #3
0
File: cfg.cpp Project: h87kg/pyston
    AST_expr* remapIfExp(AST_IfExp* node) {
        std::string rtn_name = nodeName(node);

        AST_expr* test = remapExpr(node->test);

        CFGBlock *starting_block = curblock;
        AST_Branch *br = new AST_Branch();
        br->col_offset = node->col_offset;
        br->lineno = node->lineno;
        br->test = node->test;
        push_back(br);

        CFGBlock* iftrue = cfg->addBlock();
        iftrue->info = "iftrue";
        br->iftrue = iftrue;
        starting_block->connectTo(iftrue);
        curblock = iftrue;
        push_back(makeAssign(rtn_name, remapExpr(node->body)));
        AST_Jump* jtrue = new AST_Jump();
        push_back(jtrue);
        CFGBlock* endtrue = curblock;

        CFGBlock* iffalse = cfg->addBlock();
        iffalse->info = "iffalse";
        br->iffalse = iffalse;
        starting_block->connectTo(iffalse);
        curblock = iffalse;
        push_back(makeAssign(rtn_name, remapExpr(node->orelse)));
        AST_Jump* jfalse = new AST_Jump();
        push_back(jfalse);
        CFGBlock* endfalse = curblock;

        CFGBlock* exit_block = cfg->addBlock();
        jtrue->target = exit_block;
        endtrue->connectTo(exit_block);
        jfalse->target = exit_block;
        endfalse->connectTo(exit_block);
        curblock = exit_block;

        return makeName(rtn_name, AST_TYPE::Load);
    }
Example #4
0
File: cfg.cpp Project: h87kg/pyston
    void doReturn(AST_expr* value) {
        assert(value);
        CFGBlock *rtn_dest = getReturn();
        if (rtn_dest != NULL) {
            push_back(makeAssign("#rtnval", value));

            AST_Jump *j = makeJump();
            j->target = rtn_dest;
            curblock->connectTo(rtn_dest);
            push_back(j);
        } else {
            AST_Return *node = new AST_Return();
            node->value = value;
            node->col_offset = value->col_offset;
            node->lineno = value->lineno;
            push_back(node);
        }
        curblock = NULL;
    }
Example #5
0
File: cfg.cpp Project: h87kg/pyston
    AST_expr* remapExpr(AST_expr* node, bool wrap_with_assign=true) {
        if (node == NULL)
            return NULL;

        AST_expr* rtn;
        switch (node->type) {
        case AST_TYPE::Attribute:
            rtn = remapAttribute(static_cast<AST_Attribute*>(node));
            break;
        case AST_TYPE::BinOp:
            rtn = remapBinOp(static_cast<AST_BinOp*>(node));
            break;
        case AST_TYPE::BoolOp:
            rtn = remapBoolOp(static_cast<AST_BoolOp*>(node));
            break;
        case AST_TYPE::Call:
            rtn = remapCall(static_cast<AST_Call*>(node));
            break;
        case AST_TYPE::Compare:
            rtn = remapCompare(static_cast<AST_Compare*>(node));
            break;
        case AST_TYPE::Dict:
            rtn = remapDict(static_cast<AST_Dict*>(node));
            break;
        case AST_TYPE::IfExp:
            rtn = remapIfExp(static_cast<AST_IfExp*>(node));
            break;
        case AST_TYPE::Index:
            rtn = remapIndex(static_cast<AST_Index*>(node));
            break;
        case AST_TYPE::List:
            rtn = remapList(static_cast<AST_List*>(node));
            break;
        case AST_TYPE::ListComp:
            rtn = remapListComp(static_cast<AST_ListComp*>(node));
            break;
        case AST_TYPE::Name:
            return node;
        case AST_TYPE::Num:
            return node;
        case AST_TYPE::Slice:
            rtn = remapSlice(static_cast<AST_Slice*>(node));
            break;
        case AST_TYPE::Str:
            return node;
        case AST_TYPE::Subscript:
            rtn = remapSubscript(static_cast<AST_Subscript*>(node));
            break;
        case AST_TYPE::Tuple:
            rtn = remapTuple(static_cast<AST_Tuple*>(node));
            break;
        case AST_TYPE::UnaryOp:
            rtn = remapUnaryOp(static_cast<AST_UnaryOp*>(node));
            break;
        default:
            RELEASE_ASSERT(0, "%d", node->type);
        }

        if (wrap_with_assign && rtn->type != AST_TYPE::Name) {
            std::string name = nodeName(node);
            push_back(makeAssign(name, rtn));
            return makeName(name, AST_TYPE::Load);
        } else {
            return rtn;
        }
    }
Example #6
0
File: cfg.cpp Project: h87kg/pyston
    AST_expr* remapListComp(AST_ListComp* node) {
        std::string rtn_name = nodeName(node);
        push_back(makeAssign(rtn_name, new AST_List()));

        std::vector<CFGBlock*> exit_blocks;

        // Where the current level should jump to after finishing its iteration.
        // For the outermost comprehension, this is NULL, and it doesn't jump anywhere;
        // for the inner comprehensions, they should jump to the next-outer comprehension
        // when they are done iterating.
        CFGBlock *finished_block = NULL;

        for (int i = 0, n = node->generators.size(); i < n; i++) {
            AST_comprehension *c = node->generators[i];
            bool is_innermost = (i == n-1);

            AST_expr *remapped_iter = remapExpr(c->iter);
            AST_expr *iter_attr = makeLoadAttribute(remapped_iter, "__iter__", true);
            AST_expr *iter_call = makeCall(iter_attr);
            std::string iter_name = nodeName(node, "iter", i);
            AST_stmt *iter_assign = makeAssign(iter_name, iter_call);
            push_back(iter_assign);

            // TODO bad to save these like this?
            AST_expr *hasnext_attr = makeLoadAttribute(makeName(iter_name, AST_TYPE::Load), "__hasnext__", true);
            AST_expr *next_attr = makeLoadAttribute(makeName(iter_name, AST_TYPE::Load), "next", true);

            AST_Jump *j;

            CFGBlock *test_block = cfg->addBlock();
            test_block->info = "listcomp_test";
            //printf("Test block for comp %d is %d\n", i, test_block->idx);

            j = new AST_Jump();
            j->target = test_block;
            curblock->connectTo(test_block);
            push_back(j);

            curblock = test_block;
            AST_expr *test_call = makeCall(hasnext_attr);

            CFGBlock* body_block = cfg->addBlock();
            body_block->info = "listcomp_body";
            CFGBlock* exit_block = cfg->addDeferredBlock();
            exit_block->info = "listcomp_exit";
            exit_blocks.push_back(exit_block);
            //printf("Body block for comp %d is %d\n", i, body_block->idx);

            AST_Branch *br = new AST_Branch();
            br->col_offset = node->col_offset;
            br->lineno = node->lineno;
            br->test = test_call;
            br->iftrue = body_block;
            br->iffalse = exit_block;
            curblock->connectTo(body_block);
            curblock->connectTo(exit_block);
            push_back(br);

            curblock = body_block;
            push_back(makeAssign(c->target, makeCall(next_attr)));

            for (AST_expr *if_condition : c->ifs) {
                AST_expr *remapped = remapExpr(if_condition);
                AST_Branch *br = new AST_Branch();
                br->test = remapped;
                push_back(br);

                // Put this below the entire body?
                CFGBlock *body_tramp = cfg->addBlock();
                body_tramp->info = "listcomp_if_trampoline";
                //printf("body_tramp for %d is %d\n", i, body_tramp->idx);
                CFGBlock *body_continue = cfg->addBlock();
                body_continue->info = "listcomp_if_continue";
                //printf("body_continue for %d is %d\n", i, body_continue->idx);

                br->iffalse = body_tramp;
                curblock->connectTo(body_tramp);
                br->iftrue = body_continue;
                curblock->connectTo(body_continue);

                curblock = body_tramp;
                j = new AST_Jump();
                j->target = test_block;
                push_back(j);
                curblock->connectTo(test_block, true);

                curblock = body_continue;
            }

            CFGBlock *body_end = curblock;

            assert((finished_block != NULL) == (i != 0));
            if (finished_block) {
                curblock = exit_block;
                j = new AST_Jump();
                j->target = finished_block;
                curblock->connectTo(finished_block, true);
                push_back(j);
            }
            finished_block = test_block;

            curblock = body_end;
            if (is_innermost) {
                AST_expr *elt = remapExpr(node->elt);
                push_back(makeExpr(makeCall(makeLoadAttribute(makeName(rtn_name, AST_TYPE::Load), "append", true), elt)));

                j = new AST_Jump();
                j->target = test_block;
                curblock->connectTo(test_block, true);
                push_back(j);

                assert(exit_blocks.size());
                curblock = exit_blocks[0];
            } else {
                // continue onto the next comprehension and add to this body
            }
        }

        // Wait until the end to place the end blocks, so that
        // we get a nice nesting structure, that looks similar to what
        // you'd get with a nested for loop:
        for (int i = exit_blocks.size() - 1; i >= 0; i--) {
            cfg->placeBlock(exit_blocks[i]);
            //printf("Exit block for comp %d is %d\n", i, exit_blocks[i]->idx);
        }

        return makeName(rtn_name, AST_TYPE::Load);
    };
Example #7
0
File: cfg.cpp Project: h87kg/pyston
 AST_stmt* makeAssign(const std::string &id, AST_expr *val) {
     assert(val);
     AST_expr *name = makeName(id, AST_TYPE::Store, val->lineno, 0);
     return makeAssign(name, val);
 }