6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 9:09 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
 Post subject: Testing CREATE DOES>
PostPosted: Thu Dec 13, 2018 9:49 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
I noticed on the Forth standard website when testing DOES>, there were no tests of nested CREATE DOES>. Something similar might be useful in an object oriented package for Forth. Here is a test I came up with for nested CREATE DOES>.
Code:
SCR# 3
// TEST CREATE DOES>
HEX
: LEVEL0  ( N -- )
   CREATE , DOES>  ( N2 -- )
   CREATE @ , , DOES>  ( N3 -- )
   CREATE 2@ , , , DOES>  ( N4 -- )
   CREATE DUP 2+ 2@ ROT @ , , , ,
   DOES>  ( -- )
      DUP 4 + 2@ ROT 2@ 4 0
      DO  U.  LOOP ;
2 LEVEL0 LEVEL1
3 LEVEL1 LEVEL2
5 LEVEL2 LEVEL3
7 LEVEL3 LEVEL4
LEVEL4

And here is the result
Code:
3 LOAD 2 3 5 7  OK

And an examination of the parameter fields.
Code:
' LEVEL1 >BODY 10 DUMP
5A11   2  0  6 5A 86 4C 45 56  45 4C B2 BD 59  2  0  3   ...Z.LEVEL..Y...
 OK
' LEVEL2 >BODY 10 DUMP
5A1E   2  0  3  0 13 5A 86 4C  45 56 45 4C B3 CC 59  2   .....Z.LEVEL..Y.
 OK
' LEVEL3 >BODY 10 DUMP
5A2D   2  0  3  0  5  0 22 5A  86 4C 45 56 45 4C B4 E5   ......"Z.LEVEL..
 OK
' LEVEL4 >BODY 10 DUMP
5A3E   2  0  3  0  5  0  7  0   4 44 55 4D 50 20 20 20   .........DUMP   
 OK

I'd like to hear about difficulties implementing CREATE DOES> , what situation caused it to fail, so those of us writing our own Forths can more thoroughly test our implementations of CREATE DOES>.

Cheers,
Jim


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sat Dec 15, 2018 8:10 am 
Offline

Joined: Mon Jan 07, 2013 2:42 pm
Posts: 576
Location: Just outside Berlin, Germany
I'm glad somebody is trying to get this test, the whole concept makes my brain explode. I know that https://forth-standard.org/ allows comments and discussions, have you considered posting it there for feedback?


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sat Dec 15, 2018 9:41 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
I had to go through that when I did my '816 Forth, but it has been many years so I'll have to review it when I get time. The way I originally did it turned out to have a problem, so I had to put some more brain power into it. I believe the 2nd time was a charm, but I don't remember much about it. There's also ;code, and does (a runtime routine).

_________________
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  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sun Dec 16, 2018 7:47 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
GARTHWILSON wrote:
There's also ;code, and does (a runtime routine).

I like it. My runtime routine for DOES> and ;CODE is named (;CODE) but I like DOES , it's a smaller name, and I may just rename mine.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sun Dec 16, 2018 7:54 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
JimBoyd wrote:
GARTHWILSON wrote:
There's also ;code, and does (a runtime routine).

I like it. My runtime routine for DOES> and ;CODE is named (;CODE) but I like DOES , it's a smaller name, and I may just rename mine.

The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.

_________________
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  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sun Dec 30, 2018 10:17 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
scotws wrote:
I'm glad somebody is trying to get this test, the whole concept makes my brain explode.

It really makes you appreciate what Charles Moore accomplished.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Sun Dec 30, 2018 10:36 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
GARTHWILSON wrote:
The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.

