problem in understanding a definition and whats going on

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
Post Reply
mkl0815
Posts: 183
Joined: 25 Mar 2013
Location: Germany
Contact:

problem in understanding a definition and whats going on

Post by mkl0815 »

creating the sum of all numbers that are on the stack can be done by

Code: Select all

: sum depth 0 swap 0 do + loop ; redefined sum   ok
1 2 3 4 sum . 10  ok
It works fine, but I have a problem understanding why the inner "swap 0" is needed.

Lets assume that 1 2 3 4 are already on the stack.
invoking "sum" executes "depth" first, putting the number "4" on the stack, that is used as limit for the loop.
after that a "0" is put on the stack, defining the index to start with. so the loop should run from 0 to 3 (4 times).

the "do" word takes both upper numbers (4 and 0) from the stack and runs the loop, that should add the remaining numbers on the stack.

That works fine (without the additional "swap 0" if I write

Code: Select all

: sum depth 1 do + loop ; redefined sum   ok
1 2 3 4 sum . 10  ok
But why? Because the inner loop should only run from 1 to (depth-1)

Testing with:

Code: Select all

: test 3 0 do 1 loop ; redefined test   ok
test .s <3> 1 1 1  ok
Showing that with 3 and 0 as limit and index do ... loop runs 3 times.

Can someone help me to understand that?

It is clear that the additional "swap 0" adds another number on the stack (0) that is not affecting the sum, but takes care that the stack is not empty before the loop ends.
But why is in the "sum" definition the loop is running one cycle more then in my "test" definition?

Mario.
How should I know what I think, until I hear what I've said.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: problem in understanding a definition and whats going on

Post by GARTHWILSON »

mkl0815 wrote:
creating the sum of all numbers that are on the stack can be done by

Code: Select all

: sum depth 0 swap 0 do + loop ; redefined sum   ok
1 2 3 4 sum . 10  ok
It works fine, but I have a problem understanding why the inner "swap 0" is needed.
It starts with the 0 to add the first number to. So the next thing is that <anything1> <anything2> SWAP looks strange, and the first reaction is, "Why not just reverse the order to <anything2> <anything1> so you don't have to SWAP?"; but here we have DEPTH, and putting the 0 on first will give you a different result when you do DEPTH. You could do 0 DEPTH 1- which would come out the same length and approximately the same speed.

In your other situation, you can add the first two numbers together to start, instead of adding the first one to 0 and then the second one to the first result. If the stack only had one cell on it though, you'd have an underflow.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
mkl0815
Posts: 183
Joined: 25 Mar 2013
Location: Germany
Contact:

Re: problem in understanding a definition and whats going on

Post by mkl0815 »

Ok, I understand that adding an additional 0 to the stack prevents a stack underrun if only one numer is on the stack.
But it still not clear to me why the loop construct is taking one more cycle than my "test" definition.

To prevent the "only one numer" problem, I can write:

Code: Select all

: sum 0 depth 1 do + loop ; ok
1 sum . 1  ok              
1 2 sum . 3  ok
Ok, but why do I need to loop from "1" to DEPTH instead of "0" to DEPTH?
How should I know what I think, until I hear what I've said.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: problem in understanding a definition and whats going on

Post by GARTHWILSON »

Since you already put the 0 on the stack, DEPTH gives you one more than you had when you called SUM. So if you had two cells on the stack, the 0 makes for three, so DEPTH gives you a 3, not a 2, so you're going 3 1 DO instead of 2 0 DO. (I hope I'm understanting the question.)

For non-Forthers: If <to> <from> DO seems strange (as opposed to BASIC's FOR <from> <to>), think of gifts, where the label says TO: <name1>, and underneath, FROM: <name2>.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: problem in understanding a definition and whats going on

Post by GARTHWILSON »

What you have may be an interesting exercise, but it's not of any real practical use since it excludes having any other stuff underneath, pending futher operations when you unnest. An idea I've used from Forth Dimensions is { <cell1> <cell2> <cell3> etc. }. The values can be literals, or they can be fetched or calculated between the { and the } . The { stores the depth in a variable BEG_DEPTH, then you add any number of cells you want, and the } takes the depth again and subtracts the contents of BEG_DEPTH to know how many cells you added, and puts the result on the stack. The May/Jun 1997 issue of FD had SET_OF to use like CASE_OF in a CASE statement, so you can say in essence, "In the case of the number on the top of the stack being equal to any of these, do this..." A usage example would be:

Code: Select all

   <do stuff>                                        \ something that leaves a cell on the stack
   CASE                                              \ to determine what you do next
                  A0   CASE_OF  <do stuff>  END_OF   \ In the case of it being A0, do this.
       { 13 16 20 27 }  SET_OF  <do stuff>  END_OF   \ If it's any of these numbers, do this.
               50 7F  RANGE_OF  <do stuff>  END_OF   \ If it's in the range of 50 to 7F, do this.
   END_CASE                                          \ In any other case, take no action.
BTW, those are curly braces, although they hardly look like it on my monitor.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
mkl0815
Posts: 183
Joined: 25 Mar 2013
Location: Germany
Contact:

Re: problem in understanding a definition and whats going on

Post by mkl0815 »

GARTHWILSON wrote:
Since you already put the 0 on the stack, DEPTH gives you one more than you had when you called SUM. So if you had two cells on the stack, the 0 makes for three, so DEPTH gives you a 3, not a 2, so you're going 3 1 DO instead of 2 0 DO. (I hope I'm understanting the question.)
OMG, it's so simple. Adding 3 numbers takes only 2 steps. Adding the first two numbers and then adding the result to the third number. It has nothing to do with forth. It's just simple logic. So having a "3 0 do + loop" runs three times. But at the third step there's nothing to add on the stack any more, because only one number left (the result).

Thanks for pointing to the right direction :-)

Mario.
How should I know what I think, until I hear what I've said.
chitselb
Posts: 232
Joined: 21 Aug 2010
Location: Ontonagon MI
Contact:

Re: problem in understanding a definition and whats going on

Post by chitselb »

mkl0815 wrote:
creating the sum of all numbers that are on the stack can be done by

Code: Select all

: sum depth 0 swap 0 do + loop ; redefined sum   ok
1 2 3 4 sum . 10  ok
It works fine, but I have a problem understanding why the inner "swap 0" is needed.

Code: Select all

: sum depth 1 do + loop ; redefined sum   ok
1 2 3 4 sum . 10  ok
It is clear that the additional "swap 0" adds another number on the stack (0) that is not affecting the sum, but takes care that the stack is not empty before the loop ends.
But why is in the "sum" definition the loop is running one cycle more then in my "test" definition?

Mario.
What helps me sometimes is to unfold the source and add a stack diagram after each word, e.g.

Code: Select all

: sum       ( n[depth] n[4] n[3] n[2] n[1] -- sum }
    depth   ( n[depth] n[4] n[3] n[2] n[1] depth }
    0       ( n[depth] n[4] n[3] n[2] n[1] depth 0 }
    swap   ( n[depth] n[4] n[3] n[2] n[1] 0 depth }
    0       ( n[depth] n[4] n[3] n[2] n[1] 0 depth 0 }
    do
        +    ( n[depth] n[4] n[3] n[2] 0+n[i] ; iterates "depth" times )
    loop ;    ( -- sum)
JimBoyd
Posts: 931
Joined: 05 May 2017

Re: problem in understanding a definition and whats going on

Post by JimBoyd »

GARTHWILSON wrote:
What you have may be an interesting exercise, but it's not of any real practical use since it excludes having any other stuff underneath, pending futher operations when you unnest. An idea I've used from Forth Dimensions is { <cell1> <cell2> <cell3> etc. }. The values can be literals, or they can be fetched or calculated between the { and the } .
The Commodore 64 lacks curly braces so I use <[ and ]>.
Post Reply