00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "btreebase.h"
00022 #include "expression.h"
00023 #include "instruction.h"
00024 #include "parser.h"
00025 #include "pic14.h"
00026 #include "traverser.h"
00027
00028 #include <cassert>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <qfile.h>
00032 #include <qregexp.h>
00033 #include <qstring.h>
00034
00035 #include <iostream>
00036 using namespace std;
00037
00038
00039
00040 Parser::Parser( Microbe * _mb )
00041 {
00042 m_code = 0;
00043 m_pPic = 0;
00044 mb = _mb;
00045
00046 StatementDefinition definition;
00047
00048 definition.append( Field(Field::Label, "label") );
00049 m_definitionMap["goto"] = definition;
00050 definition.clear();
00051
00052 definition.append( Field(Field::Label, "label") );
00053 m_definitionMap["call"] = definition;
00054 definition.clear();
00055
00056 definition.append( Field(Field::Expression, "expression") );
00057 definition.append( Field(Field::Code, "code") );
00058 m_definitionMap["while"] = definition;
00059 definition.clear();
00060
00061 m_definitionMap["end"] = definition;
00062 definition.clear();
00063
00064 definition.append( Field(Field::Label, "label") );
00065 definition.append( Field(Field::Code, "code") );
00066
00067 m_definitionMap["sub"] = definition;
00068 m_definitionMap["subroutine"] = definition;
00069 definition.clear();
00070
00071 definition.append( Field(Field::Label, "label") );
00072 definition.append( Field(Field::Code, "code") );
00073 m_definitionMap["interrupt"] = definition;
00074 definition.clear();
00075
00076 definition.append( Field(Field::Label, "alias") );
00077 definition.append( Field(Field::Label, "dest") );
00078 m_definitionMap["alias"] = definition;
00079 definition.clear();
00080
00081 definition.append( Field(Field::Expression, "expression") );
00082 definition.append( Field(Field::FixedString, 0, "then", true) );
00083 definition.append( Field(Field::Code, "ifCode") );
00084 definition.append( Field(Field::Newline) );
00085 definition.append( Field(Field::FixedString, 0, "else", false) );
00086 definition.append( Field(Field::Code, "elseCode") );
00087 m_definitionMap["if"] = definition;
00088 definition.clear();
00089
00090 definition.append( Field(Field::Expression, "initExpression") );
00091 definition.append( Field(Field::FixedString, 0, "to", true) );
00092 definition.append( Field(Field::Expression, "toExpression") );
00093 definition.append( Field(Field::FixedString, 0, "step", false) );
00094 definition.append( Field(Field::Expression, "stepExpression") );
00095 definition.append( Field(Field::Code, "code") );
00096 m_definitionMap["for"] = definition;
00097 definition.clear();
00098
00099 definition.append( Field(Field::Variable, "variable") );
00100 m_definitionMap["decrement"] = definition;
00101 definition.clear();
00102
00103 definition.append( Field(Field::Variable, "variable") );
00104 m_definitionMap["increment"] = definition;
00105 definition.clear();
00106
00107 definition.append( Field(Field::Variable, "variable") );
00108 m_definitionMap["rotateleft"] = definition;
00109 definition.clear();
00110
00111 definition.append( Field(Field::Variable, "variable") );
00112 m_definitionMap["rotateright"] = definition;
00113 definition.clear();
00114
00115 definition.append( Field(Field::Code, "code") );
00116 m_definitionMap["asm"] = definition;
00117 definition.clear();
00118
00119 definition.append( Field(Field::Expression, "expression") );
00120 m_definitionMap["delay"] = definition;
00121 definition.clear();
00122
00123 definition.append( Field(Field::Code, "code") );
00124 definition.append( Field(Field::Newline) );
00125 definition.append( Field(Field::FixedString, 0, "until", true) );
00126 definition.append( Field(Field::Expression, "expression") );
00127 m_definitionMap["repeat"] = definition;
00128 definition.clear();
00129
00130 definition.append( Field(Field::Name, "name") );
00131 definition.append( Field(Field::PinList, "pinlist") );
00132 m_definitionMap["sevenseg"] = definition;
00133 definition.clear();
00134
00135 definition.append( Field(Field::Name, "name") );
00136 definition.append( Field(Field::PinList, "pinlist") );
00137 m_definitionMap["keypad"] = definition;
00138 definition.clear();
00139 }
00140
00141 Parser::~Parser()
00142 {
00143 }
00144
00145 Parser* Parser::createChildParser()
00146 {
00147 Parser * parser = new Parser( mb );
00148
00149 return parser;
00150 }
00151
00152
00153 Code * Parser::parseWithChild( const SourceLineList & lines )
00154 {
00155 Parser *p = createChildParser();
00156 Code *code = p->parse(lines);
00157 delete p;
00158 return code;
00159 }
00160
00161 Code * Parser::parse( const SourceLineList & lines )
00162 {
00163 StatementList sList;
00164 m_pPic = mb->makePic();
00165 m_code = new Code();
00166 m_pPic->setCode( m_code );
00167 m_pPic->setParser(this);
00168 m_bPassedEnd = false;
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 SourceLineList::const_iterator end = lines.end();
00179 for ( SourceLineList::const_iterator slit = lines.begin(); slit != end; ++slit) {
00180 Statement s;
00181 s.content = *slit;
00182
00183
00184 SourceLineList::const_iterator previous = slit;
00185 if ( (++slit != end) && (*slit).text() == "{" )
00186 s.bracedCode = getBracedCode( & slit, end );
00187 else slit = previous;
00188
00189 if(!s.text().isEmpty()) sList.append(s);
00190 }
00191
00192 mb->resetDest();
00193
00194 for(StatementList::Iterator sit = sList.begin(); sit != sList.end(); ++sit) {
00195 m_currentSourceLine = (*sit).content;
00196
00197 QString line = (*sit).text();
00198
00199 QString command;
00200 {
00201 int spacepos = line.find(' ');
00202 if ( spacepos >= 0 ) command = line.left( spacepos );
00203 else command = line;
00204 }
00205 OutputFieldMap fieldMap;
00206
00207 if ( (*sit).content.line() >= 0 )
00208 m_code->append( new Instr_sourceCode( QString("#MSRC\t%1; %2\t%3").arg( (*sit).content.line() + 1 ).arg( (*sit).content.url() ).arg( (*sit).content.text() ) ));
00209 bool showBracesInSource = (*sit).hasBracedCode();
00210 if ( showBracesInSource )
00211 m_code->append(new Instr_sourceCode("{"));
00212
00213
00214 DefinitionMap::Iterator dmit = m_definitionMap.find(command);
00215 if(dmit == m_definitionMap.end()) {
00216 if(!processAssignment( (*sit).text())) {
00217
00218 if( (*sit).isLabel() ) {
00219 QString label = (*sit).text().left( (*sit).text().length() - 1 );
00221 m_pPic->Slabel( label );
00222 } else mistake( Microbe::Microbe::UnknownStatement );
00223 }
00224
00225 continue;
00226 }
00227 StatementDefinition definition = dmit.data();
00228
00229
00230 int newPosition = 0;
00231 int position = command.length() + 1;
00232
00233
00234 Field nextField;
00235 Statement nextStatement;
00236
00237 bool errorInLine = false;
00238 bool finishLine = false;
00239
00240 for(StatementDefinition::Iterator sdit = definition.begin(); sdit != definition.end(); ++sdit) {
00241
00242
00243
00244 if( errorInLine || finishLine) break;
00245
00246 Field field = (*sdit);
00247 QString token;
00248
00249 bool saveToken = false;
00250 bool saveBraced = false;
00251 bool saveSingleLine = false;
00252
00253 switch(field.type()) {
00254 case (Field::Label):
00255 case (Field::Variable):
00256 case (Field::Name):
00257 {
00258 newPosition = line.find( ' ', position );
00259 if(position == newPosition) {
00260 newPosition = -1;
00261 token = line.mid(position);
00262 } else token = line.mid(position, newPosition - position);
00263 if( token.isEmpty() ) {
00264 if(field.type() == Field::Label)
00265 mistake( Microbe::Microbe::LabelExpected );
00266 else if (field.type() == Field::Variable)
00267 mistake( Microbe::VariableExpected );
00268 else
00269 mistake( Microbe::NameExpected );
00270 errorInLine = true;
00271 continue;
00272 }
00273 position = newPosition;
00274 saveToken = true;
00275 break;
00276 }
00277
00278 case (Field::Expression):
00279 {
00280
00281
00282
00283 StatementDefinition::Iterator it(sdit);
00284 ++it;
00285 if( it != definition.end() ) {
00286 nextField = (*it);
00287 if(nextField.type() == Field::FixedString)
00288 newPosition = line.find(QRegExp("\\b" + nextField.string() + "\\b"));
00289
00290
00291 else if(nextField.type() == Field::Code) {
00292 newPosition = line.find("{");
00293 if(newPosition == -1) newPosition = line.length() + 1;
00294 } else if(nextField.type() == Field::Newline)
00295 newPosition = line.length()+1;
00296 else kdDebug() << "Bad statement definition - awkward field type after expression";
00297 } else newPosition = line.length() + 1;
00298
00299 if(newPosition == -1) {
00300
00301
00302 }
00303 token = line.mid(position, newPosition - position);
00304 position = newPosition;
00305 saveToken = true;
00306 }
00307 break;
00308
00309 case (Field::PinList):
00310 {
00311
00312
00313
00314
00315 token = line.mid( position + 1 );
00316 position = line.length() + 1;
00317
00318 if ( token.isEmpty() )
00319 mistake( Microbe::PinListExpected );
00320 else saveToken = true;
00321
00322 break;
00323 }
00324
00325 case (Field::Code):
00326 if ( !(*sit).hasBracedCode() ) {
00327 saveSingleLine = true;
00328 token = line.mid(position);
00329 position = line.length() + 1;
00330 } else if( position != -1 && position <= int(line.length()) )
00331 {
00332 mistake( Microbe::UnexpectedStatementBeforeBracket );
00333 errorInLine = true;
00334 continue;
00335 } else {
00336
00337
00338 saveBraced = true;
00339 }
00340 break;
00341
00342 case (Field::FixedString):
00343 {
00344
00345 int stringPosition = line.find(QRegExp("\\b"+field.string()+"\\b"));
00346 if( stringPosition != position || stringPosition == -1 ) {
00347 if( !field.compulsory() )
00348 {
00349 position = -1;
00350
00351 ++sdit;
00352 continue;
00353 } else {
00354
00355 mistake( Microbe::FixedStringExpected, field.string() );
00356 errorInLine = true;
00357 continue;
00358 }
00359 } else {
00360 position += field.string().length() + 1;
00361 }
00362 }
00363 break;
00364
00365 case (Field::Newline):
00366
00367
00368
00369
00370
00371 nextField = *(++StatementDefinition::Iterator(sdit));
00372 if( nextField.type() == Field::FixedString )
00373 {
00374 nextStatement = *(++StatementList::Iterator(sit));
00375 newPosition = nextStatement.text().find(QRegExp("\\b" + nextField.string() + "\\b"));
00376 if(newPosition != 0)
00377 {
00378
00379
00380 if(!nextField.compulsory()) continue;
00381
00382 }
00383 position = 0;
00384 line = (*(++sit)).text();
00385 m_currentSourceLine = (*sit).content;
00386 }
00387
00388 break;
00389
00390 case (Field::None):
00391
00392 break;
00393 }
00394
00395 if ( saveToken )
00396 fieldMap[field.key()] = OutputField( token );
00397
00398 if(saveSingleLine) {
00399 SourceLineList list;
00400 list << SourceLine( token, 0, -1 );
00401 fieldMap[field.key()] = OutputField( list );
00402 }
00403
00404 if(saveBraced)
00405 fieldMap[field.key()] = OutputField( (*sit).bracedCode );
00406
00407 }
00408
00409
00410
00411 if(position != -1 && position <= int(line.length())) {
00412 mistake( Microbe::TooManyTokens );
00413 errorInLine = true;
00414 }
00415
00416 if(errorInLine) continue;
00417
00418
00419 processStatement( command, fieldMap );
00420
00421 if(showBracesInSource)
00422 m_code->append(new Instr_sourceCode("}"));
00423 }
00424
00425 delete m_pPic;
00426 m_pPic = 0;
00427 return m_code;
00428 }
00429
00430 bool Parser::processAssignment(const QString &line)
00431 {
00432 QStringList tokens = Statement::tokenise(line);
00433
00434
00435 if(tokens.size() < 3) return false;
00436
00437 QString firstToken = tokens[0];
00438
00439 firstToken = mb->alias(firstToken);
00440
00441
00442
00443
00444
00445
00446 if ( firstToken.contains(".") ) {
00447 PortPin portPin = m_pPic->toPortPin( firstToken );
00448
00449
00450 if ( portPin.pin() == -1 )
00451 mistake( Microbe::InvalidPort, firstToken );
00452
00453 if ( tokens[1] != "=" )
00454 mistake( Microbe::UnassignedPin );
00455
00456 QString state = tokens[2];
00457 if( state == "high" )
00458 m_pPic->Ssetlh( portPin, true );
00459 else if( state == "low" )
00460 m_pPic->Ssetlh( portPin, false );
00461 else mistake( Microbe::NonHighLowPinState );
00462 }
00463
00464 else if(m_pPic->isValidPort(firstToken)) {
00465
00466 if ( tokens[1] != "=" )
00467 mistake( Microbe::UnassignedPort, tokens[1] );
00468
00469 Expression( m_pPic, mb, m_currentSourceLine, false ).compileExpression(line.mid(line.find("=")+1));
00470 m_pPic->saveResultToVar( firstToken );
00471 } else if(m_pPic->isValidTris( firstToken)) {
00472 if(tokens[1] == "=") {
00473 Expression( m_pPic, mb, m_currentSourceLine, false ).compileExpression(line.mid(line.find("=")+1));
00474 m_pPic->Stristate(firstToken);
00475 }
00476 } else {
00477
00478 if(tokens[1] != "=") return false;
00479
00480 if(!mb->isValidVariableName(firstToken)) {
00481 mistake( Microbe::InvalidVariableName, firstToken );
00482 return true;
00483 }
00484
00485
00486
00487 mb->addVariable( Variable( Variable::charType, firstToken ) );
00488
00489 Expression( m_pPic, mb, m_currentSourceLine, false ).compileExpression(line.mid(line.find("=")+1));
00490
00491 Variable v = mb->variable( firstToken );
00492 switch(v.type()) {
00493 case Variable::charType:
00494 m_pPic->saveResultToVar( v.name() );
00495 break;
00496
00497 case Variable::keypadType:
00498 mistake( Microbe::ReadOnlyVariable, v.name() );
00499 break;
00500
00501 case Variable::sevenSegmentType:
00502 m_pPic->SsevenSegment( v );
00503 break;
00504
00505 case Variable::invalidType:
00506
00507 break;
00508 }
00509 }
00510
00511 return true;
00512 }
00513
00514 SourceLineList Parser::getBracedCode( SourceLineList::const_iterator * it, SourceLineList::const_iterator end )
00515 {
00516
00517
00518
00519 assert( (**it).text() == "{" );
00520
00521 SourceLineList braced;
00522
00523
00524 unsigned level = 1;
00525 ++(*it);
00526
00527 for( ; *it != end; ++(*it)) {
00528 if ( (**it).text() == "{" ) level++;
00529 else if ( (**it).text() == "}" )
00530 level--;
00531
00532 if(level == 0)return braced;
00533 braced << **it;
00534 }
00535
00536
00537 return braced;
00538 }
00539
00540 void Parser::processStatement( const QString & name, const OutputFieldMap & fieldMap )
00541 {
00542
00543
00544
00545
00546 if ( name == "goto" )
00547 m_pPic->Sgoto(fieldMap["label"].string());
00548 else if ( name == "call" )
00549 m_pPic->Scall(fieldMap["label"].string());
00550 else if ( name == "while" )
00551 m_pPic->Swhile( parseWithChild(fieldMap["code"].bracedCode() ), fieldMap["expression"].string() );
00552 else if ( name == "repeat" )
00553 m_pPic->Srepeat( parseWithChild(fieldMap["code"].bracedCode() ), fieldMap["expression"].string() );
00554 else if ( name == "if" )
00555 m_pPic->Sif(
00556 parseWithChild(fieldMap["ifCode"].bracedCode() ),
00557 parseWithChild(fieldMap["elseCode"].bracedCode() ),
00558 fieldMap["expression"].string() );
00559 else if(name == "sub" || name == "subroutine" ) {
00560 if(!m_bPassedEnd) {
00561 mistake( Microbe::InterruptBeforeEnd );
00562 } else {
00563 m_pPic->Ssubroutine( fieldMap["label"].string(), parseWithChild( fieldMap["code"].bracedCode() ) );
00564 }
00565 } else if( name == "interrupt" ) {
00566 QString interrupt = fieldMap["label"].string();
00567
00568 if(!m_bPassedEnd)
00569 {
00570 mistake( Microbe::InterruptBeforeEnd );
00571 }
00572 else if( !m_pPic->isValidInterrupt( interrupt ) )
00573 {
00574 mistake( Microbe::InvalidInterrupt );
00575 }
00576 else if ( mb->isInterruptUsed( interrupt ) )
00577 {
00578 mistake( Microbe::InterruptRedefined );
00579 } else {
00580 mb->setInterruptUsed( interrupt );
00581 m_pPic->Sinterrupt( interrupt, parseWithChild( fieldMap["code"].bracedCode() ) );
00582 }
00583 } else if( name == "end" ) {
00585 m_bPassedEnd = true;
00586 m_pPic->Send();
00587 } else if( name == "for" ) {
00588 QString step = fieldMap["stepExpression"].string();
00589 bool stepPositive;
00590
00591 if(fieldMap["stepExpression"].found()) {
00592 if(step.left(1) == "+") {
00593 stepPositive = true;
00594 step = step.mid(1).stripWhiteSpace();
00595 } else if(step.left(1) == "-") {
00596 stepPositive = false;
00597 step = step.mid(1).stripWhiteSpace();
00598 } else stepPositive = true;
00599 } else {
00600 step = "1";
00601 stepPositive = true;
00602 }
00603
00604 QString variable = fieldMap["initExpression"].string().mid(0,fieldMap["initExpression"].string().find("=")).stripWhiteSpace();
00605 QString endExpr = variable+ " <= " + fieldMap["toExpression"].string().stripWhiteSpace();
00606
00607 if(fieldMap["stepExpression"].found()) {
00608 bool isConstant;
00609 step = processConstant(step,&isConstant);
00610 if( !isConstant )
00611 mistake( Microbe::NonConstantStep );
00612 }
00613
00614 SourceLineList tempList;
00615 tempList << SourceLine( fieldMap["initExpression"].string(), 0, -1 );
00616
00617 m_pPic->Sfor( parseWithChild( fieldMap["code"].bracedCode() ), parseWithChild( tempList ), endExpr, variable, step, stepPositive );
00618 } else if( name == "alias" ) {
00619
00620
00621
00622
00623 QString alias = fieldMap["alias"].string().stripWhiteSpace();
00624 QString dest = fieldMap["dest"].string().stripWhiteSpace();
00625
00626
00627
00628
00629
00630 mb->addAlias( alias, dest );
00631 } else if(name == "increment") {
00632 QString variableName = fieldMap["variable"].string();
00633
00634 if ( !mb->isVariableKnown( variableName ) )
00635 mistake( Microbe::UnknownVariable );
00636 else if ( !mb->variable( variableName ).isWritable() )
00637 mistake( Microbe::ReadOnlyVariable, variableName );
00638 else
00639 m_pPic->SincVar( variableName );
00640 } else if( name == "decrement" ) {
00641 QString variableName = fieldMap["variable"].string();
00642
00643 if ( !mb->isVariableKnown( variableName ) )
00644 mistake( Microbe::UnknownVariable );
00645 else if ( !mb->variable( variableName ).isWritable() )
00646 mistake( Microbe::ReadOnlyVariable, variableName );
00647 else
00648 m_pPic->SdecVar( variableName );
00649 } else if( name == "rotateleft" ) {
00650 QString variableName = fieldMap["variable"].string();
00651
00652 if ( !mb->isVariableKnown( variableName ) )
00653 mistake( Microbe::UnknownVariable );
00654 else if ( !mb->variable( variableName ).isWritable() )
00655 mistake( Microbe::ReadOnlyVariable, variableName );
00656 else
00657 m_pPic->SrotlVar( variableName );
00658 } else if( name == "rotateright" ) {
00659 QString variableName = fieldMap["variable"].string();
00660
00661 if ( !mb->isVariableKnown( variableName ) )
00662 mistake( Microbe::UnknownVariable );
00663 else if ( !mb->variable( variableName ).isWritable() )
00664 mistake( Microbe::ReadOnlyVariable, variableName );
00665 else
00666 m_pPic->SrotrVar( variableName );
00667 } else if( name == "asm" ) {
00668 m_pPic->Sasm( SourceLine::toStringList( fieldMap["code"].bracedCode() ).join("\n") );
00669 } else if( name == "delay" ) {
00670
00671
00672 bool isConstant;
00673 QString delay = processConstant(fieldMap["expression"].string(),&isConstant,true);
00674 if (!isConstant)
00675 mistake( Microbe::NonConstantDelay );
00676
00677 else {
00678
00679 int length_ms = literalToInt( fieldMap["expression"].string() );
00680 if ( length_ms >= 0 )
00681 m_pPic->Sdelay( length_ms * 1000 );
00682 else mistake( Microbe::NonConstantDelay );
00683 }
00684 } else if ( name == "keypad" || name == "sevenseg" ) {
00685 QStringList pins = QStringList::split( ' ', fieldMap["pinlist"].string() );
00686 QString variableName = fieldMap["name"].string();
00687
00688 if ( mb->isVariableKnown( variableName ) ) {
00689 mistake( Microbe::VariableRedefined, variableName );
00690 return;
00691 }
00692
00693 PortPinList pinList;
00694
00695 QStringList::iterator end = pins.end();
00696 for(QStringList::iterator it = pins.begin(); it != end; ++it) {
00697 PortPin portPin = m_pPic->toPortPin(*it);
00698 if ( portPin.pin() == -1 ) {
00699
00700
00701 return;
00702 }
00703 pinList << portPin;
00704 }
00705
00706 if ( name == "keypad" ) {
00707 Variable v( Variable::keypadType, variableName );
00708 v.setPortPinList( pinList );
00709 mb->addVariable( v );
00710 } else
00711 {
00712 if ( pinList.size() != 7 )
00713 mistake( Microbe::InvalidPinMapSize );
00714 else {
00715 Variable v( Variable::sevenSegmentType, variableName );
00716 v.setPortPinList( pinList );
00717 mb->addVariable( v );
00718 }
00719 }
00720 }
00721 }
00722
00723 void Parser::mistake( Microbe::MistakeType type, const QString & context )
00724 {
00725 mb->compileError( type, context, m_currentSourceLine );
00726 }
00727
00728
00729 QStringList Statement::tokenise(const QString &line)
00730 {
00731 QStringList result;
00732 QString current;
00733 int count = 0;
00734
00735 for(int i = 0; i < int(line.length()); i++) {
00736 QChar nextChar = line[i];
00737 if( nextChar.isSpace() ) {
00738 if( count > 0 ) {
00739 result.append(current);
00740 current = "";
00741 count = 0;
00742 }
00743 } else if(nextChar == '=') {
00744 if( count > 0 ) result.append(current);
00745 current = "";
00746 count = 0;
00747 result.append("=");
00748 } else if(nextChar == '{') {
00749 if( count > 0 ) result.append(current);
00750 current = "";
00751 count = 0;
00752 result.append("{");
00753 } else {
00754 count++;
00755 current.append(nextChar);
00756 }
00757 }
00758 if( count > 0 ) result.append(current);
00759 return result;
00760 }
00761
00762 int Parser::doArithmetic(int lvalue, int rvalue, Expression::Operation op)
00763 {
00764 switch(op) {
00765 case Expression::noop: return 0;
00766 case Expression::addition: return lvalue + rvalue;
00767 case Expression::subtraction: return lvalue - rvalue;
00768 case Expression::multiplication: return lvalue * rvalue;
00769 case Expression::division: return lvalue / rvalue;
00770 case Expression::exponent: return lvalue ^ rvalue;
00771 case Expression::equals: return lvalue == rvalue;
00772 case Expression::notequals: return !(lvalue == rvalue);
00773 case Expression::bwand: return lvalue & rvalue;
00774 case Expression::bwor: return lvalue | rvalue;
00775 case Expression::bwxor: return lvalue ^ rvalue;
00776 case Expression::bwnot: return !rvalue;
00777 case Expression::le: return lvalue <= rvalue;
00778 case Expression::ge: return lvalue >= rvalue;
00779 case Expression::lt: return lvalue < rvalue;
00780 case Expression::gt: return lvalue > rvalue;
00781
00782 case Expression::pin:
00783 case Expression::notpin:
00784 case Expression::function:
00785 case Expression::divbyzero:
00786 case Expression::read_keypad:
00787
00788 break;
00789 }
00790 return -1;
00791 }
00792
00793 bool Parser::isLiteral( const QString &text )
00794 {
00795 bool ok;
00796 literalToInt( text, & ok );
00797 return ok;
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 int Parser::literalToInt(const QString &literal, bool *ok )
00813 {
00814 bool temp;
00815 if ( !ok ) ok = &temp;
00816
00817 *ok = true;
00818
00819 int value = -1;
00820
00821
00822
00823
00824
00825 if( literal.left(2) == "b'" && literal.right(1) == "'" ) {
00826 value = literal.mid(2,literal.length() - 3).toInt(ok,2);
00827 return *ok ? value : -1;
00828 }
00829
00830
00831 if( literal.left(2) == "h'" && literal.right(1) == "'" ) {
00832 value = literal.mid(2,literal.length() - 3).toInt(ok,16);
00833 return *ok ? value : -1;
00834 }
00835
00836
00837
00838 value = literal.toInt( ok, 0 );
00839 return *ok ? value : -1;
00840 }
00841
00842 void Parser::compileConditionalExpression( const QString & expression, Code * ifCode, Code * elseCode ) const
00843 {
00845
00846 Expression( m_pPic, mb, m_currentSourceLine, false ).compileConditional(expression,ifCode,elseCode);
00847 }
00848
00849 QString Parser::processConstant(const QString &expression, bool * isConstant, bool suppressNumberTooBig) const
00850 {
00851 return Expression( m_pPic, mb, m_currentSourceLine, suppressNumberTooBig ).processConstant(expression, isConstant);
00852 }
00853
00854
00855
00856 Field::Field()
00857 {
00858 m_type = None;
00859 m_compulsory = false;
00860 }
00861
00862 Field::Field( Type type, const QString & key )
00863 {
00864 m_type = type;
00865 m_compulsory = false;
00866 m_key = key;
00867 }
00868
00869 Field::Field( Type type, const QString & key, const QString & string, bool compulsory )
00870 {
00871 m_type = type;
00872 m_compulsory = compulsory;
00873 m_key = key;
00874 m_string = string;
00875 }
00876
00877
00878
00879 OutputField::OutputField()
00880 {
00881 m_found = false;
00882 }
00883
00884 OutputField::OutputField( const SourceLineList & bracedCode )
00885 {
00886 m_bracedCode = bracedCode;
00887 m_found = true;
00888 }
00889
00890 OutputField::OutputField( const QString & string )
00891 {
00892 m_string = string;
00893 m_found = true;
00894 }
00895
00896
00897 #if 0
00898
00899
00900 else if( firstToken == "include" )
00901 {
00902
00903
00904 QString filename = (*sit).content.mid( (*sit).content.find("\"") ).stripWhiteSpace();
00905
00906
00907
00908 filename = filename.mid(1);
00909 filename = filename.mid(0,filename.length()-1);
00910 QFile includeFile(filename);
00911 if( includeFile.open(IO_ReadOnly) )
00912 {
00913 QTextStream stream( &includeFile );
00914 QStringList includeCode;
00915 while( !stream.atEnd() )
00916 {
00917 includeCode += stream.readLine();
00918 }
00920
00921 includeFile.close();
00922 }
00923 else
00924 mistake( Microbe::UnopenableInclude, filename );
00925 }
00926 #endif
00927