void FlowPart::handleIfElse(FlowCode *code, const QString &case1Statement, const QString &case2Statement, const QString &case1, const QString &case2) { if (!code) return; FlowPart *stop = 0; FlowPart *part1 = outputPart(case1); FlowPart *part2 = outputPart(case2); if (part1 && part2) stop = endPart(QStringList::split(',', case1 + "," + case2)); if ((!part1 && !part2) || (part1 == stop && part2 == stop)) return; code->addStopPart(stop); if (part1 && part1 != stop && code->isValidBranch(part1)) { // Use the case1 statement code->addCode("if " + case1Statement + " then " + "\n{"); code->addCodeBranch(part1); code->addCode("}"); if (part2 && part2 != stop && code->isValidBranch(part2)) { code->addCode("else\n{"); code->addCodeBranch(part2); code->addCode("}"); } } else if (code->isValidBranch(part2)) { // Use the case2 statement code->addCode("if " + case2Statement + " then " + "\n{"); code->addCodeBranch(part2); code->addCode("}"); } code->removeStopPart(stop); code->addCodeBranch(stop); }
void SetPin::generateMicrobe( FlowCode *code ) { const QString pin = dataString("pin"); const QString port = "PORT" + QString((QChar)pin[1]); const QString bit = (QChar)pin[2]; code->addCode( port+"."+bit+" = "+dataString("state") ); code->addCodeBranch( outputPart("stdoutput") ); #if 0 const QString pin = dataString("pin"); const bool isHigh = (dataString("state") == "High"); const QString port = "PORT" + QString((QChar)pin[1]); const QString bit = (QChar)pin[2]; QString newCode; if (isHigh) { newCode += "bsf " + port + "," + bit + " ; Set bit high\n"; } else { newCode += "bcf " + port + "," + bit + " ; Set bit low\n"; } code->addCodeBlock( id(), newCode ); #endif }
QString FlowPart::gotoCode(const QString& internalNodeId) { FlowPart *end = outputPart(internalNodeId); if (!end) return ""; return "goto " + end->id(); }
FlowPartList FlowPart::outputParts() { FlowPartList list; const NodeInfoMap::iterator end = m_nodeMap.end(); for (NodeInfoMap::iterator it = m_nodeMap.begin(); it != end; ++it) { FlowPart *part = outputPart(it.key()); if (part) list.append(part); } return list; }
void VarAssignment::generateMicrobe( FlowCode *code ) { code->addCode( dataString("0-var1")+" "+"="/*dataString("1-op")*/+" "+dataString("2-var2") ); code->addCodeBranch( outputPart("stdoutput") ); #if 0 QString var1 = dataString("0-var1"); QString var2 = dataString("2-var2"); QString op = dataString("1-op"); if ( FlowCode::isLiteral(var1) ) return; code->addVariable(var1); QString newCode; if ( !FlowCode::isLiteral(var1) ) { if ( FlowCode::isLiteral(var2) ) newCode += "movlw " + var2 + " ; Assign " + var2 + " to w register\n"; } if ( !FlowCode::isLiteral(var2) ) { code->addVariable(var2); newCode += "movf " + var2 + ",0 ; Move " + var2 + " to w register\n"; } if ( op == "=" ) newCode += "movwf " + var1 + " ; Move contents of w register to " + var1 + "\n"; else if ( op == "+=" ) newCode += "addwf " + var1 + ",1 ; Add contents of w register to " + var1 + " and place result back in " + var1 + "\n"; else if ( op == "-=" ) newCode += "subwf " + var1 + ",1 ; Subtract contents of w register from " + var1 + " and place result back in " + var1 + "\n"; else if ( op == "&=" ) newCode += "andwf " + var1 + ",1 ; Binary AND contents of w register with " + var1 + " and place result back in " + var1 + "\n"; else if ( op == "or=" ) newCode += "iorwf " + var1 + ",1 ; Binary inclusive OR contents of w register with " + var1 + " and place result back in " + var1 + "\n"; else if ( op == "xor=" ) newCode += "xorwf " + var1 + ",1 ; Binary exclusive OR contents of w register with " + var1 + " and place result back in " + var1 + "\n"; newCode += gotoCode("stdoutput"); code->addCodeBlock( id(), newCode ); #endif }
FlowPart* FlowPart::endPart(QStringList ids, FlowPartList *previousParts) { if (ids.empty()) { const NodeInfoMap::iterator end = m_nodeMap.end(); for (NodeInfoMap::iterator it = m_nodeMap.begin(); it != end; ++it) { ids.append(it.key()); } filterEndPartIDs(&ids); } const bool createdList = (!previousParts); if (createdList) { previousParts = new FlowPartList; } else if (previousParts->contains(this)) { return 0l; } previousParts->append(this); if (ids.empty()) { return 0; } if (ids.size() == 1) { return outputPart(*(ids.begin())); } typedef QValueList<FlowPartList> ValidPartsList; ValidPartsList validPartsList; const QStringList::iterator idsEnd = ids.end(); for (QStringList::iterator it = ids.begin(); it != idsEnd; ++it) { int prevLevel = level(); FlowPartList validParts; FlowPart *part = outputPart(*it); while (part) { if (!validParts.contains(part)) { validParts.append(part); // if ( part->level() >= level() ) { const int _l = part->level(); part = part->endPart(QStringList(), previousParts); prevLevel = _l; // } else { // part = 0l; // } } else { part = 0; } } if (!validParts.empty()) { validPartsList.append(validParts); } } if (createdList) { delete previousParts; previousParts = 0; } if (validPartsList.empty()) return 0; FlowPartList firstList = *(validPartsList.begin()); const FlowPartList::iterator flEnd = firstList.end(); const ValidPartsList::iterator vplEnd = validPartsList.end(); for (FlowPartList::iterator it = firstList.begin(); it != flEnd; ++it) { bool ok = true; for (ValidPartsList::iterator vplit = validPartsList.begin(); vplit != vplEnd; ++vplit) { if (!(*vplit).contains(*it)) ok = false; } if (ok) return *it; } return 0l; }
void SevenSeg::generateMicrobe( FlowCode *code ) { code->addCode( QString("%1 = %2").arg( dataString("sevenseg") ).arg( dataString("expression") ) ); code->addCodeBranch( outputPart("stdoutput") ); }
void Delay::generateMicrobe( FlowCode *code ) { const double delayLength_ms = dataDouble("delay_length")*1e3; code->addCode( "delay "+QString::number(delayLength_ms) ); code->addCodeBranch( outputPart("stdoutput") ); // code->addVariable("COUNT_REPEAT"); #if 0 // Code for pauses less than 769uS if ( pauseLength < 769 ) { code->addCodeBlock( id(), "movlw " + QString::number(pauseLength/3) + "\n" "movwf COUNT_REPEAT\n" "call count_3uS\n" + gotoCode("stdoutput") ); code->addCodeBlock( "count_3uS", "decfsz COUNT_REPEAT,1\n" "goto count_3uS\n" "return" ); } else if ( pauseLength < 196609 ) { code->addVariable("COUNT_LOOP_1"); code->addCodeBlock( id(), "movlw " + QString::number(pauseLength/(3*256)) + "\n" "movwf COUNT_REPEAT\n" "call count_768uS\n" + gotoCode("stdoutput") ); code->addCodeBlock( "count_768uS", "decfsz COUNT_LOOP_1,1\n" "goto count_768uS\n" "decfsz COUNT_REPEAT,1\n" "goto count_768uS\n" "return" ); } else if ( pauseLength < 50331649 ) { code->addVariable("COUNT_LOOP_1"); code->addVariable("COUNT_LOOP_2"); code->addCodeBlock( id(), "movlw " + QString::number(pauseLength/(3*256*256)) + "\n" "movwf COUNT_REPEAT\n" "call count_200mS\n" + gotoCode("stdoutput") ); code->addCodeBlock( "count_200mS", "decfsz COUNT_LOOP_1,1\n" "goto count_200mS\n" "decfsz COUNT_LOOP_2,1\n" "goto count_200mS\n" "decfsz COUNT_REPEAT,1\n" "goto count_200mS\n" "return" ); } else/* if ( pauseLength < 12884901889 )*/ { code->addVariable("COUNT_LOOP_1"); code->addVariable("COUNT_LOOP_2"); code->addVariable("COUNT_LOOP_3"); code->addCodeBlock( id(), "movlw " + QString::number(pauseLength/(3*256*256*256)) + "\n" "movwf COUNT_REPEAT\n" "call count_50S\n" + gotoCode("stdoutput") ); code->addCodeBlock( "count_50S", "decfsz COUNT_LOOP_1,1\n" "goto count_50S\n" "decfsz COUNT_LOOP_2,1\n" "goto count_50S\n" "decfsz COUNT_LOOP_3,1\n" "goto count_50S\n" "decfsz COUNT_REPEAT,1\n" "goto count_50S\n" "return" ); } #endif }
void Interrupt::generateMicrobe( FlowCode *code ) { code->addCode( "\ninterrupt "+dataString("interrupt")+"\n{" ); code->addCodeBranch( outputPart("int_in") ); code->addCode("}"); }
void VarComparison::generateMicrobe( FlowCode *code ) { QString var1 = dataString("0var1"); QString var2 = dataString("2var2"); QString test = dataString("1op"); handleIfElse( code, var1+" "+test+" "+var2, var1+" "+oppOp(test)+" "+var2, "stdoutput", "altoutput" ); #if 0 code->addCode( "if "+var1+" "+test+" "+var2+"\n{\n" ); code->addCodeBranch( outputPart("stdoutput") ); code->addCode("}"); if ( outputPart("altoutput") ) { code->addCode("else\n{"); code->addCodeBranch( outputPart("altoutput") ); code->addCode("}"); } #endif #if 0 QString newCode; if ( FlowCode::isLiteral(var2) ) newCode += "movlw " + var2 + " ; Move literal to register w\n"; else { code->addVariable(var2); newCode += "movf " + var2 + ",0 ; Move " + var2 + " to register w\n"; } if ( FlowCode::isLiteral(var1) ) newCode += "sublw " + var1 + " ; Subtract register w from " + var1 + ", placing result in w\n"; else { code->addVariable(var1); newCode += "subwf " + var1 + ",0 ; Subtract register w from " + var1 + ", placing result in w\n"; } if ( test == "==" ) { // check: works newCode += "btfss STATUS,2 ; Check if zero flag is set\n"; newCode += gotoCode("altoutput") + " ; Result from calculation was non-zero; hence comparison is false\n"; newCode += gotoCode("stdoutput") + " ; Ouput was zero; hence comparison is true, so continue from this point\n"; } else if ( test == "!=" ) { // check: works newCode += "btfsc STATUS,2 ; Check if zero flag is clear\n"; newCode += gotoCode("altoutput") + " ; Result from calculation was zero; hence comparison is false\n"; newCode += gotoCode("stdoutput") + " ; Output was non-zero; hence comparison is true, so continue from this point\n"; } else if ( test == ">=" ) { // check: works newCode += "btfss STATUS,0 ; Check if carry flag is set\n"; newCode += gotoCode("altoutput") + " ; Result from calculation is negative; hence comparison is false\n"; newCode += gotoCode("stdoutput") + " ; Result from calculation is positive or zero; so continue from this point\n"; } else if ( test == ">" ) { // check: works newCode += "btfss STATUS,0 ; Check if carry flag is set\n"; newCode += gotoCode("altoutput") + " ; Result is negative; hence comparison is false\n"; newCode += "btfsc STATUS,2 ; Check if zero flag is set\n"; newCode += gotoCode("altoutput") + " ; Result is zero; hence comparison is false\n"; newCode += gotoCode("stdoutput") + " ; Comparison is true, so continue from this point\n"; } else if ( test == "<" ) { // check: works newCode += "btfsc STATUS,0 ; Check if carry flag is set\n"; newCode += gotoCode("altoutput"); newCode += gotoCode("stdoutput"); } else if ( test == "<=" ) { // check: works newCode += "btfsc STATUS,2 ; Check if result is zero\n"; newCode += gotoCode("stdoutput") + " ; Result is zero; hence comparison is true\n"; newCode += "btfsc STATUS,0 ; Check if carry flag is set\n"; newCode += gotoCode("altoutput") + " ; Result is positive (not zero, has already tested for this); hence comparison is false\n"; newCode += gotoCode("stdoutput") + " ; Result is negative, hence comparison is true\n"; } code->addCodeBlock( id(), newCode ); #endif }