IamRob wrote:
In stead of using :NONAME, can one not just use HERE, then write some code, leave HERE on the stack so that when some future word definition needs it, the address to return to is already there. You wouldn't even need to create a colon definition or use :NONAME.
:NONAME is used to create a headerless colon definition and some of the words in Fleet Forth's system loader are candidates. These colon definitions are complex enough that I would not want to rewrite them as code words, code words which would be much larger.
Quote:
It would just be:
Code:
HERE 0 , CODE
.
.
.
ENDCODE
The
0 , would be needed since
CODE does a -2 allot, which stores the
CFA which points to the
PFA (or body) of a regular word definition. The address for
HERE gets left on the stack and is used, when needed, in the assembler calculation. Which I believe needs to be
HERE+2 to skip past the
CFA pointer.
Using CODE to create a headerless code word doesn't work because CODE parses the text stream for a name and creates a header. 64Forth's CODE behaves the same way.
Code:
: CODE ?EXEC CREATE [COMPILE] ASSEMBLER MEM !CSP ;S IMMEDIATE
This is Fleet Forth's CODE
Code:
: SUBR ( -- ADR TRUE )
CREATE LATEST TRUE
OVER TSB
[ ASSEMBLER ] ASSEMBLER MEM ;
: CODE ( -- ADR TRUE )
SUBR HERE DUP 2- ! ;
Neither version has -2 ALLOT .
The word SUBR is for creating subroutines. Here is an example from Fleet Forth's kernel.
Code:
SUBR (>FORTH) ( -- )
CLC
PLA 1 # ADC N STA
PLA 0 # ADC TAY
IP 1+ LDA PHA
IP LDA PHA
N LDA
IP STA
IP 1+ STY
NEXT JMP END-CODE
And its use in the assembler.
Code:
ASSEMBLER DEFINITIONS
: >FORTH ( -- )
?EXEC
(>FORTH) JSR
CURRENT @ CONTEXT !
] ; IMMEDIATE
FORTH DEFINITIONS
Although (>FORTH) , and all SUBR words, return the address of the code, the code in (>FORTH) does not alter the data stack.
I've also looked at the fig-FORTH Installation Manual and it appears that version of CODE also creates a header.
Here is a test screen.
Code:
SCR# 8001
0: // TEST -- THIS IS GOING TO FAIL!
1: HERE 0 , CODE ( N -- N+10 )
2: CLC
3: 0 ,X LDA 10 # ADC 0 ,X STA
4: TYA 1 ,X ADC 1 ,X STA
5: NEXT JMP
6: END-CODE
7:
8:
9:
A:
B:
C:
D:
E:
F:
And the result of trying to load it.
Code:
0 FH LOAD
( EXISTS
SCR# 32769 LINE# 1
HERE 0 , CODE ( N -- N+10 )
^^
WHAT?
So CODE tries to redefine open parenthesis and the system aborts when double dash can't be found in the specified search order. Not surprising since double dash isn't defined in Fleet Forth.
One way to create a headerless code word in Fleet Forth would be the following.
Code:
ASSEMBLER MEM ALIGN // NAMELESS CODE DEF -- INCONVENIENT
HERE DUP 2+ ,
$D020 INC
NEXT JMP
FORTH
I should mention that ALIGN does not align to an even address. If the address is of the form $xxFF, ALIGN allots one byte to push the address past the page boundary. This is done to avoid the indirect jump bug found in NMOS 6502s and the C64's 6510 processor.
Here is a way to create headerless subroutines in Fleet Forth. There is no CFA, just an address to to be used by JSR.
Code:
HERE ASSEMBLER MEM
$D020 INC
RTS
FORTH
Used like so.
Code:
>A \ push address to aux stack
CODE TEST
A> JSR NEXT JMP \ pull it and use with JSR
END-CODE