Factored FIND.
[forth.jl.git] / src / lib_8_decompiler.4th
1 \ Decompilation
2
3 : SEE
4         BL WORD FIND    ( find the dictionary entry to decompile )
5
6         CR
7
8         0= IF
9                 ." Word '" COUNT TYPE ." ' not found in dictionary."
10                 EXIT
11         THEN
12
13         >LINK
14
15         ( Now we search again, looking for the next word in the dictionary.  This gives us
16           the length of the word that we will be decompiling.  (Well, mostly it does). )
17         HERE          ( address of the end of the last compiled word )
18         LATEST @        ( word last curr )
19         BEGIN
20                 2 PICK          ( word last curr word )
21                 OVER            ( word last curr word curr )
22                 <>              ( word last curr word<>curr? )
23         WHILE                   ( word last curr )
24                 NIP             ( word curr )
25                 DUP @           ( word curr prev (which becomes: word last curr) )
26         REPEAT
27
28         DROP            ( at this point, the stack is: start-of-word end-of-word )
29         SWAP            ( end-of-word start-of-word )
30
31         DUP LINK> @ CASE
32                 DOCOL OF
33                         \ Colon definition
34                         [CHAR] : EMIT SPACE DUP 1+ .NAME SPACE
35                         DUP ?IMMEDIATE IF ." IMMEDIATE " THEN CR
36                 ENDOF
37                 DOVAR OF
38                         \ Variable definition
39                         ." Variable " DUP 1+ .NAME CR
40                         2DROP EXIT
41                 ENDOF
42                 DOCON OF
43                         \ Constant definition
44                         ." Constant " DUP 1+ .NAME CR
45                         2DROP EXIT
46                 ENDOF
47
48                 \ Unknown codeword
49                 ." Primitive or word with unrecognized codeword." CR 
50                 DROP 2DROP EXIT
51         ENDCASE
52
53         4 SPACES
54
55         LINK> >BODY            ( get the data address, ie. points after DOCOL | end-of-word start-of-data )
56
57         ( now we start decompiling until we hit the end of the word )
58         BEGIN           ( end start )
59                 2DUP >
60         WHILE
61                 DUP @           ( end start codeword )
62
63                 CASE
64                 ['] LIT OF                ( is it LIT ? )
65                         1+ DUP @                ( get next word which is the integer constant )
66                         .                       ( and print it )
67                 ENDOF
68                 ['] LITSTRING OF          ( is it LITSTRING ? )
69                         [CHAR] S EMIT [CHAR] " EMIT SPACE ( print S"<space> )
70                         1+ DUP @                ( get the length word )
71                         SWAP 1+ SWAP            ( end start+1 length )
72                         2DUP TYPE               ( print the string )
73                         [CHAR] " EMIT SPACE          ( finish the string with a final quote )
74                         +                       ( end start+1+len, aligned )
75                         1-                     ( because we're about to add 4 below )
76                 ENDOF
77                 ['] 0BRANCH OF            ( is it 0BRANCH ? )
78                         ." 0BRANCH ( "
79                         1+ DUP @               ( print the offset )
80                         .
81                         ." ) "
82                 ENDOF
83                 ['] BRANCH OF             ( is it BRANCH ? )
84                         ." BRANCH ( "
85                         1+ DUP @               ( print the offset )
86                         .
87                         ." ) "
88                 ENDOF
89                 ['] ['] OF                  ( is it ['] ? )
90                         ." ['] "
91                         1+ DUP @               ( get the next codeword )
92                         >NAME                    ( and force it to be printed as a dictionary entry )
93                         .NAME SPACE
94                 ENDOF
95                 ['] EXIT OF               ( is it EXIT? )
96                         ( We expect the last word to be EXIT, and if it is then we don't print it
97                           because EXIT is normally implied by ;.  EXIT can also appear in the middle
98                           of words, and then it needs to be printed. )
99                         2DUP                    ( end start end start )
100                         1+                     ( end start end start+1 )
101                         <> IF                   ( end start | we're not at the end )
102                                 ." EXIT "
103                         THEN
104                 ENDOF
105                                         ( default case: )
106                         DUP                     ( in the default case we always need to DUP before using )
107                         >NAME                    ( look up the codeword to get the dictionary entry )
108                         .NAME SPACE               ( and print it )
109                 ENDCASE
110
111                 1+             ( end start+1 )
112         REPEAT
113
114         [CHAR] ; EMIT CR
115
116         2DROP           ( restore stack )
117 ;
118