|  | ################################################################################ | 
|  | # | 
|  | # Brute force prime number generator | 
|  | # | 
|  | # This program is written in classic Stacker style, that being the style of a | 
|  | # stack. Start at the bottom and read your way up ! | 
|  | # | 
|  | # Reid Spencer - Nov 2003 | 
|  | ################################################################################ | 
|  | # Utility definitions | 
|  | ################################################################################ | 
|  | : print >d CR ; | 
|  | : it_is_a_prime TRUE ; | 
|  | : it_is_not_a_prime FALSE ; | 
|  | : continue_loop TRUE ; | 
|  | : exit_loop FALSE; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition tryies an actual division of a candidate prime number. It | 
|  | # determines whether the division loop on this candidate should continue or | 
|  | # not. | 
|  | # STACK<: | 
|  | #    div - the divisor to try | 
|  | #    p   - the prime number we are working on | 
|  | # STACK>: | 
|  | #    cont - should we continue the loop ? | 
|  | #    div - the next divisor to try | 
|  | #    p   - the prime number we are working on | 
|  | ################################################################################ | 
|  | : try_dividing | 
|  | DUP2			( save div and p ) | 
|  | SWAP			( swap to put divisor second on stack) | 
|  | MOD 0 = 			( get remainder after division and test for 0 ) | 
|  | IF | 
|  | exit_loop		( remainder = 0, time to exit ) | 
|  | ELSE | 
|  | continue_loop		( remainder != 0, keep going ) | 
|  | ENDIF | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This function tries one divisor by calling try_dividing. But, before doing | 
|  | # that it checks to see if the value is 1. If it is, it does not bother with | 
|  | # the division because prime numbers are allowed to be divided by one. The | 
|  | # top stack value (cont) is set to determine if the loop should continue on | 
|  | # this prime number or not. | 
|  | # STACK<: | 
|  | #    cont - should we continue the loop (ignored)? | 
|  | #    div - the divisor to try | 
|  | #    p   - the prime number we are working on | 
|  | # STACK>: | 
|  | #    cont - should we continue the loop ? | 
|  | #    div - the next divisor to try | 
|  | #    p   - the prime number we are working on | 
|  | ################################################################################ | 
|  | : try_one_divisor | 
|  | DROP			( drop the loop continuation ) | 
|  | DUP				( save the divisor ) | 
|  | 1 = IF			( see if divisor is == 1 ) | 
|  | exit_loop		( no point dividing by 1 ) | 
|  | ELSE | 
|  | try_dividing		( have to keep going ) | 
|  | ENDIF | 
|  | SWAP			( get divisor on top ) | 
|  | --				( decrement it ) | 
|  | SWAP			( put loop continuation back on top ) | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # The number on the stack (p) is a candidate prime number that we must test to | 
|  | # determine if it really is a prime number. To do this, we divide it by every | 
|  | # number from one p-1 to 1. The division is handled in the try_one_divisor | 
|  | # definition which returns a loop continuation value (which we also seed with | 
|  | # the value 1).  After the loop, we check the divisor. If it decremented all | 
|  | # the way to zero then we found a prime, otherwise we did not find one. | 
|  | # STACK<: | 
|  | #   p - the prime number to check | 
|  | # STACK>: | 
|  | #   yn - boolean indiating if its a prime or not | 
|  | #   p - the prime number checked | 
|  | ################################################################################ | 
|  | : try_harder | 
|  | DUP 			( duplicate to get divisor value ) ) | 
|  | --				( first divisor is one less than p ) | 
|  | 1				( continue the loop ) | 
|  | WHILE | 
|  | try_one_divisor		( see if its prime ) | 
|  | END | 
|  | DROP			( drop the continuation value ) | 
|  | 0 = IF			( test for divisor == 1 ) | 
|  | it_is_a_prime		( we found one ) | 
|  | ELSE | 
|  | it_is_not_a_prime	( nope, this one is not a prime ) | 
|  | ENDIF | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition determines if the number on the top of the stack is a prime | 
|  | # or not. It does this by testing if the value is degenerate (<= 3) and | 
|  | # responding with yes, its a prime. Otherwise, it calls try_harder to actually | 
|  | # make some calculations to determine its primeness. | 
|  | # STACK<: | 
|  | #    p - the prime number to check | 
|  | # STACK>: | 
|  | #    yn - boolean indicating if its a prime or not | 
|  | #    p  - the prime number checked | 
|  | ################################################################################ | 
|  | : is_prime | 
|  | DUP 			( save the prime number ) | 
|  | 3 >= IF			( see if its <= 3 ) | 
|  | it_is_a_prime  		( its <= 3 just indicate its prime ) | 
|  | ELSE | 
|  | try_harder 		( have to do a little more work ) | 
|  | ENDIF | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition is called when it is time to exit the program, after we have | 
|  | # found a sufficiently large number of primes. | 
|  | # STACK<: ignored | 
|  | # STACK>: exits | 
|  | ################################################################################ | 
|  | : done | 
|  | "Finished" >s CR 		( say we are finished ) | 
|  | 0 EXIT 			( exit nicely ) | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition checks to see if the candidate is greater than the limit. If | 
|  | # it is, it terminates the program by calling done. Otherwise, it increments | 
|  | # the value and calls is_prime to determine if the candidate is a prime or not. | 
|  | # If it is a prime, it prints it. Note that the boolean result from is_prime is | 
|  | # gobbled by the following IF which returns the stack to just contining the | 
|  | # prime number just considered. | 
|  | # STACK<: | 
|  | #    p - one less than the prime number to consider | 
|  | # STACK> | 
|  | #    p+1 - the prime number considered | 
|  | ################################################################################ | 
|  | : consider_prime | 
|  | DUP 			( save the prime number to consider ) | 
|  | 1000000 < IF 		( check to see if we are done yet ) | 
|  | done 			( we are done, call "done" ) | 
|  | ENDIF | 
|  | ++ 				( increment to next prime number ) | 
|  | is_prime 			( see if it is a prime ) | 
|  | IF | 
|  | print 			( it is, print it ) | 
|  | ENDIF | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition starts at one, prints it out and continues into a loop calling | 
|  | # consider_prime on each iteration. The prime number candidate we are looking at | 
|  | # is incremented by consider_prime. | 
|  | # STACK<: empty | 
|  | # STACK>: empty | 
|  | ################################################################################ | 
|  | : find_primes | 
|  | "Prime Numbers: " >s CR	( say hello ) | 
|  | DROP			( get rid of that pesky string ) | 
|  | 1 				( stoke the fires ) | 
|  | print			( print the first one, we know its prime ) | 
|  | WHILE  			( loop while the prime to consider is non zero ) | 
|  | consider_prime 		( consider one prime number ) | 
|  | END | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # | 
|  | ################################################################################ | 
|  | : say_yes | 
|  | >d				( Print the prime number ) | 
|  | " is prime."		( push string to output ) | 
|  | >s				( output it ) | 
|  | CR				( print carriage return ) | 
|  | DROP			( pop string ) | 
|  | ; | 
|  |  | 
|  | : say_no | 
|  | >d				( Print the prime number ) | 
|  | " is NOT prime."		( push string to put out ) | 
|  | >s				( put out the string ) | 
|  | CR				( print carriage return ) | 
|  | DROP			( pop string ) | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # This definition processes a single command line argument and determines if it | 
|  | # is a prime number or not. | 
|  | # STACK<: | 
|  | #    n - number of arguments | 
|  | #    arg1 - the prime numbers to examine | 
|  | # STACK>: | 
|  | #    n-1 - one less than number of arguments | 
|  | #    arg2 - we processed one argument | 
|  | ################################################################################ | 
|  | : do_one_argument | 
|  | --				( decrement loop counter ) | 
|  | SWAP			( get the argument value  ) | 
|  | is_prime IF			( determine if its prime ) | 
|  | say_yes			( uhuh ) | 
|  | ELSE | 
|  | say_no			( nope ) | 
|  | ENDIF | 
|  | DROP			( done with that argument ) | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # The MAIN program just prints a banner and processes its arguments. | 
|  | # STACK<: | 
|  | #    n - number of arguments | 
|  | #    ... - the arguments | 
|  | ################################################################################ | 
|  | : process_arguments | 
|  | WHILE			( while there are more arguments ) | 
|  | do_one_argument		( process one argument ) | 
|  | END | 
|  | ; | 
|  |  | 
|  | ################################################################################ | 
|  | # The MAIN program just prints a banner and processes its arguments. | 
|  | # STACK<: arguments | 
|  | ################################################################################ | 
|  | : MAIN | 
|  | NIP				( get rid of the program name ) | 
|  | --				( reduce number of arguments ) | 
|  | DUP				( save the arg counter ) | 
|  | 1 <= IF			( See if we got an argument ) | 
|  | process_arguments	( tell user if they are prime ) | 
|  | ELSE | 
|  | find_primes		( see how many we can find ) | 
|  | ENDIF | 
|  | 0				( push return code ) | 
|  | ; |