Imported Debian patch 21-11
[debian/pforth] / see.fth
1 \ @(#) see.fth 98/01/26 1.4
2 \ SEE ( <name> -- , disassemble pForth word )
3 \
4 \ Copyright 1996 Phil Burk
5
6 ' file? >code rfence a!
7
8 anew task-see.fth
9
10 : .XT ( xt -- , print execution tokens name )
11         >name
12         dup c@ flag_immediate and
13         IF
14                 ." POSTPONE "
15         THEN
16         id. space
17 ;
18
19 \ dictionary may be defined as byte code or cell code
20 0 constant BYTE_CODE
21
22 BYTE_CODE [IF]
23         : CODE@ ( addr -- xt , fetch from code space )   C@ ;
24         1 constant CODE_CELL
25         .( BYTE_CODE not implemented) abort
26 [ELSE]
27         : CODE@ ( addr -- xt , fetch from code space )   @ ;
28         CELL constant CODE_CELL
29 [THEN]
30
31 private{
32
33 0 value see_level  \ level of conditional imdentation
34 0 value see_addr   \ address of next token
35 0 value see_out
36
37 : SEE.INDENT.BY ( -- n )
38         see_level 1+ 1 max 4 *
39 ;
40
41 : SEE.CR
42         >newline
43         see_addr ." ( ".hex ." )"
44         see.indent.by spaces
45         0 -> see_out
46 ;
47 : SEE.NEWLINE
48         see_out 0>
49         IF see.cr
50         THEN
51 ;
52 : SEE.CR?
53         see_out 6 >
54         IF
55                 see.newline
56         THEN
57 ;
58 : SEE.OUT+
59         1 +-> see_out
60 ;
61
62 : SEE.ADVANCE
63         code_cell +-> see_addr
64 ;
65 : SEE.GET.INLINE ( -- n )
66         see_addr @
67 ;
68
69 : SEE.GET.TARGET  ( -- branch-target-addr )
70         see_addr @ see_addr +
71 ;
72
73 : SEE.SHOW.LIT ( -- )
74         see.get.inline .
75         see.advance
76         see.out+
77 ;
78
79 exists? F* [IF]
80 : SEE.SHOW.FLIT ( -- )
81         see_addr f@ f.
82         1 floats +-> see_addr
83         see.out+
84 ;
85 [THEN]
86
87 : SEE.SHOW.ALIT ( -- )
88         see.get.inline >name id. space
89         see.advance
90         see.out+
91 ;
92
93 : SEE.SHOW.STRING ( -- )
94         see_addr count 2dup + aligned -> see_addr type
95         see.out+
96 ;
97 : SEE.SHOW.TARGET ( -- )
98         see.get.target .hex see.advance
99 ;
100
101 : SEE.BRANCH ( -- addr | , handle branch )
102         -1 +-> see_level
103         see.newline 
104         see.get.inline  0>
105         IF  \ forward branch
106                 ." ELSE "
107                 see.get.target \ calculate address of target
108                 1 +-> see_level
109                 nip \ remove old address for THEN
110         ELSE
111                 ." REPEAT " see.get.target .hex
112                 drop \ remove old address for THEN
113         THEN
114         see.advance
115         see.cr
116 ;
117
118 : SEE.0BRANCH ( -- addr | , handle 0branch )
119         see.newline 
120         see.get.inline 0>
121         IF  \ forward branch
122                 ." IF or WHILE "
123                 see.get.target \ calculate adress of target
124                 1 +-> see_level
125         ELSE
126                 ." UNTIL=>" see.get.target .hex
127         THEN
128         see.advance
129         see.cr
130 ;
131
132 : SEE.XT  { xt -- }
133         xt
134         CASE
135                 0 OF see_level 0> IF ." EXIT " see.out+ ELSE ." ;" 0  -> see_addr THEN ENDOF
136                 ['] (LITERAL) OF see.show.lit ENDOF
137                 ['] (ALITERAL) OF see.show.alit ENDOF
138 [ exists? (FLITERAL) [IF] ]
139                 ['] (FLITERAL) OF see.show.flit ENDOF
140 [ [THEN] ]
141                 ['] BRANCH    OF see.branch ENDOF
142                 ['] 0BRANCH   OF see.0branch ENDOF
143                 ['] (LOOP)    OF -1 +-> see_level see.newline ." LOOP " see.advance see.cr  ENDOF
144                 ['] (+LOOP)   OF -1 +-> see_level see.newline ." +LOOP" see.advance see.cr  ENDOF
145                 ['] (DO)      OF see.newline ." DO" 1 +-> see_level see.cr ENDOF
146                 ['] (?DO)     OF see.newline ." ?DO " see.advance 1 +-> see_level see.cr ENDOF
147                 ['] (.") OF .' ." ' see.show.string .' " ' ENDOF
148                 ['] (C") OF .' C" ' see.show.string .' " ' ENDOF
149                 ['] (S") OF .' S" ' see.show.string .' " ' ENDOF
150
151                 see.cr? xt .xt see.out+
152         ENDCASE
153 ;
154
155 : (SEE) { cfa | xt  -- }
156         0 -> see_level
157         cfa -> see_addr
158         see.cr
159         0 \ fake address for THEN handler
160         BEGIN
161                 see_addr code@ -> xt
162                 BEGIN
163                         dup see_addr ( >newline .s ) =
164                 WHILE
165                         -1 +-> see_level see.newline 
166                         ." THEN " see.cr
167                         drop
168                 REPEAT
169                 CODE_CELL +-> see_addr
170                 xt see.xt
171                 see_addr 0=
172         UNTIL
173         cr
174         0= not abort" SEE conditional analyser nesting failed!"
175 ;
176
177 }PRIVATE
178
179 : SEE  ( <name> -- , disassemble )
180         '
181         dup ['] FIRST_COLON >
182         IF
183                 >code (see)
184         ELSE
185                 >name id.
186                 ."  is primitive defined in 'C' kernel." cr
187         THEN
188 ;
189
190 PRIVATIZE
191
192 0 [IF]
193
194 : SEE.JOKE
195         dup swap drop
196 ;
197
198 : SEE.IF
199         IF
200                 ." hello" cr
201         ELSE
202                 ." bye" cr
203         THEN
204         see.joke
205 ;
206 : SEE.DO
207         4 0
208         DO
209                 i . cr
210         LOOP
211 ;
212 : SEE."
213         ." Here are some strings." cr
214         c" Forth string." count type cr
215         s" Addr/Cnt string" type cr
216 ;
217
218 [THEN]