6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 12:40 pm

All times are UTC




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Thu Apr 22, 2021 2:13 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Someone in the #forth channel on IRC showed me a way of handling local variables with what he called a "frame pointer." Here's an example:
Code:
: foo 3 { s1 @ s2 @ + s0 ! } 2drop ;

which is equivalent to this:
Code:
: foo + swap ! ;


3 { makes a copy of the data pointer, subtracts 3 cells from it, and saves it to the "frame pointer." s0 pushes the frame pointer to the stack, s1 pushes the frame pointer +1 cell etc. That way whatever is passed in on the stack as arguments can be frozen in place and accessed regardless of whatever else is on the stack as long as the rest of the word doesn't drop those first three items until it's done with them.

Obviously this is more trouble than it's worth for a short word like the one above, but it seems handy for a larger word with nested loops that need to access more than 3 items passed in.

Is this something that already exists in some forths?


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 22, 2021 3:30 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
Druzyek wrote:
Someone in the #forth channel on IRC showed me a way of handling local variables with what he called a "frame pointer." Here's an example:
Code:
: foo 3 { s1 @ s2 @ + s0 ! } 2drop ;

which is equivalent to this:
Code:
: foo + swap ! ;


3 { makes a copy of the data pointer, subtracts 3 cells from it, and saves it to the "frame pointer." s0 pushes the frame pointer to the stack, s1 pushes the frame pointer +1 cell etc. That way whatever is passed in on the stack as arguments can be frozen in place and accessed regardless of whatever else is on the stack as long as the rest of the word doesn't drop those first three items until it's done with them.

Obviously this is more trouble than it's worth for a short word like the one above, but it seems handy for a larger word with nested loops that need to access more than 3 items passed in.

Is this something that already exists in some forths?


Hmm! Would the code to handle these frames be different for different occasions?

I started writing something similar the same as PICK using R.
With any number of values ( n1 n2 .. nn -- ) pushed on the return stack, one could get numbers that are buried without popping a value off the stack with "1 R, 2 R .. nR" . I dropped that idea when I needed to push something else on the return stack and it threw the order out the window. And also wanted to be able to carry a value back to the calling word.

I prefer using free zero page memory and on my computer, memory is free for Forth use from $0-$F. I use this area constantly as scratch pointers. Although one has to use @ or C@ to retrieve the value, the value does not have to be dropped when the definition is finished and the values can can also be carried back to the calling word.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 22, 2021 4:25 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Quote:
Hmm! Would the code to handle these frames be different for different occasions?
If you mean whether it depends on what's on the stack then no. The problem with PICK is that you need to know exactly how many items are on the stack, which you may not know, and you have to go back and adjust all your PICK offsets if you tweak anything. Doing it this way, the access to those stack items is totally independent of what the stack is doing otherwise.


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 22, 2021 6:32 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
It's like doing the TSX, XXX 101,X (where the XXX is any instruction with the abs,X address mode) in assembly language, where you can add other stuff to the page-1 hardware stack without having to adjust the 100's number as long as you don't do another TSX. It works, and may reduce confusion, but it's a step below actually having local variables. I've considered various ways to implement local variables, but had not thought of what you're suggesting.

A similar one I had considered was to put them on the return stack and keep a couple of variables STK_BASE and #LOC_BYTs which get saved on the return stack by INIT_LOCALS and restored by END_LOCALS. INIT_LOCALS makes the new stack base to be the old stack base + #LOC_BYTs, and then #LOC_BYTs gets updated by INIT_LOCALS. It's quite simple and manual, like nameless variables on a calculator where you just have to remember what you're keeping in R01, R02, etc, but they won't be interfering with other nested levels' use of R01, R02, etc.. I wondered if it's so simple that it's of little value. Actually, when we do PICK or ROLL, we don't have names for the stack elements we're dealing with either, and this will be easier than that. Names could be added to the locals, but the names would be global words. That would still work for recursion, since for example
Code:
        LOCALS 4 +
(where an array starts with the fifth byte of the word's locals area) could be replaced with
Code:
        OUT_ARRAY
which is much more descriptive and yet references the current local array base regardless of levels of nesting, and without disturbing previous nesting levels.

What I've tentatively decided to implement (but have not gotten around to yet) is considerably more complex, so the names can be local too, and handled the same as global variables and arrays. It involves setting up buffers out near the end of RAM which can be any length you want, limited only by available memory. The buffer use during compilation is different from how it is at run time. During compilation, the buffer space is actually part of the dictionary, so subsequent compilation can FIND the words. When a word is done being compiled, the buffer is deleted. At run time, a buffer of appropriate size is created at the beginning of the word needing the locals, and deleted at the end. You could potentially have thousands of bytes of local variables active or pending at any given time.

_________________
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  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 10 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: