6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Mar 28, 2024 9:24 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Wed Apr 23, 2014 6:37 pm 
Offline

Joined: Mon Mar 25, 2013 9:26 pm
Posts: 183
Location: Germany
creating the sum of all numbers that are on the stack can be done by
Code:
: 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:
: 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:
: 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.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 23, 2014 6:58 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8412
Location: Southern California
mkl0815 wrote:
creating the sum of all numbers that are on the stack can be done by
Code:
: 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?


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 23, 2014 7:17 pm 
Offline

Joined: Mon Mar 25, 2013 9:26 pm
Posts: 183
Location: Germany
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:
: 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.


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 23, 2014 7:58 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8412
Location: Southern California
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 24, 2014 12:40 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8412
Location: Southern California
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:
   <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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 24, 2014 3:21 am 
Offline

Joined: Mon Mar 25, 2013 9:26 pm
Posts: 183
Location: Germany
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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 24, 2014 1:01 pm 
Offline

Joined: Sat Aug 21, 2010 7:52 am
Posts: 231
Location: Arlington VA
mkl0815 wrote:
creating the sum of all numbers that are on the stack can be done by
Code:
: 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:
: 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:
: 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)


Top
 Profile  
Reply with quote  
PostPosted: Sun Aug 12, 2018 7:56 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 841
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 ]>.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: