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

void Parser::processStatement ( const QString &  name,
const OutputFieldMap &  fieldMap 
) [private]

This is called when the bulk of the actual parsing has been carried out and is ready to be turned into assembly code.

Parameters:
name Name of the statement to be processed
fieldMap A map of named fields as appropriate to the statement

TODO handle end if we are not in the top level

Definition at line 591 of file parser.cpp.

References Microbe::addAlias(), Microbe::addVariable(), Microbe::isInterruptUsed(), PIC14::isValidInterrupt(), Microbe::isVariableKnown(), Variable::isWritable(), literalToInt(), mistake(), parseWithChild(), PortPin::pin(), PIC14::Sasm(), PIC14::Scall(), PIC14::SdecVar(), PIC14::Sdelay(), PIC14::Send(), Microbe::setInterruptUsed(), Variable::setPortPinList(), PIC14::Sfor(), PIC14::Sgoto(), PIC14::Sif(), PIC14::SincVar(), PIC14::Sinterrupt(), PIC14::Srepeat(), PIC14::SrotlVar(), PIC14::SrotrVar(), PIC14::Ssubroutine(), PIC14::Swhile(), PIC14::toPortPin(), SourceLine::toStringList(), and Microbe::variable().

Referenced by parse().

{
      // Name is guaranteed to be something known, the calling
      // code has taken care of that. Also fieldMap is guaranteed to contain
      // all required fields.

      if ( name == "goto" )
            m_pPic->Sgoto(fieldMap["label"].string());
      
      else if ( name == "call" )
            m_pPic->Scall(fieldMap["label"].string());
      
      else if ( name == "while" )
            m_pPic->Swhile( parseWithChild(fieldMap["code"].bracedCode() ), fieldMap["expression"].string() );
      
      else if ( name == "repeat" )
            m_pPic->Srepeat( parseWithChild(fieldMap["code"].bracedCode() ), fieldMap["expression"].string() );
      
      else if ( name == "if" )
            m_pPic->Sif(
                        parseWithChild(fieldMap["ifCode"].bracedCode() ),
                        parseWithChild(fieldMap["elseCode"].bracedCode() ),
                        fieldMap["expression"].string() );
      
      else if ( name == "sub" || name == "subroutine" )
      {     
            if(!m_bPassedEnd)
            {
                  mistake( Microbe::InterruptBeforeEnd );
            }
            else
            {
                  m_pPic->Ssubroutine( fieldMap["label"].string(), parseWithChild( fieldMap["code"].bracedCode() ) );
            }
      }
      else if( name == "interrupt" )
      {     
            QString interrupt = fieldMap["label"].string();
            
            if(!m_bPassedEnd)
            {
                  mistake( Microbe::InterruptBeforeEnd );
            }
            else if( !m_pPic->isValidInterrupt( interrupt ) )
            {
                  mistake( Microbe::InvalidInterrupt );
            }
            else if ( mb->isInterruptUsed( interrupt ) )
            {
                  mistake( Microbe::InterruptRedefined );
            }
            else
            {
                  mb->setInterruptUsed( interrupt );
                  m_pPic->Sinterrupt( interrupt, parseWithChild( fieldMap["code"].bracedCode() ) );
            }
      }
      else if( name == "end" )
      {
            ///TODO handle end if we are not in the top level
            m_bPassedEnd = true;
            m_pPic->Send();
      }
      else if( name == "for" )
      {
            QString step = fieldMap["stepExpression"].string();
            bool stepPositive;
            
            if( fieldMap["stepExpression"].found() )
            {
                  if(step.left(1) == "+")
                  {
                        stepPositive = true;
                        step = step.mid(1).stripWhiteSpace();
                  }
                  else if(step.left(1) == "-")
                  {
                        stepPositive = false;
                        step = step.mid(1).stripWhiteSpace();
                  }
                  else stepPositive = true;
            }
            else
            {
                  step = "1";
                  stepPositive = true;
            }
            
            QString variable = fieldMap["initExpression"].string().mid(0,fieldMap["initExpression"].string().find("=")).stripWhiteSpace();      
            QString endExpr = variable+ " <= " + fieldMap["toExpression"].string().stripWhiteSpace();
            
            if( fieldMap["stepExpression"].found() )
            {     
                  bool isConstant;
                  step = processConstant(step,&isConstant);
                  if( !isConstant )
                        mistake( Microbe::NonConstantStep );
            }
            
            SourceLineList tempList;
            tempList << SourceLine( fieldMap["initExpression"].string(), 0, -1 );
            
            m_pPic->Sfor( parseWithChild( fieldMap["code"].bracedCode() ), parseWithChild( tempList ), endExpr, variable, step, stepPositive );
      }
      else if( name == "alias" )
      {
            // It is important to get this the right way round!
            // The alias should be the key since two aliases could
            // point to the same name.
      
            QString alias = fieldMap["alias"].string().stripWhiteSpace(); 
            QString dest = fieldMap["dest"].string().stripWhiteSpace();
            
            // Check to see whether or not we've already aliased it...
//          if ( mb->alias(alias) != alias )
//                mistake( Microbe::AliasRedefined );
//          else
                  mb->addAlias( alias, dest );
      }
      else if( name == "increment" )
      {
            QString variableName = fieldMap["variable"].string();
            
            if ( !mb->isVariableKnown( variableName ) )
                  mistake( Microbe::UnknownVariable );
            else if ( !mb->variable( variableName ).isWritable() )
                  mistake( Microbe::ReadOnlyVariable, variableName );
            else
                  m_pPic->SincVar( variableName );
      }
      else if( name == "decrement" )
      {
            QString variableName = fieldMap["variable"].string();
            
            if ( !mb->isVariableKnown( variableName ) )
                  mistake( Microbe::UnknownVariable );
            else if ( !mb->variable( variableName ).isWritable() )
                  mistake( Microbe::ReadOnlyVariable, variableName );
            else
                  m_pPic->SdecVar( variableName );
      }
      else if( name == "rotateleft" )
      {
            QString variableName = fieldMap["variable"].string();
            
            if ( !mb->isVariableKnown( variableName ) )
                  mistake( Microbe::UnknownVariable );
            else if ( !mb->variable( variableName ).isWritable() )
                  mistake( Microbe::ReadOnlyVariable, variableName );
            else
                  m_pPic->SrotlVar( variableName );
      }
      else if( name == "rotateright" )
      {
            QString variableName = fieldMap["variable"].string();
            
            if ( !mb->isVariableKnown( variableName ) )
                  mistake( Microbe::UnknownVariable );
            else if ( !mb->variable( variableName ).isWritable() )
                  mistake( Microbe::ReadOnlyVariable, variableName );
            else
                  m_pPic->SrotrVar( variableName );
      }
      else if( name == "asm" )
      {     
            m_pPic->Sasm( SourceLine::toStringList( fieldMap["code"].bracedCode() ).join("\n") );
      }
      else if( name == "delay" )
      {
            // This is one of the rare occasions that the number will be bigger than a byte,
            // so suppressNumberTooBig must be used
            bool isConstant;
            QString delay = processConstant(fieldMap["expression"].string(),&isConstant,true);
            if (!isConstant)
                  mistake( Microbe::NonConstantDelay );
//          else m_pPic->Sdelay( fieldMap["expression"].string(), "");
            else
            {
                  // TODO We should use the "delay" string returned by processConstant - not the expression (as, e.g. 2*3 won't be ok)
                  int length_ms = literalToInt( fieldMap["expression"].string() );
                  if ( length_ms >= 0 )
                        m_pPic->Sdelay( length_ms * 1000 ); // Pause the delay length in microseconds
                  else
                        mistake( Microbe::NonConstantDelay );
            }
      }
      else if ( name == "keypad" || name == "sevenseg" )
      {
            QStringList pins = QStringList::split( ' ', fieldMap["pinlist"].string() );
            QString variableName = fieldMap["name"].string();
            
            if ( mb->isVariableKnown( variableName ) )
            {
                  mistake( Microbe::VariableRedefined, variableName );
                  return;
            }
            
            PortPinList pinList;
            
            QStringList::iterator end = pins.end();
            for ( QStringList::iterator it = pins.begin(); it != end; ++it )
            {
                  PortPin portPin = m_pPic->toPortPin(*it);
                  if ( portPin.pin() == -1 )
                  {
                        // Invalid port/pin
                        //TODO mistake
                        return;
                  }
                  pinList << portPin;
            }
            
            if ( name == "keypad" )
            {
                  Variable v( Variable::keypadType, variableName );
                  v.setPortPinList( pinList );
                  mb->addVariable( v );
            }
            
            else // name == "sevenseg"
            {
                  if ( pinList.size() != 7 )
                        mistake( Microbe::InvalidPinMapSize );
                  else
                  {
                        Variable v( Variable::sevenSegmentType, variableName );
                        v.setPortPinList( pinList );
                        mb->addVariable( v );
                  }
            }
      }
}


Generated by  Doxygen 1.6.0   Back to index