Sadly, the Commodore 64 uses PETSCII and it doesn't have a caps lock key, it has a shift lock key.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Thu Jan 03, 2019 11:31 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
Regrettably, I cannot relate any difficulties I had because the first time I wrote a Forth for the C64, the only Forth I've written, was in the mid 1990's and I have no records ( notes or source code ) from that time.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Mon Jan 07, 2019 9:46 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
The following should also work under Forth-83 and ANSForth. Edited so the computer's responses are in curly braces.
Code:
: DOES1   DOES>  @ . ;  { OK }
: DOES2   DOES>  @ 2* . ;  { OK }
CREATE PI  314 ,  { OK }
DOES1 PI { 314  OK }
PI  { 314  OK }
DOES2 PI { 628  OK }
PI { 628  OK }
DOES1 PI { 314  OK }
PI { 314  OK }


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Fri Oct 14, 2022 10:42 pm 
Offline

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

The following example is for an ITC Forth. It's not so much a test to determine if CREATE DOES> is properly implemented, more like a test of what's possible. This example is a number generator which may also work with other Forth threading techniques.
Code:
: GEN  ( -- )
   CREATE
      NOOP
   DOES>
      DUP 2@ SWAP ROT +! ;

Now to alter GEN to change it into a number generator. Each time it is called it will return a number.
Code:
GEN

Set GEN to return an initial value of zero and increment by one each time it is executed.
Code:
' GEN >BODY OFF
1 ' GEN >BODY 2+ !

Now set the new initial value to 1000 and the increment to 5.
Code:
1000 ' GEN >BODY !
5 ' GEN >BODY 2+ !

In this example NOOP is just a place holder. DOES> compiles DOES , which will change the code field of the latest word in the current vocabulary. Since GEN is used to change its own code field, these two words are only executed once and can be safely overwritten after GEN modifies itself.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Thu Apr 20, 2023 2:09 am 
Offline

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

Should CREATE ;CODE be nestable if after ;CODE there is a shift to high level Forth?
Here is a test of nesting CREATE ;CODE and placing a CREATE DOES> in the mix. The JSR to the subroutine DO.VAR places the PFA on the data stack.
Code:
SCR# 1
// DO.VAR
SUBR DO.VAR  ( -- ADR )
   CLC
   W    LDA  2 # ADC
   W 1+ LDY  CS IF  INY  THEN
   DEX  DEX
   0 ,X STA  1 ,X STY
   RTS
   END-CODE

SCR# 2
// TEST CREATE ;CODE
DECIMAL
: LEVEL0  ( N -- )
   CREATE , ;CODE  ( N2 -- )
   DO.VAR JSR  >FORTH
   CREATE @ , , ;CODE  ( N3 -- )
   DO.VAR JSR  >FORTH
   CREATE 2@ , , , ;CODE  ( N4 -- )
   DO.VAR JSR  >FORTH
   CREATE DUP 2+ 2@ ROT @ , , , ,
   DOES>  ( -- )
      DUP 4 + 2@ ROT 2@ 4 0
      DO  U.  LOOP ;

SCR# 3
// THE TEST RUN
2 LEVEL0 LEVEL1
3 LEVEL1 LEVEL2
5 LEVEL2 LEVEL3
7 LEVEL3 LEVEL4
LEVEL4

And the result.
Code:
1 RAM 3 RAM THRU 4001 4002 4003 2 3 5 7  OK

The contents of the parameter fields of LEVEL1 , LEVEL2 , LEVEL3 and LEVEL4 .
Code:
' LEVEL1 >BODY 2 DUMP
7A0C   2  0  3 40  1 7A 86 4C  45 56 45 4C B2 B0 79  2   B@C@A..LEVEL...B
 OK
' LEVEL2 >BODY 4 DUMP
7A1B   2  0  3  0  3 40 10 7A  86 4C 45 56 45 4C B3 C2   B@C@C@P..LEVEL..
 OK
' LEVEL3 >BODY 6 DUMP
7A2C   2  0  3  0  5  0  3 40  21 7A 86 4C 45 56 45 4C   B@C@E@C@!..LEVEL
 OK
