How to write an inlining CONST word?

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
Post Reply
pdragon
Posts: 126
Joined: 26 Sep 2023

How to write an inlining CONST word?

Post by pdragon »

It seems like CONSTANT words compile a reference to themselves, so the value isn't looked up til run-time.
I guess this allows the value to change before the word executes which is perhaps a benefit in some cases.

I want to make a CONST word which just inlines itself at compile-time, so the value is guaranteed and it runs a bit faster.

Code: Select all

42 CONSTANT a
: foo a + ;  \ the word a executes at runtime to deliver its value

: foo [ a ] literal + ;  \ the value of a is inlined at compile time
Below is what I came up with - is there a better way?

Code: Select all

: CONST ( n "name" -- ) 
    CREATE ,  IMMEDIATE            
    DOES> @  STATE @ IF POSTPONE LITERAL THEN 
;
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: How to write an inlining CONST word?

Post by GARTHWILSON »

What threading model are you interested in doing this in?  The way I do it in my ITC Forth is almost the same for CONSTANT as for VARIABLE, both putting a number on the stack, but for a variable the number is expected to be an address.  It was many years ago that I wrote it, but it looks like if I were to really get into the details now I would find not more than a cycle or two difference in execution speed in my '816 Forth.  That's for when the target computer is running.  When I'm forming the kernel in another computer, whether assembling or compiling, for a ROM-based system where the variable's data cannot be right there with the variable's header, they truly are the same, and VARIABLE just returns the (constant) number which is the address of the variable's data in RAM.  The runtime is const for both VARIABLE and CONSTANT.  No difference.

In your example though, if you have an assembler onboard and it's super easy to write primitives, why not just do that.  In the simplest example, 1+ in the '816 with accumulator width set to 16-bit becomes just INC  0,X, rather that putting 1 on the stack as a constant and then running the add routine.  If there's a number you need to add frequently and quickly, make it a primitive, for example 42+ becomes (for 65816 with accumulator width option set to 16-bit):

Code: Select all

        LDA  0,X
        CLC
        ADC  #42
        STA  0,X
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?
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: How to write an inlining CONST word?

Post by SamCoVT »

If you want speed instead of size, you can forgo using LITERAL and just put the assembly to get the value on the stack (looks like Garth beat me to it):

Code: Select all

assembler-wordlist >order
: const  create , immediate   does>
  @  STATE @ IF
    postpone dex postpone dex
    $100 /mod
    postpone lda.#   1 postpone sta.zx
    postpone lda.#   0 postpone sta.zx 
  THEN ;
If you are doing a lot of 8-bit work, you could also make a version that just uses STZ for the high byte.

All of the POSTPONEs on the assembly words essentially create an assembly macro.

Edit: To answer Garth's question, I'm assuming this is for Tali Forth 2, an STC Forth, which makes it super easy to mix in some assembly.
pdragon
Posts: 126
Joined: 26 Sep 2023

Re: How to write an inlining CONST word?

Post by pdragon »

yes, for Tali. Looks like it automatically does the inlining from the postpone literal already :heart:

Code: Select all

42 const fubar  ok
fubar . 42  ok
.s <0>  ok
: snafu fubar + ;  ok
see snafu 
...
943     2A lda.#
945        dex
946        dex
947      0 sta.zx
949      1 stz.zx
94B   80BE jsr     2 STACK DEPTH CHECK
94E        clc
94F      0 lda.zx
951      2 adc.zx
953      2 sta.zx
955      1 lda.zx
957      3 adc.zx
959      3 sta.zx
95B        inx
95C        inx
 ok
.s <0>  ok
7 snafu . 49  ok
pdragon
Posts: 126
Joined: 26 Sep 2023

Re: How to write an inlining CONST word?

Post by pdragon »

yes, i like Garth's idea of adding a couple of primitives too. I think I can speed up the 65c02-on-65c02 emulator a lot with inlined const and some well-chosen bit-twiddling words for all the flag updates. needs a bit of thought about exactly what words tho.
Post Reply