6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue Nov 12, 2024 3:27 pm

All times are UTC




Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Jan 11, 2021 11:08 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
It certainly is a hoot to test the limits of Forth. I recently thought of an idea to implement an assembly language terminology of self-modifying code. In this case though, a word would modify another word.

As an example, ERROR is only called a couple of times. Once by ?ERROR and once by R/W.

But ?ERROR is called 17 times and R/W is called whenever disk access is required.

My thought was if I modified ?ERROR to a different ERROR routine, then the original ERROR routine can still be used by R/W and ?ERROR will have a different ERROR routine.

For example, ?ERROR has this definition:

: ?ERROR SWAP IF ERROR ELSE DROP THEN ;

The goal is to change the CFA of ERROR to something else. This is what I came up with:

: error1 ." something different than the original word definition." cr quit ;
: modify ( modify cccc dddd eeee ffff) [compile] ' 0 ! [compile] ' 2 ! [compile] ' 4 !
[compile] ' 6 ! 0 @ begin 2+ dup @ 4 @ = if 6 @ swap ! quit else
dup @ 2 @ = then until ;

example: MODIFY ?ERROR ; ERROR ERROR1 will change the CFA of ERROR to the CFA of ERROR1 in the word ?ERROR.

cccc: ?ERROR ( is the word to change)
dddd: ; ( ?ERROR's delimiter: either ; or (;code)
eeee: ERROR ( gets the CFA of the old word to be replaced)
ffff: ERROR1 ( gets the CFA of the new word higher in memory)


This is just an exercise to see if it could be done. Discussion of practicality is welcome.

NOTES:
ERROR and ERROR1 cannot be the same name as -FIND will not find lower definition in memory.
Take note that memory addresses 0,2,4,6 are free for use with Forth in my system. Change as necessary for yours.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 12, 2021 12:57 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
I've done this kind of thing, mainly to modify already-compiled code during development, but have hardly used the words I wrote to do it. Just about anything can be done in Forth.

If you haven't already, look into the Forth words DOER and MAKE. A note I have penciled in in Appendix B of my paper copy of "Thinking Forth" says,

Quote:
You make a word with DOER, then tell it later on what you want it to do, using MAKE. You can change what you want that word to do as many times as you wish, by invoking MAKE again. One advantage this has over recompiling the word is that this way, all the later code that uses the word can remain unchanged. More on p.221-228.

I must confess that I have not used it though, and that if I needed it just once, I might feel like it's not worth the time to really understand it, so I might instead just have a variable the and use PERFORM (same as @ EXECUTE) and change the variable to point to the word I want executed.

_________________
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: Tue Jan 12, 2021 7:52 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
GARTHWILSON wrote:
Quote:
You make a word with DOER, then tell it later on what you want it to do, using MAKE. You can change what you want that word to do as many times as you wish, by invoking MAKE again. One advantage this has over recompiling the word is that this way, all the later code that uses the word can remain unchanged. More on p.221-228.

My Forth does not have >BODY. Is there a definition anywhere?

Doing a google search is useless as it doesn't recognize the ">" sign.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 12, 2021 8:35 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
IamRob wrote:
My Forth does not have >BODY. Is there a definition anywhere?

I didn't mention >BODY myself; but in 6502 ITC Forth it's the same as 2+ because you're just incrementing from the CFA to the PFA. >BODY's CFA points to 2+'s PFA.

_________________
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 Jan 13, 2021 12:18 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
GARTHWILSON wrote:
IamRob wrote:
My Forth does not have >BODY. Is there a definition anywhere?

I didn't mention >BODY myself; but in 6502 ITC Forth it's the same as 2+ because you're just incrementing from the CFA to the PFA. >BODY's CFA points to 2+'s PFA.

Thanks. It is not about what you may or may not have mentioned. A couple of different codes that I found for DOER/MAKE had >BODY, so I gathered that DOER/MAKE was part of a newer Forth standard and was not likely to see an older definition that I could use.

I really thought >BODY was a more complex definition. I am actually disappointed in its definition now since it takes 3 extra characters more to type than its definition. :) But I understand it is more about what the word is supposed to represent.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 12:21 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895

Using >BODY helps with source code portability. A DTC (direct threaded code) Forth has a 3 byte code field so >BODY would be 3 +


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 12:58 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
GARTHWILSON wrote:
I've done this kind of thing, mainly to modify already-compiled code during development, but have hardly used the words I wrote to do it. Just about anything can be done in Forth.


Since I have EVALUATE , I didn't need to define new words to accomplish this. From the source for my metacompiler:
Code:
0
" 2+ DUP ' INTERPRET + @ ' , = >IN !"
COUNT EVALUATE CONSTANT I.OFFSET

