From: cbbrowne@csi.uottawa.ca (Christopher Browne)
Subject: Re: Floating Point
Organization: Dept. of Computer Science, University of Ottawa
Date: Sat, 3 Oct 92 21:40:08 GMT

In article <4092.UUL1.3#5129@willett.pgh.pa.us> Elizabeth Rather writes:
>Regarding the discussion of Locals and the existance of a separate floating
>point stack... please don't forget that the major use of a separate FP stack
>is to take advantage of the really significant speed advantage of the
>*hardware* floating stacks in, for example, the 80x87 NDPs, not just to "get
>FPs out of the way."  

Very good point.

>I don't want to dive in for or against Locals, but they
>aren't part of that particular debate as far as ANS Forth is concerned.

This is probably a useful fact to know.  It's useful to know that the
way the standard was designed in this area was NOT fractious with
respect to locals.

I've always found it interesting when people start to "freak out" when
others suggest the use of "Yet Another Stack."  I personally think
that it's probably a useful thing to at least CONSIDER the potential
addition of additional stacks.

It's been very useful to have two stacks, primarily intended to store
return addresses and function parameters, respectively.

The stacks have since been used (abused?) to store a whole variety of
other sorts of information; from loop counters/looping addresses to
some (occasionally weird) varieties of local variables.

There was an article in FD a couple of years ago ("Forth Needs Three
More Stacks" - Ayman Abu-Mostafa, XI #1) that proposed adding extra
stacks to use for:
a) Loop parameters
b) Handling conditions
c) Counting cases, for the case control structures

This made a lot of sense to me; many of the stack contortions of which
Forth programs become guilty come as a result of trying to use the two
"standard" stacks to do things other than the straightforward
Return/Parameter passing for which they are PRIMARILY intended.

A bonus that was found is that control structures could be made to
work in the command line, without forcing 'em to be compiled.
Something that people "love" to attempt.

Adding local variables winds up being fairly trivial (and amenable to
recursive functions) if we add Yet Another Stack to do
d) Local Variables.
I hacked up such a beast based on the idea of "Stack Variables", from
the FD article by that name in XII #1.

This idea DOES have a couple of "bugs" (Other than the fact that it
might break the Standard, which is a "given" problem of any potential
change.):

i) Some hardware may be optimized for 2 stacks, and playing with more
would slow it down.

ii) Adequate memory would be required for each such stack.  It would be
nice to have no arbitrary limits; this is particularly important for
an implementation of local variables.  'Twould be very ugly if you
were only allowed to have (say) 32 instantiations of local variables.
This precludes the use of local variables for recursive algorithms, if
there's likely to be any significant level of recursing.

For a "conditional" or "case" stack, a limited stack depth would
probably be a less drastic problem, since conditionals tend not to
nest EXTREMELY far.

As an aside; has the "guaranteed stack depth" changed lately?  The
last I remember hearing was that 32 cells were guaranteed for the
parameter stack, but that could easily have changed.

The "challenge": Can you think of some other "problem area" in Forth
whose solution could be made easier by the addition of a personalized
stack?

The current list of contenders:
I) Return Stack
II) Function parameters
(These two being the "standard" stacks currently existant)

III) Floating point math
IV) Loop parameters
V) Handling conditions
VI) Counting cases, for the case control structures
VII) Local Variables

Obvious extensions:
- Specialized data structures
  - Toss two matrices onto the matrix stack, and do "Mat+"
  - It grabs the floating point members, tosses them 2 by 2 onto the
  FP stack, adds them together, putting the result <somewhere>;
  whether that be into the 2nd matrix, or maybe into a third spot
  (which would require that there be THREE arguments...)

There'd be some gyrations on 3 or 4 different stacks; but the
gyrations related to one stack wouldn't mess up the others.

One might generalize this, in the absense of a "special"
implementation of the extra stacks, by creating words like:

Stack:  ( n -- addr )
\ Creates a stack of size n; on execution, returns the address of
\ the stack

push    ( value stack -- )
\ pushes <value> onto <stack>

pop     ( stack -- value )
\ pops <value> from <stack>

\ Which would be used as follows:
MATRIXDEFS load   \ Load in definition of matrix data types
80 Stack: MatrixStack

4 5 2DMatrix A
4 5 2DMatrix B
4 5 2DMatrix C

A Getvalue \ Reads a value into matrix A
B Getvalue \ Reads a value into matrix B

A MatrixStack push
B MatrixStack push
C MatrixStack push

Add2dMatrices  \ ( MatrixStack: a b c -- ) Adds a + b, putting it in c

Mitch Bradley's Forthmacs has the word stack:, push, and pop, that
look pretty much like this...

-- 
Christopher Browne
cbbrowne@csi.uottawa.ca
University of Ottawa
Master of System Science Program
Newsgroups: comp.lang.forth