386BSD 0.1 development
[unix-history] / usr / src / usr.bin / awk / da.c
CommitLineData
a7e60862
WJ
1
2/********************************************
3da.c
4copyright 1991, Michael D. Brennan
5
6This is a source file for mawk, an implementation of
7the AWK programming language.
8
9Mawk is distributed without warranty under the terms of
10the GNU General Public License, version 2, 1991.
11********************************************/
12
13
14/* $Log: da.c,v $
15 * Revision 5.1 91/12/05 07:55:45 brennan
16 * 1.1 pre-release
17 *
18*/
19
20
21/* da.c */
22/* disassemble code */
23
24/* This and new posix stuff won't fit in small model DOS */
25
26
27
28#include "mawk.h"
29
30#if ! SM_DOS
31
32#include "code.h"
33#include "bi_funct.h"
34#include "repl.h"
35#include "field.h"
36
37static char *PROTO(find_bi_name, (PF_CP) ) ;
38
39static struct sc {
40char op ; char *name ;
41} simple_code[] = {
42_STOP, "stop",
43FE_PUSHA, "fe_pusha",
44FE_PUSHI, "fe_pushi",
45A_TEST, "a_test",
46A_DEL , "a_del",
47A_CAT, "a_cat",
48_POP, "pop",
49_ADD, "add",
50_SUB, "sub",
51_MUL, "mul",
52_DIV, "div",
53_MOD, "mod",
54_POW, "pow",
55_NOT, "not",
56_UMINUS, "uminus",
57_UPLUS, "uplus",
58_DUP, "dup",
59_TEST, "test",
60_CAT, "cat",
61_ASSIGN, "assign",
62_ADD_ASG, "add_asg",
63_SUB_ASG, "sub_asg",
64_MUL_ASG, "mul_asg",
65_DIV_ASG, "div_asg",
66_MOD_ASG, "mod_asg",
67_POW_ASG, "pow_asg",
68NF_PUSHI, "nf_pushi",
69F_ASSIGN, "f_assign",
70F_ADD_ASG, "f_add_asg",
71F_SUB_ASG, "f_sub_asg",
72F_MUL_ASG, "f_mul_asg",
73F_DIV_ASG, "f_div_asg",
74F_MOD_ASG, "f_mod_asg",
75F_POW_ASG, "f_pow_asg",
76_POST_INC, "post_inc",
77_POST_DEC, "post_dec",
78_PRE_INC, "pre_inc",
79_PRE_INC, "pre_dec",
80F_POST_INC, "f_post_inc",
81F_POST_DEC, "f_post_dec",
82F_PRE_INC, "f_pre_inc",
83F_PRE_INC, "f_pre_dec",
84_EQ, "eq",
85_NEQ, "neq",
86_LT, "lt",
87_LTE, "lte",
88_GT, "gt",
89_GTE, "gte",
90_MATCH2, "match2",
91_EXIT, "exit",
92_EXIT0, "exit0",
93_NEXT, "next",
94_RET, "ret",
95_RET0, "ret0",
96_OMAIN, "omain",
97_JMAIN, "jmain",
98OL_GL, "ol_gl",
99OL_GL_NR, "ol_gl_nr",
100_HALT , (char *) 0 } ;
101
102void da(start, fp)
103 INST *start ;
104 FILE *fp ;
105{ CELL *cp ;
106 register INST *p = start ;
107 char *name ;
108
109 while ( p->op != _HALT )
110 { /* print the relative code address (label) */
111 fprintf(fp,"%03d ", p - start) ;
112
113 switch( p++->op )
114 {
115
116 case _PUSHC :
117 cp = (CELL *) p++->ptr ;
118 switch( cp->type )
119 {
120 case C_RE :
121 fprintf(fp,"pushc\t0x%lx\t/%s/\n" , (long) cp->ptr ,
122 re_uncompile(cp->ptr) ) ;
123 break ;
124
125 case C_SPACE :
126 fprintf(fp, "pushc\tspace split\n") ;
127 break ;
128
129 case C_SNULL :
130 fprintf(fp, "pushc\tnull split\n") ;
131 break ;
132 case C_REPL :
133 fprintf(fp, "pushc\trepl\t%s\n" ,
134 repl_uncompile(cp) ) ;
135 break ;
136 case C_REPLV :
137 fprintf(fp, "pushc\treplv\t%s\n" ,
138 repl_uncompile(cp) ) ;
139 break ;
140
141 default :
142 fprintf(fp,"pushc\tWEIRD\n") ; ;
143 break ;
144 }
145 break ;
146
147 case _PUSHD :
148 fprintf(fp,"pushd\t%.6g\n" , *(double*)p++->ptr) ;
149 break ;
150 case _PUSHS :
151 { STRING *sval = (STRING *) p++->ptr ;
152 fprintf(fp,"pushs\t\"%s\"\n" , sval->str) ;
153 break ;
154 }
155
156 case _MATCH0 :
157 case _MATCH1 :
158 fprintf(fp, "match%d\t0x%lx\t/%s/\n" ,
159 p[-1].op == _MATCH1, (long) p->ptr,
160 re_uncompile(p->ptr) ) ;
161 p++ ;
162 break ;
163
164 case _PUSHA :
165 fprintf(fp,"pusha\t%s\n",
166 reverse_find(ST_VAR, & p++ -> ptr)) ;
167 break ;
168
169 case _PUSHI :
170 cp = (CELL *) p++ -> ptr ;
171 if ( cp == field )
172 fprintf(fp, "pushi\t$0\n") ;
173 else
174 if ( cp == &fs_shadow )
175 fprintf(fp, "pushi\t@fs_shadow\n") ;
176 else
177 {
178 if (
179#if LM_DOS
180 SAMESEG(cp,field) &&
181#endif
182 cp > NF && cp <= LAST_PFIELD )
183 name = reverse_find(ST_FIELD, &cp) ;
184 else
185 name = reverse_find(ST_VAR, &cp) ;
186
187 fprintf(fp, "pushi\t%s\n", name) ;
188 }
189 break ;
190
191 case L_PUSHA :
192 fprintf( fp, "l_pusha\t%d\n", p++->op) ;
193 break ;
194
195 case L_PUSHI :
196 fprintf( fp, "l_pushi\t%d\n", p++->op) ;
197 break ;
198
199 case LAE_PUSHI :
200 fprintf( fp, "lae_pushi\t%d\n", p++->op) ;
201 break ;
202
203 case LAE_PUSHA :
204 fprintf( fp, "lae_pusha\t%d\n", p++->op) ;
205 break ;
206
207 case LA_PUSHA :
208 fprintf( fp, "la_pusha\t%d\n", p++->op) ;
209 break ;
210
211 case F_PUSHA :
212 cp = (CELL *) p++ -> ptr ;
213 if (
214#if LM_DOS
215 SAMESEG(cp,field) &&
216#endif
217 cp >= NF && cp <= LAST_PFIELD )
218 fprintf(fp, "f_pusha\t%s\n",
219 reverse_find(ST_FIELD, &cp)) ;
220 else
221 fprintf(fp, "f_pusha\t$%d\n",
222 field_addr_to_index(cp)) ;
223 break ;
224
225 case F_PUSHI :
226 p++ ;
227 fprintf(fp, "f_pushi\t$%d\n", p++ -> op) ;
228 break ;
229
230 case AE_PUSHA :
231 fprintf(fp,"ae_pusha\t%s\n" ,
232 reverse_find(ST_ARRAY, & p++->ptr) ) ;
233 break ;
234
235 case AE_PUSHI :
236 fprintf(fp,"ae_pushi\t%s\n" ,
237 reverse_find(ST_ARRAY, & p++->ptr)) ;
238 break ;
239
240 case A_PUSHA :
241 fprintf(fp,"a_pusha\t%s\n" ,
242 reverse_find(ST_ARRAY, & p++->ptr)) ;
243 break ;
244
245 case _PUSHINT :
246 fprintf(fp,"pushint\t%d\n" , p++ -> op ) ;
247 break ;
248
249 case _BUILTIN :
250 fprintf(fp,"%s\n" ,
251 find_bi_name( (PF_CP) p++ -> ptr ) ) ;
252 break ;
253
254 case _PRINT :
255 fprintf(fp,"%s\n",
256 (PF_CP) p++ -> ptr == bi_printf
257 ? "printf" : "print") ;
258 break ;
259
260 case _JMP :
261 case _JNZ :
262 case _JZ :
263 { int j = (p-1)->op ;
264 char *s = j == _JMP ? "jmp" :
265 j == _JNZ ? "jnz" : "jz" ;
266
267 fprintf(fp,"%s\t\t%03d\n" , s ,
268 (p - start) + p->op ) ;
269 p++ ;
270 break ;
271 }
272
273 case SET_ALOOP :
274 fprintf(fp, "s_aloop\t%03d\n", p + p->op - start ) ;
275 p++ ;
276 break ;
277
278 case ALOOP :
279 fprintf(fp,"aloop\t%03d\n", p-start+p->op) ;
280 p += 2 ;
281 break ;
282
283 case _CALL :
284 fprintf(fp, "call\t%s\t%d\n",
285 ((FBLOCK*)p->ptr)->name , p[1].op) ;
286 p += 2 ;
287 break ;
288
289 case _RANGE :
290 fprintf(fp, "range\t%03d %03d %03d\n",
291 /* label for pat2, action, follow */
292 p - start + p[1].op ,
293 p - start + p[2].op ,
294 p - start + p[3].op ) ;
295 p += 4 ;
296 break ;
297 default :
298 {
299 struct sc *q = simple_code ;
300 int k = (p-1)->op ;
301
302 while ( q->op != _HALT && q->op != k ) q++ ;
303
304 fprintf(fp, "%s\n",
305 q->op != _HALT ? q->name : "bad instruction") ;
306 }
307 break ;
308 }
309 }
310}
311
312static struct {
313PF_CP action ;
314char *name ;
315} special_cases[] = {
316bi_split, "split",
317bi_match, "match",
318bi_getline,"getline",
319bi_sub, "sub",
320bi_gsub , "gsub",
321(PF_CP) 0, (char *) 0 } ;
322
323static char *find_bi_name( p )
324 PF_CP p ;
325{ BI_REC *q ;
326 int i ;
327
328 for( q = bi_funct ; q->name ; q++ )
329 if ( q->fp == p ) /* found */
330 return q->name ;
331 /* next check some special cases */
332 for( i = 0 ; special_cases[i].action ; i++)
333 if ( special_cases[i].action == p )
334 return special_cases[i].name ;
335
336 return "unknown builtin" ;
337}
338
339static struct fdump {
340struct fdump *link ;
341FBLOCK *fbp ;
342} *fdump_list ; /* linked list of all user functions */
343
344void add_to_fdump_list( fbp )
345 FBLOCK *fbp ;
346{ struct fdump *p = (struct fdump *)zmalloc(sizeof(struct fdump)) ;
347 p->fbp = fbp ;
348 p->link = fdump_list ; fdump_list = p ;
349}
350
351void fdump()
352{
353 register struct fdump *p, *q = fdump_list ;
354
355 while ( p = q )
356 { q = p->link ;
357 fprintf(stderr, "function %s\n" , p->fbp->name) ;
358 da(p->fbp->code, stderr) ;
359 zfree(p, sizeof(struct fdump)) ;
360 }
361}
362
363#endif /* SM_DOS */