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 | |
| 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 '')
| -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: |
