I found that
: x : y ;
is legal (in gforth at least), but I can't think of a use case for this construct.
As I understand, executing x
start a redefinition of y
, but throw error at the closing semicolon:
: y 42 ; ok
: x : y ; ok
x 43 ;
:3: unstructured
x 43 >>>;<<<
Backtrace:
$7FD8A0818988 throw
$7FD8A08284E0 c(abort")
$7FD8A0835600 def?
$7FD8A08218C0 ;-hook
Can someone explain this?
I often type a colon instead of a semicolon and my interpreter crashes. I was going to add a check and treat it like any other error, but I can't do that if it's a legal construct.
If you don't need this construct, you can add the check:
: : ( "name" -- colon-sys )
state @ abort" colon inside a definition?"
:
; immediate
Now, to use :
inside a definition you have to write ['] : execute
.
As you can see, we legally use :
inside a definition to make this check. Another example of such use is preventing redefinitions.
Note that :
(Colon), when executed, consumes name from the input buffer (see Parsed-text notation) and leaves colon-sys on the stack, and ;
(Semicolon) consumes this colon-sys from the stack: ( colon-sys -- )
. If Semicolon does not see colon-sys on the top of the stack, it may throw an error (and it does throw in Gforth). This is not actually related to stack depth, but to data types checking.
Also note, when the Forth text interpreter encounters the standard word :
while compiling a definition, it does not execute this word, but compiles it — because this word is ordinary. The above implementation for Colon is an immediate word, so when the Forth text interpreter encounters it while compiling a definition, it executes it.