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