void BytecodeGenerationVisitor::visitBlockNode(BlockNode* node) {   // DONE
	Scope* prevScope = currentScope;
	currentScope = node->scope();
	
	Scope::VarIterator varsToSave(currentScope);
	while (varsToSave.hasNext()) {
		AstVar* v = varsToSave.next();
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOADVAR]);
		bytecode->addInt16(getVarId(v));
		locals.push_back(v);
	}
	
	Scope::VarIterator varsToInit(currentScope);
	while (varsToInit.hasNext()) {
		AstVar* v = varsToInit.next();
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOAD0]);
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]);
		bytecode->addInt16(getVarId(v));
	}
	
	Scope::FunctionIterator functionsToAdd(node -> scope());
	while (functionsToAdd.hasNext()) {
		AstFunction *astFunction = functionsToAdd.next();
		BytecodeFunction *bytecodeFunction = new BytecodeFunction(astFunction);
		code -> addFunction(bytecodeFunction);
	}
	
	Scope::FunctionIterator functionsToBuild(node -> scope());
	while (functionsToBuild.hasNext()) {
		AstFunction *astFunction = functionsToBuild.next();
		astFunction->node()->visit(this);
	}

	for (unsigned int i = 0; i < (node -> nodes()); i++) {
		node -> nodeAt(i) -> visit(this);
		if (currentType != VT_VOID && !(node->nodeAt(i)->isReturnNode())) {
			bytecode -> addInsn(BC_POP);
		}
	}
	
	Scope::VarIterator varsToRestore(currentScope);
	stack<AstVar*> variables;
	while (varsToRestore.hasNext()) {
		variables.push(varsToRestore.next());
	}
	
	while (!variables.empty()) {
		AstVar* v = variables.top();
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]);
		bytecode->addInt16(getVarId(v));
		locals.pop_back();
		variables.pop();
	}
	
	currentScope = prevScope;
	currentType = VT_VOID;
}
void BytecodeGenerationVisitor::visitCallNode(CallNode* node) {
	const Signature& sign = code->functionByName(node->name())->signature();
	AstFunction* f = currentScope->lookupFunction(node->name());
	
	for (unsigned int i = 0; i < node->parametersNumber(); i++) {
		AstVar* v = f->scope()->lookupVariable(sign[i + 1].second);
		uint16_t varId = getVarId(v);
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_LOADVAR]);
		bytecode->addInt16(varId);
	}
	
	for (unsigned int i = 0; i < node->parametersNumber(); i++) {
		node->parameterAt(i)->visit(this);
		if (currentType == VT_INT && sign[i + 1].first == VT_DOUBLE) {
			bytecode->addInsn(BC_I2D);
		} else if (currentType == VT_DOUBLE && sign[i + 1].first == VT_INT) {
			bytecode->addInsn(BC_D2I);
		}
	}
	
	for (int i = node->parametersNumber(); i > 0; i--) {
		AstVar* v = f->scope()->lookupVariable(sign[i].second);
		uint16_t varId = getVarId(v);
		bytecode->addInsn(insnByUntypedInsn[sign[i].first][UT_STOREVAR]);
		bytecode->addInt16(varId);
	}
	
	bytecode->addInsn(BC_CALL);
	bytecode->addInt16(code->functionByName(node->name())->id());
	
	if (sign[0].first == VT_VOID) {
		for (unsigned int i = node->parametersNumber(); i > 0; i--) {
			AstVar* v = f->scope()->lookupVariable(sign[i].second);
			uint16_t varId = getVarId(v);
			bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]);
			bytecode->addInt16(varId);
		}
	} else {
		for (unsigned int i = node->parametersNumber(); i > 0; i--) {
			AstVar* v = f->scope()->lookupVariable(sign[i].second);
			uint16_t varId = getVarId(v);
			bytecode->addInsn(BC_SWAP);
			bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]);
			bytecode->addInt16(varId);
		}
	}
	
	currentType = sign[0].first;
}
Exemplo n.º 3
0
int CAction::executeRegExp(char* P_string, VariableTable *P_callVarTable)
{
    regmatch_t pmatch[10];
    int error;
    int nbOfMatch = 0;
    char* result = NULL ;

    if (!M_regExpSet) {
        ERROR("Trying to perform regular expression match on action that does not have one!");
    }

    if (getNbSubVarId() > 9) {
        ERROR("You can only have nine sub expressions!");
    }

    memset((void*)pmatch, 0, sizeof(regmatch_t)*10);

    error = regexec(&(M_internalRegExp), P_string, 10, pmatch, REGEXP_PARAMS);
    if ( error == 0) {
        CCallVariable* L_callVar = P_callVarTable->getVar(getVarId());

        for(int i = 0; i <= getNbSubVarId(); i++) {
            if(pmatch[i].rm_eo == -1) break ;

            setSubString(&result, P_string, pmatch[i].rm_so, pmatch[i].rm_eo);
            L_callVar->setMatchingValue(result);

            if (i == getNbSubVarId())
                break ;

            L_callVar = P_callVarTable->getVar(getSubVarId(i));
        }
    }
    return(nbOfMatch);
}
void BytecodeGenerationVisitor::visitReturnNode(ReturnNode* node) { // DONE
	bool swap = false;
	if (node->returnExpr() != 0) {
		swap = true;
		node -> returnExpr() -> visit(this);
		if (currentType == VT_INT && returnType == VT_DOUBLE) {
			bytecode->addInsn(BC_I2D);
		} else if (currentType == VT_DOUBLE && returnType == VT_INT) {
			bytecode->addInsn(BC_D2I);
		} else if (currentType != returnType){
			throw std::exception();
		}
	}
	
	for (int i = locals.size() - 1; i >= 0; i--) {
		if (swap) {
			bytecode->addInsn(BC_SWAP);
		}
		const AstVar* v = locals[i];
		bytecode->addInsn(insnByUntypedInsn[v->type()][UT_STOREVAR]);
		bytecode->addInt16(getVarId(v));
	}
	
	bytecode -> addInsn(BC_RETURN);
	currentType = VT_VOID;
}
void BytecodeGenerationVisitor::visitLoadNode(LoadNode* node) { // DONE
	uint16_t varId = getVarId(node -> var());
	VarType type = node -> var() -> type();

	bytecode -> addInsn(insnByUntypedInsn[type][UT_LOADVAR]);
	bytecode -> addUInt16(varId);

	currentType = type;
}
Exemplo n.º 6
0
MCAHead translate_DecList(Node *n, SymbolTable table, MCA mca)
{
    assert(n->nodetype == DecList);
    Var v1 = NULL, v2 = NULL, v3 = NULL;
    Node* declist = n;
    Node *dec = NULL;
    char *decid;
    MCAHead h = NULL;
    MCAHead h1 = NULL, h2 = NULL, h3 = NULL;
    Symbol symbol;

    while(1)
    {
        dec = NT_getChild(declist, 0); 
        decid = getVarId(NT_getChild(dec, 0));
        symbol = LookUpSymbol(sts, NewSymbol(decid, NULL, -1)); 
        switch(symbol->type->tn)
        {
            case ARRAY:
                v1 = NewVar(VAR);
                v1->name = decid;
                v2 = NewVar(SIZE);
                v2->value = symbol->type->width; 
                h1 = NewMCAHead(mca, NewMidCode(C_DEC, v1, v2, NULL));
                break;
            case STRUCTURE:
                printf("%s", "Cannot translate: Code contains variables or parameters of structure type\n.");
                exit(0);
                break;
            case BASIC:
                break;
        }
        if(dec->seq == 1)
        {
            v1 = NewVar(VAR);
            v1->name = decid;
            v2 = NewVar(PLACE);
            v2->ttype = TEMP;
            h2 = translate_Exp(NT_getChild(dec, 2), table, v2, mca);
            h3 = NewMCAHead(mca, NewMidCode(C_ASSIGN, v1, v2, NULL));
        }
        h = LinkMulMCAHead(mca, 4, h, h1, h2, h3);

        if(declist->seq == 0)
            break;
        declist = NT_getChild(declist, 2);
    }
    return h;
}
Exemplo n.º 7
0
MCAHead translate_FunDec(Node *n, SymbolTable table, MCA mca)
{
    assert(n->nodetype == FunDec);
    Var v1, v2, v3;
    Node* varlist = NT_getChild(n, 2);
    char *varid;
    Node *funcdecid;
    MCAHead h = NULL;
    MCAHead h1, h2, h3;
    funcdecid = NT_getChild(n, 0);
    v1 = NewVar(VAR);
    v1->name = funcdecid->data.s;
    h = NewMCAHead(mca, NewMidCode(C_FUNC,  v1, NULL, NULL));
    if(n->seq == 0)
    {
    while(1)
    {
        varid = getVarId(NT_getChild(NT_getChild(varlist, 0), 1));
        Symbol s = LookUpSymbol(sts, NewSymbol(varid, NULL, -1));
        if(s->type->tn == STRUCTURE)
        {
            printf("%s", "Cannot translate: Code contains variables or parameters of structure type.\n");
            exit(0);
            
        }
        
        v1 = NewVar(VAR);
        v1->name = varid;
        h1 = NewMCAHead(mca, NewMidCode(C_PARAM, v1, NULL, NULL));
        h = LinkMulMCAHead(mca, 2, h, h1);
        if(varlist->seq == 1)
            break;
        varlist = NT_getChild(varlist, 2);
    }
    }

    return h;
}
void BytecodeGenerationVisitor::visitStoreNode(StoreNode* node) {   // DONE
	uint16_t varId = getVarId(node -> var());
	VarType type = node -> var() -> type();

	node -> value() -> visit(this);
	
	if (currentType == VT_INT && type == VT_DOUBLE) {
		bytecode->addInsn(BC_I2D);
	} else if (currentType == VT_DOUBLE && type == VT_INT) {
		bytecode->addInsn(BC_D2I);
	}

	TokenKind op = node -> op();
	switch (op) {
		case tASSIGN:
			bytecode -> addInsn(insnByUntypedInsn[type][UT_STOREVAR]);
			bytecode -> addUInt16(varId);
			break;
		case tINCRSET:
			bytecode -> addInsn(insnByUntypedInsn[type][UT_LOADVAR]);
			bytecode -> addUInt16(varId);
			bytecode -> addInsn(insnByUntypedInsn[type][UT_ADD]);
			bytecode -> addInsn(insnByUntypedInsn[type][UT_STOREVAR]);
			bytecode -> addUInt16(varId);
			break;
		case tDECRSET:
			bytecode -> addInsn(insnByUntypedInsn[type][UT_LOADVAR]);
			bytecode -> addUInt16(varId);
			bytecode -> addInsn(insnByUntypedInsn[type][UT_SUB]);
			bytecode -> addInsn(insnByUntypedInsn[type][UT_STOREVAR]);
			bytecode -> addUInt16(varId);
			break;
		default:
			throw std::exception();
	}
	
	currentType = VT_VOID;
}
void BytecodeGenerationVisitor::visitForNode(ForNode* node) { // DONE
	uint16_t varId = getVarId(node -> var());
	node -> inExpr() -> visit(this);

	// checking cycle condition
	int returnIndex = bytecode -> length();
	bytecode -> addInsn(BC_IFICMPG);
	int jumpOffsetIndex = bytecode -> length();
	bytecode -> addInt16(0);
	int jumpIndex = bytecode->length();

	// setting cycle variable value
	bytecode -> addInsn(BC_STOREIVAR);
	bytecode -> addUInt16(varId);
	bytecode -> addInsn(BC_LOADIVAR);
	bytecode -> addUInt16(varId);

	node -> body() -> visit(this);

	// updating cycle variable
	bytecode -> addInsn(BC_ILOAD1);
	bytecode -> addInsn(BC_IADD);

	// returning to the cycle begin
	bytecode -> addInsn(BC_JA);
	bytecode -> addInt16(returnIndex - (bytecode -> length() + 2));

	// setting offset to exit from cycle
	int endIndex = bytecode -> length();
	bytecode -> setInt16(jumpOffsetIndex, endIndex - jumpIndex);

	// deleting cycle bounds parameters
	bytecode -> addInsn(BC_POP);
	bytecode -> addInsn(BC_POP);
	currentType = VT_VOID;
}