3

I'm using Gforth to try to implement exponentiation. I understand, in theory, how a stack-based language is supposed to operate. However, I'm having difficulties with my implementation of it on Gforth.

Here's what I have right now:

: myexp
    1 swap ?do rot dup * rot rot loop ;

However, when I run it I see a stack underflow like:

3 2 myexp
:1: Stack underflow
3 2 >>>myexp<<<
Backtrace:
$7F645EFD6EF0 rot
$2
$1

Is Gforth's looping structure manipulating the stack when it loops?

I'm in the dark on how Forth works as most looping examples I've seen online are rather involved and confusing to someone new to Forth.

What is wrong with my implementation?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David
  • 2,080
  • 5
  • 29
  • 44

2 Answers2

7
  • The 1 swap is wrong. ?do wants the lower bound at the top of the stack.
  • The loop body is wrong. The two bounds are removed from the data stack, so your use of rot to access the exponentiation base doesn't work.
: myexp ( u1 u2 -- u3 ) \ u3 = u1^u2
   over swap 1 ?do over * loop nip ;
Lars Brinkhoff
  • 13,542
  • 2
  • 28
  • 48
  • Thanks! Would you also be able to explain what's in the ( )? I know the text after the \ is a comment, but I'm not sure what's supposed to go in the ( ). – David Jan 15 '14 at 16:51
  • 5
    `( )` is also a comment, so you can put anything you like in there. However, there is a convention to add a stack comment to definitions. So the stuff before and after the `--` is the elements on the stack before and after the definition runs. There are also conventions for how to describe the elements; in this case `u` signifies unsigned numbers. – Lars Brinkhoff Jan 15 '14 at 20:10
  • 1
    See e.g. http://lars.nocrew.org/dpans/dpans2.htm#2.2.2 and http://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Stack_002dEffect-Comments-Tutorial.html#Stack_002dEffect-Comments-Tutorial – Lars Brinkhoff Jan 16 '14 at 06:07
1

I'm not sure how to use Gforth's floating point stack, so I can't give you the answer, but instead of using a loop, you can use the Pascal programming trick of defining exponentiation like so:

x^y = exp(y*ln(x))

Note...for more information, see this answer from the question on Exponentiation of real numbers.

Community
  • 1
  • 1
clay
  • 1,757
  • 2
  • 20
  • 23