diff options
author | Mike Buland <eichlan@xagasoft.com> | 2016-12-13 12:46:09 -0700 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2016-12-13 12:46:09 -0700 |
commit | 7e0edb6c2db17c87415fbd041ef7add9dfb467e5 (patch) | |
tree | 2feddf5d1dde80d97b2eefdd299cbebc0d2e30d4 /src | |
parent | 5d59aa3e9dffe2912215335ce0b76c67ebbe5a4e (diff) | |
download | clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.gz clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.bz2 clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.xz clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.cpp | 12 | ||||
-rw-r--r-- | src/parser.cpp | 24 | ||||
-rw-r--r-- | src/scriptengine.cpp | 70 | ||||
-rw-r--r-- | src/token.cpp | 7 | ||||
-rw-r--r-- | src/token.h | 10 | ||||
-rw-r--r-- | src/unitnumber.cpp | 4 |
6 files changed, 83 insertions, 44 deletions
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() | |||
96 | { | 96 | { |
97 | sTmp->append( sBuf[iBufPos] ); | 97 | sTmp->append( sBuf[iBufPos] ); |
98 | } | 98 | } |
99 | return Token( Token::tCommand, sTmp ); | 99 | if( *sTmp == "quit" || *sTmp == "exit" ) |
100 | return Token( Token::tCmdExit ); | ||
101 | else if( *sTmp == "scale" ) | ||
102 | return Token( Token::tCmdScale ); | ||
103 | else if( *sTmp == "radix" ) | ||
104 | return Token( Token::tCmdRadix ); | ||
105 | return Token( Token::tCmdExtended, sTmp ); | ||
100 | } | 106 | } |
101 | break; | 107 | break; |
102 | 108 | ||
@@ -196,13 +202,13 @@ Token Lexer::nextTokenCommand() | |||
196 | if( iBufPos >= sBuf.getSize() ) | 202 | if( iBufPos >= sBuf.getSize() ) |
197 | { | 203 | { |
198 | iBufPos = -1; | 204 | iBufPos = -1; |
199 | return Token( Token::tEndOfLine ); | 205 | return Token( Token::tCmdEndParams ); |
200 | } | 206 | } |
201 | 207 | ||
202 | if( iBufPos < 0 ) | 208 | if( iBufPos < 0 ) |
203 | { | 209 | { |
204 | if( rIn.isEos() ) | 210 | if( rIn.isEos() ) |
205 | return Token( Token::tEndOfInput ); | 211 | return Token( Token::tCmdEndParams ); |
206 | 212 | ||
207 | sBuf = rIn.readLine(); | 213 | sBuf = rIn.readLine(); |
208 | if( sBuf.getSize() == 0 ) | 214 | 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 @@ | |||
8 | #include <bu/sio.h> | 8 | #include <bu/sio.h> |
9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | 10 | ||
11 | // #define DEBUG_MODE 1 | 11 | //#define DEBUG_MODE 1 |
12 | #ifdef DEBUG_MODE | 12 | #ifdef DEBUG_MODE |
13 | #define DBG( x ) { x; } (void)0 | 13 | #define DBG( x ) { x; } (void)0 |
14 | #else | 14 | #else |
@@ -161,6 +161,7 @@ void Parser::exprP() | |||
161 | return; | 161 | return; |
162 | } | 162 | } |
163 | 163 | ||
164 | DBG( Bu::sio << "exprP on " << lex[0] << Bu::sio.nl ); | ||
164 | switch( lex[0].eType ) | 165 | switch( lex[0].eType ) |
165 | { | 166 | { |
166 | case Token::tNumber: | 167 | case Token::tNumber: |
@@ -188,7 +189,7 @@ void Parser::exprP() | |||
188 | case Token::tMinus: | 189 | case Token::tMinus: |
189 | lex.nextToken(); | 190 | lex.nextToken(); |
190 | exprP(); | 191 | exprP(); |
191 | shift( Token( Token::tNegate ) ); | 192 | shift( Token( Token::tNegate ) ); |
192 | reduce(); | 193 | reduce(); |
193 | break; | 194 | break; |
194 | } | 195 | } |
@@ -196,7 +197,7 @@ void Parser::exprP() | |||
196 | 197 | ||
197 | void Parser::statement() | 198 | void Parser::statement() |
198 | { | 199 | { |
199 | if( lex[0].eType == Token::tCommand ) | 200 | if( (lex[0].eType&Token::mMetaCmd) ) |
200 | { | 201 | { |
201 | lex.setMode( Lexer::modeCommand ); | 202 | lex.setMode( Lexer::modeCommand ); |
202 | output( lex[0] ); | 203 | output( lex[0] ); |
@@ -309,7 +310,8 @@ case Token::tCommand: | |||
309 | 310 | ||
310 | void Parser::shift( const Token &t ) | 311 | void Parser::shift( const Token &t ) |
311 | { | 312 | { |
312 | if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) | 313 | if( (t.eType&(Token::mMetaOperator|Token::mMetaAltOp)) || |
314 | t.eType==Token::tCloseParen ) | ||
313 | tsTerminal.push( t ); | 315 | tsTerminal.push( t ); |
314 | else | 316 | else |
315 | tsNonTerminal.push( t ); | 317 | tsNonTerminal.push( t ); |
@@ -317,9 +319,20 @@ void Parser::shift( const Token &t ) | |||
317 | 319 | ||
318 | void Parser::reduce() | 320 | void Parser::reduce() |
319 | { | 321 | { |
320 | if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) | 322 | if( tsTerminal.isEmpty() ) |
323 | { | ||
324 | DBG( Bu::sio << "reduce: terminal stack empty." << Bu::sio.nl ); | ||
325 | if( !tsNonTerminal.isEmpty() ) | ||
326 | { | ||
327 | DBG( Bu::sio << " : non-terminal stack non-empty, pushing item." << Bu::sio.nl ); | ||
328 | output( tsNonTerminal.peekPop() ); | ||
329 | } | ||
330 | return; | ||
331 | } | ||
332 | if( tsNonTerminal.peek().eType == Token::tOpenParen ) | ||
321 | return; | 333 | return; |
322 | Token tOp = tsTerminal.peekPop(); | 334 | Token tOp = tsTerminal.peekPop(); |
335 | DBG( Bu::sio << "recuding on " << tOp << Bu::sio.nl ); | ||
323 | switch( tOp.eType ) | 336 | switch( tOp.eType ) |
324 | { | 337 | { |
325 | /* | 338 | /* |
@@ -416,7 +429,6 @@ int Parser::getPriority( Token::Type eType ) | |||
416 | { | 429 | { |
417 | case Token::tNumber: | 430 | case Token::tNumber: |
418 | case Token::tVariable: | 431 | case Token::tVariable: |
419 | case Token::tCommand: | ||
420 | return 0; | 432 | return 0; |
421 | 433 | ||
422 | case Token::tPlus: | 434 | 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 ) | |||
39 | 39 | ||
40 | for( Expression::iterator i = pExpr->begin(); i; i++ ) | 40 | for( Expression::iterator i = pExpr->begin(); i; i++ ) |
41 | { | 41 | { |
42 | // Bu::sio << (*i).eType << " - " << sNums << Bu::sio.nl; | ||
43 | if( ((*i).eType&Token::mMetaCmd) ) | ||
44 | { | ||
45 | command( i ); | ||
46 | continue; | ||
47 | } | ||
42 | switch( (*i).eType ) | 48 | switch( (*i).eType ) |
43 | { | 49 | { |
44 | case Token::tNumber: | 50 | case Token::tNumber: |
@@ -96,10 +102,6 @@ void ScriptEngine::exec( Expression *pExpr ) | |||
96 | case Token::tNegate: | 102 | case Token::tNegate: |
97 | sNums.push( -sNums.peekPop() ); | 103 | sNums.push( -sNums.peekPop() ); |
98 | break; | 104 | break; |
99 | |||
100 | case Token::tCommand: | ||
101 | command( i ); | ||
102 | return; | ||
103 | } | 105 | } |
104 | } | 106 | } |
105 | 107 | ||
@@ -109,35 +111,39 @@ void ScriptEngine::exec( Expression *pExpr ) | |||
109 | 111 | ||
110 | void ScriptEngine::command( Expression::iterator &i ) | 112 | void ScriptEngine::command( Expression::iterator &i ) |
111 | { | 113 | { |
112 | Bu::String sCmd = *(*i).sVal; | 114 | switch( (*i).eType ) |
113 | if( sCmd == "exit" || sCmd == "quit" ) | ||
114 | { | 115 | { |
115 | bRunning = false; | 116 | case Token::tCmdExit: |
116 | return; | 117 | bRunning = false; |
117 | } | ||
118 | else if( sCmd == "scale" ) | ||
119 | { | ||
120 | if( !(++i) ) | ||
121 | { | ||
122 | if( sigError.isSet() ) | ||
123 | sigError("You must provide a positive integer."); | ||
124 | return; | 118 | return; |
125 | } | 119 | |
126 | int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); | 120 | case Token::tCmdScale: |
127 | if( iScale < 0 ) | 121 | { |
128 | { | 122 | if( !(++i) ) |
129 | if( sigError.isSet() ) | 123 | { |
130 | sigError("You must provide a positive integer."); | 124 | if( sigError.isSet() ) |
131 | return; | 125 | sigError("You must provide a positive integer."); |
132 | } | 126 | return; |
133 | if( sigMessage.isSet() ) | 127 | } |
134 | sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); | 128 | int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); |
135 | for( VarHash::iterator i = hVarState.begin(); i; i++ ) | 129 | if( iScale < 0 ) |
136 | (*i).setScale( iScale ); | 130 | { |
137 | } | 131 | if( sigError.isSet() ) |
138 | else if( sCmd == "radix" ) | 132 | sigError("You must provide a positive integer."); |
139 | { | 133 | return; |
140 | } | 134 | } |
135 | if( sigMessage.isSet() ) | ||
136 | sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); | ||
137 | for( VarHash::iterator i = hVarState.begin(); i; i++ ) | ||
138 | (*i).setScale( iScale ); | ||
139 | } | ||
140 | break; | ||
141 | |||
142 | case Token::tCmdRadix: | ||
143 | break; | ||
144 | |||
145 | case Token::tCmdExtended: | ||
146 | /* | ||
141 | else if( sCmd == "vars" ) | 147 | else if( sCmd == "vars" ) |
142 | { | 148 | { |
143 | } | 149 | } |
@@ -146,6 +152,8 @@ void ScriptEngine::command( Expression::iterator &i ) | |||
146 | } | 152 | } |
147 | else | 153 | else |
148 | { | 154 | { |
155 | }*/ | ||
156 | break; | ||
149 | } | 157 | } |
150 | } | 158 | } |
151 | 159 | ||
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() | |||
45 | break; | 45 | break; |
46 | 46 | ||
47 | case tVariable: | 47 | case tVariable: |
48 | case tCommand: | ||
49 | case tString: | 48 | case tString: |
49 | case tCmdExtended: | ||
50 | case tCmdParam: | ||
50 | delete sVal; | 51 | delete sVal; |
51 | break; | 52 | break; |
52 | 53 | ||
@@ -64,8 +65,9 @@ Token &Token::operator=( const Token &rhs ) | |||
64 | break; | 65 | break; |
65 | 66 | ||
66 | case tVariable: | 67 | case tVariable: |
67 | case tCommand: | ||
68 | case tString: | 68 | case tString: |
69 | case tCmdExtended: | ||
70 | case tCmdParam: | ||
69 | delete sVal; | 71 | delete sVal; |
70 | break; | 72 | break; |
71 | 73 | ||
@@ -87,7 +89,6 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType ) | |||
87 | { | 89 | { |
88 | case Token::tNumber: return f << "num"; | 90 | case Token::tNumber: return f << "num"; |
89 | case Token::tVariable: return f << "var"; | 91 | case Token::tVariable: return f << "var"; |
90 | case Token::tCommand: return f << "cmd"; | ||
91 | case Token::tPlus: return f << "+"; | 92 | case Token::tPlus: return f << "+"; |
92 | case Token::tMinus: return f << "-"; | 93 | case Token::tMinus: return f << "-"; |
93 | case Token::tDivide: return f << "/"; | 94 | 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: | |||
15 | { | 15 | { |
16 | tNumber = 0x1001, | 16 | tNumber = 0x1001, |
17 | tVariable = 0x2002, | 17 | tVariable = 0x2002, |
18 | tCommand = 0x2003, | 18 | //tCommand = 0x2003, |
19 | tPlus = 0x4004, | 19 | tPlus = 0x4004, |
20 | tMinus = 0x4005, | 20 | tMinus = 0x4005, |
21 | tDivide = 0x4006, | 21 | tDivide = 0x4006, |
@@ -34,12 +34,20 @@ public: | |||
34 | tUninitialized = 0x0110, | 34 | tUninitialized = 0x0110, |
35 | tComputedValue = 0x0111, | 35 | tComputedValue = 0x0111, |
36 | 36 | ||
37 | tCmdExit = 0x0201, | ||
38 | tCmdScale = 0x0202, | ||
39 | tCmdRadix = 0x0203, | ||
40 | tCmdExtended = 0x02f0, | ||
41 | tCmdParam = 0x02f1, | ||
42 | tCmdEndParams = 0x02f2, | ||
43 | |||
37 | 44 | ||
38 | mMetaNumber = 0x1000, | 45 | mMetaNumber = 0x1000, |
39 | mMetaString = 0x2000, | 46 | mMetaString = 0x2000, |
40 | mMetaOperator = 0x4000, | 47 | mMetaOperator = 0x4000, |
41 | mMetaAltOp = 0x8000, | 48 | mMetaAltOp = 0x8000, |
42 | mMetaMeta = 0x0100, | 49 | mMetaMeta = 0x0100, |
50 | mMetaCmd = 0x0200 | ||
43 | }; | 51 | }; |
44 | 52 | ||
45 | Token(); | 53 | 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() | |||
89 | mathTest("1000902491523000321", *, "3004392012498000700", | 89 | mathTest("1000902491523000321", *, "3004392012498000700", |
90 | "3007103450821050020096034077958224700"); | 90 | "3007103450821050020096034077958224700"); |
91 | 91 | ||
92 | mathTest("-4", -, "5", "-9"); | ||
93 | mathTest("-4", -, "-5", "1"); | ||
94 | mathTest("-4", +, "5", "1"); | ||
95 | mathTest("5", +, "-4", "1"); | ||
92 | mathTest("-872", +, "123", "-749"); | 96 | mathTest("-872", +, "123", "-749"); |
93 | mathTest("728", +, "-51", "677"); | 97 | mathTest("728", +, "-51", "677"); |
94 | mathTest("44", +, "-55", "-11"); | 98 | mathTest("44", +, "-55", "-11"); |