' LEVEL4 >BODY 8 DUMP
7A3F   2  0  3  0  5  0  7  0   4 44 55 4D 50 20 20 20   B@C@E@G@DDUMP   
 OK

These are the same results as with my test of nested CREATE DOES> .


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Thu Nov 16, 2023 10:09 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 895
I made an error in the following and I'm surprised nobody noticed. At least, nobody commented on it.
JimBoyd wrote:

The following example is for an ITC Forth. It's not so much a test to determine if CREATE DOES> is properly implemented, more like a test of what's possible. This example is a number generator which may also work with other Forth threading techniques.
Code:
: GEN  ( -- )
   CREATE
      NOOP
   DOES>
      DUP 2@ SWAP ROT +! ;

Now to alter GEN to change it into a number generator. Each time it is called it will return a number.
Code:
GEN

Set GEN to return an initial value of zero and increment by one each time it is executed.
Code:
' GEN >BODY OFF
1 ' GEN >BODY 2+ !

Now set the new initial value to 1000 and the increment to 5.
Code:
1000 ' GEN >BODY !
5 ' GEN >BODY 2+ !

In this example NOOP is just a place holder. DOES> compiles DOES , which will change the code field of the latest word in the current vocabulary. Since GEN is used to change its own code field, these two words are only executed once and can be safely overwritten after GEN modifies itself.

When GEN is run without a name, CREATE will abort with an error message.
Code:
GEN
GEN
   
NAME?!

CREATE should not be in the definition of GEN if it is to modify itself. The presence of NOOP and DOES (compiled by DOES> ) reserves room for two cells.
Code:
: GEN
    NOOP
    DOES>
       DUP 2@ SWAP ROT +! ;
GEN
1000 ' GEN >BODY !
5 ' GEN >BODY 2+ !

A short test.
Code:
: TEST
   5 0
   DO
       GEN .
   LOOP ;

And the results.
Code:
TEST 1000 1005 1010 1015 1020  OK
TEST 1025 1030 1035 1040 1045  OK
TEST 1050 1055 1060 1065 1070  OK



Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Tue Nov 21, 2023 4:10 pm 
Offline

Joined: Wed Aug 21, 2019 6:10 pm
Posts: 217
JimBoyd wrote:
GARTHWILSON wrote:
The 6502 Forth I got started on used lower-case for the internals, and I have stuck with that. So for example, DO compiles do, LOOP compiles loop, IF compiles 0branch, etc.. It's shorter than (do), (loop), etc.. which I think fig-Forth does, and if you want to put it in a comment marked out by parentheses, you can, without ending the comment prematurely.


Sadly, the Commodore 64 uses PETSCII and it doesn't have a caps lock key, it has a shift lock key.


For my (still unfinished) xForth for the X16, which supports both ASCII and PETSCII, I use upper case ASCII for the Forth words, which is still upper case in PETSCII graphics and is lower case in PETSCII upper/lower case. In that context, lower case for the internals would drive me around the bend, since it would be EXTERNALNAME internalname in ASCII mode and externalname INTERNALNAME in PETSCII upper/lower case and EXTERNALNAME <petsciigraphicstring> in PETSCII graphics mode.

At one time I must have come across a Forth that uses DO<name> for internals, since that I what I mostly have ... DOLOOP DOLIT etc. ... but one of the conventions I might use to save a scattered byte here or there is to use the leading underscore for the internals ... _LOOP _LIT etc.

In PETSCII, that underscore character is a right pointing arrow, which kind of works.


Top
 Profile  
Reply with quote  
 Post subject: Re: Testing CREATE DOES>
PostPosted: Thu Dec 21, 2023 12:01 am 
Offline

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

The internals for the DO LOOPs and a few others now have the same name as the compiling words in my Forth.
The internal for DO is DO and the internal for LOOP is LOOP to name just two. This is because an internal does not normally need found once its compiling word is defined.


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

All times are UTC


Who is online

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