diff options
author | Mike Buland <mike@xagasoft.com> | 2013-05-09 15:24:11 -0600 |
---|---|---|
committer | Mike Buland <mike@xagasoft.com> | 2013-05-09 15:24:11 -0600 |
commit | ce68e816bd82612c14f3492e8bc969da9bfab06c (patch) | |
tree | be50fa63ce720ecde2748df3df83f38a284c3ff6 /src | |
parent | 722e0ef0ea2624c1cd9bd5ca69833e37dc09f97f (diff) | |
download | clic-ce68e816bd82612c14f3492e8bc969da9bfab06c.tar.gz clic-ce68e816bd82612c14f3492e8bc969da9bfab06c.tar.bz2 clic-ce68e816bd82612c14f3492e8bc969da9bfab06c.tar.xz clic-ce68e816bd82612c14f3492e8bc969da9bfab06c.zip |
Added better filtering in Number::set, and cli options.
The command line options let you set the initial radix/scale, and
there's a function te test if any number is prime, that's fun.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/number.cpp | 22 | ||||
-rw-r--r-- | src/options.cpp | 47 | ||||
-rw-r--r-- | src/options.h | 7 | ||||
-rw-r--r-- | src/parser.cpp | 24 |
5 files changed, 88 insertions, 14 deletions
diff --git a/src/main.cpp b/src/main.cpp index 8e8c19d..c128dd8 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -377,6 +377,8 @@ int main( int argc, char *argv[] ) | |||
377 | // ordertest(); | 377 | // ordertest(); |
378 | 378 | ||
379 | Lexer lex( sioRaw ); | 379 | Lexer lex( sioRaw ); |
380 | lex.setScale( opt.getScale() ); | ||
381 | lex.setRadix( opt.getRadix() ); | ||
380 | Parser parser( lex, sioRaw ); | 382 | Parser parser( lex, sioRaw ); |
381 | parser.parse(); | 383 | parser.parse(); |
382 | 384 | ||
diff --git a/src/number.cpp b/src/number.cpp index 062e368..eb4d01d 100644 --- a/src/number.cpp +++ b/src/number.cpp | |||
@@ -306,15 +306,22 @@ void Number::set( const Bu::String &sNum ) | |||
306 | } | 306 | } |
307 | for( ; iEnd < sNum.getSize() && sNum[iEnd] == '0'; iEnd++ ) { } | 307 | for( ; iEnd < sNum.getSize() && sNum[iEnd] == '0'; iEnd++ ) { } |
308 | 308 | ||
309 | int iDigit; | ||
309 | for( int j = iPt-1; j >= iEnd; j-- ) | 310 | for( int j = iPt-1; j >= iEnd; j-- ) |
310 | { | 311 | { |
311 | // Bu::println(" -> '%1'").arg( sNum[j] ); | 312 | // Bu::println(" -> '%1'").arg( sNum[j] ); |
312 | if( sNum[j] == '.' ) | 313 | if( sNum[j] == '.' ) |
313 | break; | 314 | break; |
314 | if( sNum[j] >= '0' && sNum[j] <= '9' ) | 315 | if( sNum[j] >= '0' && sNum[j] <= '9' ) |
315 | aInt.append( sNum[j]-'0' ); | 316 | iDigit = sNum[j]-'0'; |
316 | else | 317 | else |
317 | aInt.append( sNum[j]-'a'+10 ); | 318 | iDigit = sNum[j]-'a'+10; |
319 | if( iDigit < 0 || iDigit >= iRadix ) | ||
320 | throw Bu::ExceptionBase(Bu::String( | ||
321 | "Invalid character '%1' in Number::set").arg(sNum[j]). | ||
322 | end().getStr() | ||
323 | ); | ||
324 | aInt.append( iDigit ); | ||
318 | } | 325 | } |
319 | 326 | ||
320 | if( iScale > 0 ) | 327 | if( iScale > 0 ) |
@@ -324,9 +331,16 @@ void Number::set( const Bu::String &sNum ) | |||
324 | { | 331 | { |
325 | // Bu::println(" => '%1'").arg( sNum[j] ); | 332 | // Bu::println(" => '%1'").arg( sNum[j] ); |
326 | if( sNum[j] >= '0' && sNum[j] <= '9' ) | 333 | if( sNum[j] >= '0' && sNum[j] <= '9' ) |
327 | aFrac.set( iFrac++, sNum[j]-'0' ); | 334 | iDigit = sNum[j]-'0'; |
328 | else | 335 | else |
329 | aFrac.set( iFrac++, sNum[j]-'a'+10 ); | 336 | iDigit = sNum[j]-'a'+10; |
337 | |||
338 | if( iDigit < 0 || iDigit >= iRadix ) | ||
339 | throw Bu::ExceptionBase(Bu::String( | ||
340 | "Invalid character '%1' in Number::set").arg(sNum[j]). | ||
341 | end().getStr() | ||
342 | ); | ||
343 | aFrac.set( iFrac++, iDigit ); | ||
330 | if( iFrac >= iScale ) | 344 | if( iFrac >= iScale ) |
331 | break; | 345 | break; |
332 | } | 346 | } |
diff --git a/src/options.cpp b/src/options.cpp index 7f66028..d9cd8f1 100644 --- a/src/options.cpp +++ b/src/options.cpp | |||
@@ -6,12 +6,20 @@ | |||
6 | #include <bu/sio.h> | 6 | #include <bu/sio.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | 8 | ||
9 | Options::Options( int argc, char *argv[] ) | 9 | Options::Options( int argc, char *argv[] ) : |
10 | iScale( 0 ), | ||
11 | iRadix( 10 ) | ||
10 | { | 12 | { |
13 | addOption( iRadix, 'r', "radix", | ||
14 | Bu::String("Set the radix (default: %1)").arg( iRadix ) ); | ||
15 | addOption( iScale, 's', "scale", | ||
16 | Bu::String("Set the scale (default: %1)").arg( iScale ) ); | ||
11 | addOption( Bu::slot(this, &Options::selfTest), "self-test", | 17 | addOption( Bu::slot(this, &Options::selfTest), "self-test", |
12 | "Run a series of tests to ensure everything is working correctly."); | 18 | "Run a series of tests to ensure everything is working correctly."); |
13 | addOption( Bu::slot(this, &Options::textPrimes), "text-primes", | 19 | addOption( Bu::slot(this, &Options::textPrimes), "text-primes", |
14 | "Generate primes in base 36 that only have digits > 9 in them."); | 20 | "Generate primes in base 36 that only have digits > 9 in them."); |
21 | addOption( Bu::slot(this, &Options::isPrime), 'p', "is-prime", | ||
22 | "Test if the given number is prime. Set radix first."); | ||
15 | addHelpOption('h', "help", "This help"); | 23 | addHelpOption('h', "help", "This help"); |
16 | 24 | ||
17 | parse( argc, argv ); | 25 | parse( argc, argv ); |
@@ -75,3 +83,40 @@ int Options::textPrimes( Bu::StringArray ) | |||
75 | return 0; | 83 | return 0; |
76 | } | 84 | } |
77 | 85 | ||
86 | int Options::isPrime( Bu::StringArray aArgs ) | ||
87 | { | ||
88 | Number tst( 0, iRadix ); | ||
89 | Number max( 0, iRadix ); | ||
90 | Number j( 0, iRadix ); | ||
91 | Number one( 0, iRadix ); | ||
92 | Number fact( 0, iRadix ); | ||
93 | one = "1"; | ||
94 | fact = "2"; | ||
95 | |||
96 | Bu::println("Radix: %1").arg( iRadix ); | ||
97 | |||
98 | for( Bu::StringArray::iterator i = aArgs.begin()+1; i; i++ ) | ||
99 | { | ||
100 | tst = *i; | ||
101 | Bu::println("%1").arg( tst ); | ||
102 | max = tst / fact; | ||
103 | bool bPrime = true; | ||
104 | for( j = "2"; j < max; j = j + one ) | ||
105 | { | ||
106 | if( (tst%j).isZero() ) | ||
107 | { | ||
108 | bPrime = false; | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | if( bPrime ) | ||
114 | { | ||
115 | Bu::println("%1").arg( tst ); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | exit( 0 ); | ||
120 | return aArgs.getSize(); | ||
121 | } | ||
122 | |||
diff --git a/src/options.h b/src/options.h index 11bf896..1085e1e 100644 --- a/src/options.h +++ b/src/options.h | |||
@@ -9,9 +9,16 @@ public: | |||
9 | Options( int argc, char *argv[] ); | 9 | Options( int argc, char *argv[] ); |
10 | virtual ~Options(); | 10 | virtual ~Options(); |
11 | 11 | ||
12 | int getScale() const { return iScale; } | ||
13 | int getRadix() const { return iRadix; } | ||
14 | |||
12 | private: | 15 | private: |
13 | int selfTest( Bu::StringArray aArgs ); | 16 | int selfTest( Bu::StringArray aArgs ); |
14 | int textPrimes( Bu::StringArray aArgs ); | 17 | int textPrimes( Bu::StringArray aArgs ); |
18 | int isPrime( Bu::StringArray aArgs ); | ||
19 | |||
20 | int iScale; | ||
21 | int iRadix; | ||
15 | }; | 22 | }; |
16 | 23 | ||
17 | #endif | 24 | #endif |
diff --git a/src/parser.cpp b/src/parser.cpp index 57144c2..38988f5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
@@ -152,22 +152,17 @@ void Parser::parse() | |||
152 | 152 | ||
153 | default: | 153 | default: |
154 | if( tsNonTerminal.getSize() == 0 || | 154 | if( tsNonTerminal.getSize() == 0 || |
155 | getPriority( tsNonTerminal.peek().eType ) < | 155 | getPriority( tsNonTerminal.peek().eType ) <= |
156 | getPriority( t.eType ) ) | 156 | getPriority( t.eType ) ) |
157 | { | 157 | { |
158 | // Bu::println("Pushing non-terminal: %1").arg( t.eType ); | 158 | // Bu::println("Pushing non-terminal: %1").arg( t.eType ); |
159 | tsNonTerminal.push( t ); | 159 | tsNonTerminal.push( t ); |
160 | |||
161 | // for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) Bu::print(" [%1]").arg( *(*i).nVal ); Bu::println(""); | ||
162 | // for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) Bu::print(" <%1>").arg( (*i).eType ); Bu::println(""); | ||
163 | } | 160 | } |
164 | else | 161 | else |
165 | { | 162 | { |
166 | // Bu::println("Unwinding stack before pushing: %1").arg( t.eType ); | 163 | // Bu::println("Unwinding stack before pushing: %1").arg( t.eType ); |
167 | unwind(); | 164 | unwind(); |
168 | tsNonTerminal.push( t ); | 165 | tsNonTerminal.push( t ); |
169 | // for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) Bu::print(" [%1]").arg( *(*i).nVal ); Bu::println(""); | ||
170 | // for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) Bu::print(" <%1>").arg( (*i).eType ); Bu::println(""); | ||
171 | } | 166 | } |
172 | break; | 167 | break; |
173 | } | 168 | } |
@@ -178,8 +173,19 @@ void Parser::unwind() | |||
178 | { | 173 | { |
179 | for(;;) | 174 | for(;;) |
180 | { | 175 | { |
181 | // for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) Bu::print(" [%1]").arg( *(*i).nVal ); Bu::println(""); | 176 | /* |
182 | // for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) Bu::print(" <%1>").arg( (*i).eType ); Bu::println(""); | 177 | for( TokenStack::iterator i = tsTerminal.begin(); i; i++ ) |
178 | { | ||
179 | if( (*i).eType == Token::tNumber ) | ||
180 | Bu::print(" [%1]").arg( *(*i).nVal ); | ||
181 | else | ||
182 | Bu::print(" [%1]").arg( *(*i).sVal ); | ||
183 | } | ||
184 | Bu::println(""); | ||
185 | for( TokenStack::iterator i = tsNonTerminal.begin(); i; i++ ) | ||
186 | Bu::print(" <%1>").arg( (*i).eType ); | ||
187 | Bu::println(""); | ||
188 | */ | ||
183 | if( tsNonTerminal.isEmpty() ) | 189 | if( tsNonTerminal.isEmpty() ) |
184 | return; | 190 | return; |
185 | 191 | ||
@@ -330,7 +336,6 @@ int Parser::getPriority( Token::Type eType ) | |||
330 | case Token::tNumber: | 336 | case Token::tNumber: |
331 | case Token::tVariable: | 337 | case Token::tVariable: |
332 | case Token::tCommand: | 338 | case Token::tCommand: |
333 | case Token::tEquals: | ||
334 | return 0; | 339 | return 0; |
335 | 340 | ||
336 | case Token::tPlus: | 341 | case Token::tPlus: |
@@ -348,6 +353,7 @@ int Parser::getPriority( Token::Type eType ) | |||
348 | 353 | ||
349 | case Token::tEndOfLine: | 354 | case Token::tEndOfLine: |
350 | case Token::tEndOfInput: | 355 | case Token::tEndOfInput: |
356 | case Token::tEquals: | ||
351 | return -1; | 357 | return -1; |
352 | 358 | ||
353 | default: | 359 | default: |