Search code examples
forthgforth

gforth base-execute syntax


Some online gforth docs provide a seemingly complete description of base-execute's effects:

base-execute       i*x xt u – j*x         gforth       “base-execute”

execute xt with the content of BASE being u, and restoring the
original BASE afterwards.

But the syntax for the effects seems like a lock without a key -- the page links to nothing that describes what i*x xt u – j*x signifies. Some hunting turned up a partial description of the syntax notation, (which tells us that u is an unsigned number and xt is an execution token), but that's still not enough to understand i*x xt u – j*x.

How is base-execute used, and what does it do?


Solution

  • To understand what base-execute does you need to understand execute and BASE. I'll also explain how to read i*x and j*x in the stack effect.

    execute works by taking an execution token xt and executing it. ' 1+ execute is the same as 1+ on its own. The reason to use execute, though, is because you can pass xt on the stack, instead of having to choose it ahead of time. For instance:

    : exec-twice dup >r execute r> execute ;
    2 ' 1+ exec-twice . ( this outputs 4 )
    

    BASE is a variable that controls what numeric base to use for input and output. BASE is initially 10. So 5 2 BASE ! . outputs 101 (which is 5 in base 2).

    base-execute puts them together: it changes BASE to u, executes xt, then restores BASE to its previous value. Its implementation might look like this:

    : base-execute BASE @ >r BASE ! execute r> BASE ! ;
    

    Here's an example usage:

    : squared ( n1 -- n2 ) dup * ;
    : squares ( n -- ) 0 do i squared . loop ;
    
    10 squares ( 0 1 4 9 16 25 36 49 64 81 )
    
    : hex-execute ( i*x xt -- j*x ) 16 base-execute ;
    
    10 ' squares hex-execute ( 0 1 4 9 10 19 24 31 40 51 )
    
    10 squares ( 0 1 ... 81  we're back to decimal )
    

    Now for i*x xt u -- j*x:

    The stack notation documentation you linked to has most of the information you need to read the effect. i*x -- j*x means that something might happen to the stack, but it doesn't specify what. In this case, the exact stack effect depends on what xt is.

    To know the stack effect with a given xt, replace i*x and j*x with the two sides of xt's stack effect.

    For example, if xt is ' . you would look at .'s stack effect, which is n --. In that case you could think of base-execute's stack effect as n xt-of-. u --.