barrym95838 wrote:
Maybe I'm just feeling goofy today, but your assembler/disassembler notations are starting to grow on me (in a good way). How does your disassembler know that FD is W 1- instead of IP 2+ or a thousand other possibilities?
Strings. Seriously, there is a defining word
AMONG that builds a list of numbers. The list is terminated with zero.
AMONG is used in about three other places in the decompiler. The child word takes a number from the stack and returns the index into the list if it is found or -1 if it is not. [Edit: Zero is a valid index.] The index is used as the index into a string array for the names. The string array word is defined and used like this code for i/o error codes ( for the C64 ).
Code:
// from the kernel
HEX
: SARRAY ( -- )
CREATE
DOES> ( U -- )
SWAP 0
?DO COUNT + LOOP
$? ;
// used as
SARRAY SIOERR ( U -- )
," TOO MANY OPEN FILES"
," FILE ALREADY OPEN"
," FILE NOT OPEN"
," FILE NOT FOUND"
," DEVICE NOT PRESENT"
," NOT INPUT FILE"
," NOT OUTPUT FILE"
," MISSING FILE NAME"
," ILLEGAL DEVICE NUMBER"
," UNKNOWN ERROR"
: IOERR ( U -- ) ?DUP 0EXIT
1- 9 UMIN WHERE CR SIOERR
ABORT ;
," compiles a counted string and
$? is just:
Code:
: $? ( ADR -- ) COUNT TYPE ;
Including
SARRAY in the kernel saved memory over the alternative of testing the error number several times as in:
Code:
DUP 1 = ABORT" TOO MANY OPEN FILES"
DUP 2 = ABORT" FILE ALREADY OPEN"
.
.
.
<etc>
Here is
AMONGCode:
: AMONG ( -- ) CREATE
DOES> ( W -- U)
DUP>R
BEGIN
2DUP @ ?DUP
WHILE
= IF
NIP R> - 2/ EXIT
THEN
2+
REPEAT
R> 2DROP <> ;
And here are the relevant tables in the decompiler.
Code:
HEX
SARRAY LABEL ( U -- )
," POPTWO" ," POP" ," SETUP"
," PUSH" ," PUT" ," NEXT"
," IP" ," IP 1+" ," XSAVE"
," UP" ," UP 1+" ," W 1-"
," W" ," W 1+" ," N 1-"
," N" ," N 1+" ," N 2+"
," N 3 +" ," N 4 +" ," N 5 +"
," N 6 +" ," N 7 +"
," APUSH" ," NEXT 2+"
HEX
AMONG ADDRESSES ( W -- U ) ASSEMBLER
POPTWO , POP , SETUP ,
PUSH , PUT , NEXT ,
IP , IP 1+ , XSAVE ,
UP , UP 1+ , W 1- ,
W , W 1+ , N 1- ,
N , N 1+ , N 2+ ,
N 3 + , N 4 + , N 5 + ,
N 6 + , N 7 + ,
APUSH , NEXT 2+ ,
0 ,
FORTH
The decompiler takes the operand and checks if it is in
ADDRESSES. If it is, the decompiler prints the corresponding string.