// PATCH INTERPRETER AND LITERAL
HEX HOST
: META.ON
   ['] M,
   ['] INTERPRET I.OFFSET + !
   ['] MLITERAL @ ['] LITERAL ! ;
: META.OFF
   ['] ,
   ['] INTERPRET I.OFFSET + !
   ['] : @ ['] LITERAL ! ;

Admittedly, it would have been better if I'd started with the address of INTERPRET's body and returned the address I need rather than obtaining an offset.
If an implementation does not have EVALUATE , this non nestable version of [BEGIN] and [UNTIL] would work.
Code:
VARIABLE <IN
: [BEGIN]  ( -- )
   >IN @ <IN ! ; IMMEDIATE
: [UNTIL]  ( F -- )
   ?EXIT
   <IN @ >IN ! ; IMMEDIATE

used like so
Code:
' INTERPRET >BODY [BEGIN] 2+ DUP @ ' , = [UNTIL]

This version skips the first cell in the body of INTERPRET , but I know that , ( comma ) is further down.

Quote:

I must confess that I have not used it though, and that if I needed it just once, I might feel like it's not worth the time to really understand it, so I might instead just have a variable the and use PERFORM (same as @ EXECUTE) and change the variable to point to the word I want executed.


This sounds like a good use for a DEFERred word.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 2:33 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
IamRob wrote:
My Forth does not have >BODY. Is there a definition anywhere?

Doing a google search is useless as it doesn't recognize the ">" sign.


The earliest I've seen >BODY mentioned is the Forth-83 Standard.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 2:53 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
JimBoyd wrote:

The earliest I've seen >BODY mentioned is the Forth-83 Standard.

My HP-71's Forth has >BODY and I think it's more or less Forth-79. (It's not exact, because the unusual hardware makes it impractical to make it exact; also, I have not worked elsewhere with '79 to be very aware of the differences.) What does fig-Forth use for >BODY?

_________________
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 Jan 14, 2021 3:24 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
GARTHWILSON wrote:
My HP-71's Forth has >BODY and I think it's more or less Forth-79. (It's not exact, because the unusual hardware makes it impractical to make it exact; also, I have not worked elsewhere with '79 to be very aware of the differences.)


I don't see >BODY in the Forth-79 Standard. It may have been included in the Forth-83 Standard because of common use?

Quote:

What does fig-Forth use for >BODY?


It's my understanding that fig-Forth does it the other way around. FIND returns the address of a word's body and the word CFA is used to go from the parameter field address to the code field address.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 3:46 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
JimBoyd wrote:
It's my understanding that fig-Forth does it the other way around. FIND returns the address of a word's body and the word CFA is used to go from the parameter field address to the code field address.

Yes; but what goes the other direction? It's not PFA, because that takes the NFA to give you the PFA; and NFA goes the opposite direction. I'm looking in the fig-Forth assembly source code and the installation manual and I'm not finding a word to do that. I guess you're just supposed to know to use 2+.

_________________
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 Jan 14, 2021 3:56 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
GARTHWILSON wrote:

Yes; but what goes the other direction? It's not PFA, because that takes the NFA to give you the PFA; and NFA goes the opposite direction.

I don't know.
Quote:

I'm looking in the fig-Forth assembly source code and the installation manual and I'm not finding a word to do that. I guess you're just supposed to know to use 2+.


I guess so. To be fair, of the words in Kim Harris' experimental proposal, only >BODY was already in the Forth-83 Standard as a required word.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 4:18 am 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
GARTHWILSON wrote:
JimBoyd wrote:
It's my understanding that fig-Forth does it the other way around. FIND returns the address of a word's body and the word CFA is used to go from the parameter field address to the code field address.

Yes; but what goes the other direction? It's not PFA, because that takes the NFA to give you the PFA; and NFA goes the opposite direction. I'm looking in the fig-Forth assembly source code and the installation manual and I'm not finding a word to do that. I guess you're just supposed to know to use 2+.

This kind of confusion is why I am kind of adopting a "best suited" method. Some words don't even have a PFA as the code is or can be redirected to elsewhere in memory.

My Forth breaks more if I use : PFA CFA 2+, so I rewrote it so that FIND returns the CFA, then to get the PFA it is just : PFA CFA @. Even with an STC forth, PFA, instead of being 3+, could be made to work with CFA @, without breaking STC or DTC portability.

I don't know, but I think this seems to be an easier port between different threaded Forths.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 5:34 pm 
Offline

Joined: Sun Apr 26, 2020 3:08 am
Posts: 357
IamRob wrote:
GARTHWILSON wrote:
JimBoyd wrote:
It's my understanding that fig-Forth does it the other way around. FIND returns the address of a word's body and the word CFA is used to go from the parameter field address to the code field address.

Yes; but what goes the other direction? It's not PFA, because that takes the NFA to give you the PFA; and NFA goes the opposite direction. I'm looking in the fig-Forth assembly source code and the installation manual and I'm not finding a word to do that. I guess you're just supposed to know to use 2+.

This kind of confusion is why I am kind of adopting a "best suited" method. Some words don't even have a PFA as the code is or can be redirected to elsewhere in memory.

My Forth breaks more if I use : PFA CFA 2+, so I rewrote it so that FIND returns the CFA, then to get the PFA it is just : PFA CFA @. Even with an STC forth, PFA, instead of being 3+, could be made to work with CFA @, without breaking STC or DTC portability.

I don't know, but I think this seems to be an easier port between different threaded Forths.

After reading some other topics and finally understanding them, I see that >BODY makes sense if only used with words without CODE.

Since >BODY can damage a code word, wouldn't it be more prudent to define >BODY to only allow a change to the body of a word if that word is a COLON word? Maybe something like this:

: >BODY ( cfa --- ) DUP @ [ ' DO @ ] = IF 2+ ELSE DROP # ERROR THEN ;

it seems to me that any word that can cause damage, or allow to cause damage, to another word (by human error) should have at least a little error checking.


Top
 Profile  
Reply with quote  
PostPosted: Thu Jan 14, 2021 7:51 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8539
Location: Southern California
>BODY doesn't make any changes to the word. All it does is return the PFA, given the CFA. It's only information about the word.

_________________
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  [ 24 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: John West and 1 guest


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: