summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2013-05-09 15:24:11 -0600
committerMike Buland <mike@xagasoft.com>2013-05-09 15:24:11 -0600
commitce68e816bd82612c14f3492e8bc969da9bfab06c (patch)
treebe50fa63ce720ecde2748df3df83f38a284c3ff6 /src
parent722e0ef0ea2624c1cd9bd5ca69833e37dc09f97f (diff)
downloadclic-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.cpp2
-rw-r--r--src/number.cpp22
-rw-r--r--src/options.cpp47
-rw-r--r--src/options.h7
-rw-r--r--src/parser.cpp24
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
9Options::Options( int argc, char *argv[] ) 9Options::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
86int 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
12private: 15private:
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: