Logo Search packages:      
Sourcecode: ktechlab version File versions  Download package

QString FlowCode::generateMicrobe ( const ItemList &  itemList,
MicroSettings settings 
)

Generates and returns the microbe code

Parameters:
nonVerbal if true then will not inform the user when something goes wrong

Definition at line 152 of file flowcode.cpp.

References addCode(), addCodeBranch(), addSubroutine(), MicroInfo::id(), Item::id(), Item::level(), MicroSettings::microInfo(), CNItem::nodeMap(), FlowPart::outputPart(), MicroInfo::package(), MicroPackage::pinCount(), MicroSettings::pinMappings(), MicroPackage::portNames(), MicroSettings::portState(), MicroSettings::portType(), setStartPart(), tidyCode(), Node::type(), MicroSettings::variableInfo(), and MicroSettings::variableNames().

Referenced by processInput().

{
      bool foundStart = false;
      const ItemList::const_iterator end = itemList.end();
      for ( ItemList::const_iterator it = itemList.begin(); it != end; ++it )
      {
            if (!*it)
                  continue;
            
            FlowPart * startPart = dynamic_cast<FlowPart*>((Item*)*it);
            
            if (!startPart)
                  continue;
            
            // Check to see if we have any floating connections
            const NodeMap nodeMap = startPart->nodeMap();
            NodeMap::const_iterator nodeMapEnd = nodeMap.end();
            for ( NodeMap::const_iterator nodeMapIt = nodeMap.begin(); nodeMapIt != nodeMapEnd; ++nodeMapIt )
            {
                  Node * node = nodeMapIt.data().node;
                  if ( !node || (node->type() != Node::fp_out) )
                        continue;
                  
                  if ( !startPart->outputPart( nodeMapIt.key() ) )
                        outputWarning( i18n("Warning: Floating connection for %1").arg( startPart->id() ) );
            }
            
            FlowContainer * fc = dynamic_cast<FlowContainer*>((Item*)*it);
            
            if ( (*it)->id().startsWith("START") && startPart )
            {
                  foundStart = true;
                  setStartPart(startPart);
            }
            else if ( ((*it)->id().startsWith("interrupt") || (*it)->id().startsWith("sub")) && fc )
            {
                  addSubroutine(fc);
            }
      }
      
      if (!foundStart)
      {
            outputError( i18n("KTechlab was unable to find the \"Start\" part.\nThis must be included as the starting point for your program.") );
            return 0;
      }
      
      m_addedParts.clear();
      m_stopParts.clear();
      m_gotos.clear();
      m_labels.clear();
      m_code = QString::null;
      
      // PIC type
      {
            const QString codeString = settings->microInfo()->id() + "\n";
            addCode(codeString);
      }
      
      // Initial variables
      {
            QStringList vars = settings->variableNames();
            
            // If "inited" is true at the end, we comment at the insertion point
            bool inited = false;
            const QString codeString = "// Initial variable values:\n";
            addCode(codeString);
            
            const QStringList::iterator end = vars.end();
            for ( QStringList::iterator it = vars.begin(); it != end; ++it )
            {
                  VariableInfo *info = settings->variableInfo(*it);
                  if ( info /*&& info->initAtStart*/ )
                  {
                        inited = true;
                        addCode(*it+" = "+info->valueAsString());
                  }
            }
            if (!inited) {
                  m_code.remove(codeString);
            } else {
                  addCode("\n");
            }
      }
      
      // Initial pin maps
      {
            const PinMappingMap pinMappings = settings->pinMappings();
            PinMappingMap::const_iterator end = pinMappings.end();
            for ( PinMappingMap::const_iterator it = pinMappings.begin(); it != end; ++it )
            {
                  QString type;
                  
                  switch ( it.data().type() )
                  {
                        case PinMapping::Keypad_4x3:
                        case PinMapping::Keypad_4x4:
                              type = "keypad";
                              break;
                              
                        case PinMapping::SevenSegment:
                              type = "sevenseg";
                              break;
                              
                        case PinMapping::Invalid:
                              break;
                  }
                  
                  if ( type.isEmpty() )
                        continue;
                  
                  addCode( QString("%1 %2 %3").arg( type ).arg( it.key() ).arg( it.data().pins().join(" ") ) );
            }
      }
      
      // Initial port settings
      {
            QStringList portNames = settings->microInfo()->package()->portNames();
            const QStringList::iterator end = portNames.end();
            
            // TRIS registers (remember that this is set to ..11111 on all resets)
            for ( QStringList::iterator it = portNames.begin(); it != end; ++it )
            {
                  const int portType = settings->portType(*it);
                  const int pinCount = settings->microInfo()->package()->pinCount( 0, *it );
                  
                  // We don't need to reset it if portType == 2^(pinCount-1)
                  if ( portType != (1<<pinCount)-1 )
                  {
                        QString name = *it;
                        name.replace("PORT","TRIS");
                        addCode( name+" = "+QString::number(portType) );
                  }
            }
            
            // PORT registers
            for ( QStringList::iterator it = portNames.begin(); it != end; ++it )
            {
                  const int portState = settings->portState(*it);
                  addCode( (*it)+" = "+QString::number(portState) );
            }
      }
      
      
      m_curLevel = p_startPart->level();
      addCodeBranch(p_startPart);
      addCode("end");
      
      {
            const FlowPartList::iterator end = m_subroutines.end();
            for ( FlowPartList::iterator it = m_subroutines.begin(); it != end; ++it )
            {
                  m_curLevel = 0;
                  if (*it)
                  {
                        addCode("\n");
                        addCodeBranch(*it);
                  }
            }
      }
      
      tidyCode();
      return m_code;
}


Generated by  Doxygen 1.6.0   Back to index