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; }
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; }
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; }
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; }