From 7e0edb6c2db17c87415fbd041ef7add9dfb467e5 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 13 Dec 2016 12:46:09 -0700 Subject: Corrected negation and single value parse bugs. Discovered arithmetic bug in the Number class, -4 + 5 is coming back as -1, not 1. It's getting the sign wrong somehow. I'll have to hunt that down. --- src/lexer.cpp | 12 ++++++--- src/parser.cpp | 24 +++++++++++++----- src/scriptengine.cpp | 70 +++++++++++++++++++++++++++++----------------------- src/token.cpp | 7 +++--- src/token.h | 10 +++++++- src/unitnumber.cpp | 4 +++ 6 files changed, 83 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/lexer.cpp b/src/lexer.cpp index 87d603a..9c8b36a 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -96,7 +96,13 @@ Token Lexer::nextTokenNormal() { sTmp->append( sBuf[iBufPos] ); } - return Token( Token::tCommand, sTmp ); + if( *sTmp == "quit" || *sTmp == "exit" ) + return Token( Token::tCmdExit ); + else if( *sTmp == "scale" ) + return Token( Token::tCmdScale ); + else if( *sTmp == "radix" ) + return Token( Token::tCmdRadix ); + return Token( Token::tCmdExtended, sTmp ); } break; @@ -196,13 +202,13 @@ Token Lexer::nextTokenCommand() if( iBufPos >= sBuf.getSize() ) { iBufPos = -1; - return Token( Token::tEndOfLine ); + return Token( Token::tCmdEndParams ); } if( iBufPos < 0 ) { if( rIn.isEos() ) - return Token( Token::tEndOfInput ); + return Token( Token::tCmdEndParams ); sBuf = rIn.readLine(); if( sBuf.getSize() == 0 ) diff --git a/src/parser.cpp b/src/parser.cpp index 982c342..8e30d24 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -8,7 +8,7 @@ #include #include -// #define DEBUG_MODE 1 +//#define DEBUG_MODE 1 #ifdef DEBUG_MODE #define DBG( x ) { x; } (void)0 #else @@ -161,6 +161,7 @@ void Parser::exprP() return; } + DBG( Bu::sio << "exprP on " << lex[0] << Bu::sio.nl ); switch( lex[0].eType ) { case Token::tNumber: @@ -188,7 +189,7 @@ void Parser::exprP() case Token::tMinus: lex.nextToken(); exprP(); - shift( Token( Token::tNegate ) ); + shift( Token( Token::tNegate ) ); reduce(); break; } @@ -196,7 +197,7 @@ void Parser::exprP() void Parser::statement() { - if( lex[0].eType == Token::tCommand ) + if( (lex[0].eType&Token::mMetaCmd) ) { lex.setMode( Lexer::modeCommand ); output( lex[0] ); @@ -309,7 +310,8 @@ case Token::tCommand: void Parser::shift( const Token &t ) { - if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) + if( (t.eType&(Token::mMetaOperator|Token::mMetaAltOp)) || + t.eType==Token::tCloseParen ) tsTerminal.push( t ); else tsNonTerminal.push( t ); @@ -317,9 +319,20 @@ void Parser::shift( const Token &t ) void Parser::reduce() { - if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) + if( tsTerminal.isEmpty() ) + { + DBG( Bu::sio << "reduce: terminal stack empty." << Bu::sio.nl ); + if( !tsNonTerminal.isEmpty() ) + { + DBG( Bu::sio << " : non-terminal stack non-empty, pushing item." << Bu::sio.nl ); + output( tsNonTerminal.peekPop() ); + } + return; + } + if( tsNonTerminal.peek().eType == Token::tOpenParen ) return; Token tOp = tsTerminal.peekPop(); + DBG( Bu::sio << "recuding on " << tOp << Bu::sio.nl ); switch( tOp.eType ) { /* @@ -416,7 +429,6 @@ int Parser::getPriority( Token::Type eType ) { case Token::tNumber: case Token::tVariable: - case Token::tCommand: return 0; case Token::tPlus: diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index b65db70..e4c5c2e 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp @@ -39,6 +39,12 @@ void ScriptEngine::exec( Expression *pExpr ) for( Expression::iterator i = pExpr->begin(); i; i++ ) { +// Bu::sio << (*i).eType << " - " << sNums << Bu::sio.nl; + if( ((*i).eType&Token::mMetaCmd) ) + { + command( i ); + continue; + } switch( (*i).eType ) { case Token::tNumber: @@ -96,10 +102,6 @@ void ScriptEngine::exec( Expression *pExpr ) case Token::tNegate: sNums.push( -sNums.peekPop() ); break; - - case Token::tCommand: - command( i ); - return; } } @@ -109,35 +111,39 @@ void ScriptEngine::exec( Expression *pExpr ) void ScriptEngine::command( Expression::iterator &i ) { - Bu::String sCmd = *(*i).sVal; - if( sCmd == "exit" || sCmd == "quit" ) + switch( (*i).eType ) { - bRunning = false; - return; - } - else if( sCmd == "scale" ) - { - if( !(++i) ) - { - if( sigError.isSet() ) - sigError("You must provide a positive integer."); + case Token::tCmdExit: + bRunning = false; return; - } - int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); - if( iScale < 0 ) - { - if( sigError.isSet() ) - sigError("You must provide a positive integer."); - return; - } - if( sigMessage.isSet() ) - sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); - for( VarHash::iterator i = hVarState.begin(); i; i++ ) - (*i).setScale( iScale ); - } - else if( sCmd == "radix" ) - { - } + + case Token::tCmdScale: + { + if( !(++i) ) + { + if( sigError.isSet() ) + sigError("You must provide a positive integer."); + return; + } + int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); + if( iScale < 0 ) + { + if( sigError.isSet() ) + sigError("You must provide a positive integer."); + return; + } + if( sigMessage.isSet() ) + sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); + for( VarHash::iterator i = hVarState.begin(); i; i++ ) + (*i).setScale( iScale ); + } + break; + + case Token::tCmdRadix: + break; + + case Token::tCmdExtended: + /* else if( sCmd == "vars" ) { } @@ -146,6 +152,8 @@ void ScriptEngine::command( Expression::iterator &i ) } else { + }*/ + break; } } diff --git a/src/token.cpp b/src/token.cpp index 0c7bda1..ff04e94 100644 --- a/src/token.cpp +++ b/src/token.cpp @@ -45,8 +45,9 @@ Token::~Token() break; case tVariable: - case tCommand: case tString: + case tCmdExtended: + case tCmdParam: delete sVal; break; @@ -64,8 +65,9 @@ Token &Token::operator=( const Token &rhs ) break; case tVariable: - case tCommand: case tString: + case tCmdExtended: + case tCmdParam: delete sVal; break; @@ -87,7 +89,6 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) { case Token::tNumber: return f << "num"; case Token::tVariable: return f << "var"; - case Token::tCommand: return f << "cmd"; case Token::tPlus: return f << "+"; case Token::tMinus: return f << "-"; case Token::tDivide: return f << "/"; diff --git a/src/token.h b/src/token.h index 5bede41..4d738ec 100644 --- a/src/token.h +++ b/src/token.h @@ -15,7 +15,7 @@ public: { tNumber = 0x1001, tVariable = 0x2002, - tCommand = 0x2003, + //tCommand = 0x2003, tPlus = 0x4004, tMinus = 0x4005, tDivide = 0x4006, @@ -34,12 +34,20 @@ public: tUninitialized = 0x0110, tComputedValue = 0x0111, + tCmdExit = 0x0201, + tCmdScale = 0x0202, + tCmdRadix = 0x0203, + tCmdExtended = 0x02f0, + tCmdParam = 0x02f1, + tCmdEndParams = 0x02f2, + mMetaNumber = 0x1000, mMetaString = 0x2000, mMetaOperator = 0x4000, mMetaAltOp = 0x8000, mMetaMeta = 0x0100, + mMetaCmd = 0x0200 }; Token(); diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp index d213ed7..c316d4b 100644 --- a/src/unitnumber.cpp +++ b/src/unitnumber.cpp @@ -89,6 +89,10 @@ void UnitNumber::number1() mathTest("1000902491523000321", *, "3004392012498000700", "3007103450821050020096034077958224700"); + mathTest("-4", -, "5", "-9"); + mathTest("-4", -, "-5", "1"); + mathTest("-4", +, "5", "1"); + mathTest("5", +, "-4", "1"); mathTest("-872", +, "123", "-749"); mathTest("728", +, "-51", "677"); mathTest("44", +, "-55", "-11"); -- cgit v1.2.3