6

I've written a piece of code in Forth which calculates the 9th Fibonacci number:

." Fibonacci numbers"
: INP 9 0 ;
: FIB_0 1 0 1 ;
: FIB FIB_0 INP DO  + SWAP OVER LOOP SWAP . ;

Now I want to read the integer number N from user input and give it to INP instead of 9 so that I could calculate an arbitrary integer Fibonacci number. I'm using Gforth on Windows.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3048747
  • 179
  • 1
  • 9

2 Answers2

8

You can use accept to grab user input and then s>number? to attempt to convert it to a number. accept expects a memory address and a max length. 's>number?` leaves a double and a flag.

So you could do something like

: fetch-input ( - n f ) 
     pad 40 accept   
     pad swap s>number? 
     >r d>s r> ;

If s>number? can't convert the string to a number it will leave 0 0 under the flag on the stack.

So after s>number? you have three entries on the stack: the two parts of the double precision fixed point number and a flag--stack comment would be: ( - n n f ). But I'm assuming you want a single precision number given the code in your question.

d>s will take a double precision number and convert it to single precision. We need to move the flag out of the way so we can get to the number. A standard trick for temporarily moving something out of the way is to move it from the data stack to the return stack, do whatever it is you need to do, then move it back. Thus, >r and r>.

Matthew Burke
  • 2,295
  • 17
  • 14
3

While the accepted answer provides, what you want, I'm unsure, how well your approach fits the language philosophy. In my opinion executing the input within the word is an approach of other programming languages.

With this code:

: (fibo-iter) ( n n - n n) swap over + ;
: th-fibo ( n - n) >r 1 dup r> 2 - 0 do (fibo-iter) loop nip ;

one can write:

10 th-fibo .

to produce the tenth fibonacci number. The input is provided on stack, the calculation is done by th-fibo which (adjusting the input for the predefined values and without error checking) and the printing - if desired - follows explicitly.

guidot
  • 5,095
  • 2
  • 25
  • 37