Commit | Line | Data |
---|---|---|
a7e60862 WJ |
1 | |
2 | /******************************************** | |
3 | da.c | |
4 | copyright 1991, Michael D. Brennan | |
5 | ||
6 | This is a source file for mawk, an implementation of | |
7 | the AWK programming language. | |
8 | ||
9 | Mawk is distributed without warranty under the terms of | |
10 | the 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 | ||
37 | static char *PROTO(find_bi_name, (PF_CP) ) ; | |
38 | ||
39 | static struct sc { | |
40 | char op ; char *name ; | |
41 | } simple_code[] = { | |
42 | _STOP, "stop", | |
43 | FE_PUSHA, "fe_pusha", | |
44 | FE_PUSHI, "fe_pushi", | |
45 | A_TEST, "a_test", | |
46 | A_DEL , "a_del", | |
47 | A_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", | |
68 | NF_PUSHI, "nf_pushi", | |
69 | F_ASSIGN, "f_assign", | |
70 | F_ADD_ASG, "f_add_asg", | |
71 | F_SUB_ASG, "f_sub_asg", | |
72 | F_MUL_ASG, "f_mul_asg", | |
73 | F_DIV_ASG, "f_div_asg", | |
74 | F_MOD_ASG, "f_mod_asg", | |
75 | F_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", | |
80 | F_POST_INC, "f_post_inc", | |
81 | F_POST_DEC, "f_post_dec", | |
82 | F_PRE_INC, "f_pre_inc", | |
83 | F_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", | |
98 | OL_GL, "ol_gl", | |
99 | OL_GL_NR, "ol_gl_nr", | |
100 | _HALT , (char *) 0 } ; | |
101 | ||
102 | void 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 | ||
312 | static struct { | |
313 | PF_CP action ; | |
314 | char *name ; | |
315 | } special_cases[] = { | |
316 | bi_split, "split", | |
317 | bi_match, "match", | |
318 | bi_getline,"getline", | |
319 | bi_sub, "sub", | |
320 | bi_gsub , "gsub", | |
321 | (PF_CP) 0, (char *) 0 } ; | |
322 | ||
323 | static 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 | ||
339 | static struct fdump { | |
340 | struct fdump *link ; | |
341 | FBLOCK *fbp ; | |
342 | } *fdump_list ; /* linked list of all user functions */ | |
343 | ||
344 | void 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 | ||
351 | void 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 */ |