mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10192 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			236 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Smalltalk
		
	
	
	
	
	
			
		
		
	
	
			236 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Smalltalk
		
	
	
	
	
	
| ################################################################################
 | |
| #
 | |
| # 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 )
 | |
| ;
 |