2 /********************************************
4 copyright 1991, Michael D. Brennan
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
15 * Revision 1.6 1995/06/18 19:19:59 mike
16 * remove use of comma operator that broke some sysVr3 compilers
18 * Revision 1.5 1994/12/13 00:12:08 mike
19 * delete A statement to delete all of A at once
21 * Revision 1.4 1994/10/08 19:15:32 mike
24 * Revision 1.3 1993/12/01 14:25:10 mike
25 * reentrant array loops
27 * Revision 1.2 1993/07/22 00:04:05 mike
28 * new op code _LJZ _LJNZ
30 * Revision 1.1.1.1 1993/07/03 18:58:10 mike
33 * Revision 5.4 1993/01/09 19:05:48 mike
34 * dump code to stdout and exit(0)
36 * Revision 5.3 1993/01/07 02:50:33 mike
37 * relative vs absolute code
39 * Revision 5.2 1992/07/25 21:35:25 brennan
41 * fixed small typo on da of _PRE_DEC
43 * Revision 5.1 1991/12/05 07:55:45 brennan
50 /* disassemble code */
62 static char *PROTO(find_bi_name, (PF_CP)) ;
72 {FE_PUSHA, "fe_pusha"},
73 {FE_PUSHI, "fe_pushi"},
91 {_ADD_ASG, "add_asg"},
92 {_SUB_ASG, "sub_asg"},
93 {_MUL_ASG, "mul_asg"},
94 {_DIV_ASG, "div_asg"},
95 {_MOD_ASG, "mod_asg"},
96 {_POW_ASG, "pow_asg"},
97 {NF_PUSHI, "nf_pushi"},
98 {F_ASSIGN, "f_assign"},
99 {F_ADD_ASG, "f_add_asg"},
100 {F_SUB_ASG, "f_sub_asg"},
101 {F_MUL_ASG, "f_mul_asg"},
102 {F_DIV_ASG, "f_div_asg"},
103 {F_MOD_ASG, "f_mod_asg"},
104 {F_POW_ASG, "f_pow_asg"},
105 {_POST_INC, "post_inc"},
106 {_POST_DEC, "post_dec"},
107 {_PRE_INC, "pre_inc"},
108 {_PRE_DEC, "pre_dec"},
109 {F_POST_INC, "f_post_inc"},
110 {F_POST_DEC, "f_post_dec"},
111 {F_PRE_INC, "f_pre_inc"},
112 {F_PRE_DEC, "f_pre_dec"},
128 {OL_GL_NR, "ol_gl_nr"},
132 static char *jfmt = "%s%s%03d\n" ;
133 /* format to print jumps */
134 static char *tab2 = "\t\t" ;
142 register INST *p = start ;
145 while (p->op != _HALT)
147 /* print the relative code address (label) */
148 fprintf(fp, "%03d ", p - start) ;
154 cp = (CELL *) p++->ptr ;
158 fprintf(fp, "pushc\t0x%lx\t/%s/\n", (long) cp->ptr,
159 re_uncompile(cp->ptr)) ;
163 fprintf(fp, "pushc\tspace split\n") ;
167 fprintf(fp, "pushc\tnull split\n") ;
170 fprintf(fp, "pushc\trepl\t%s\n",
171 repl_uncompile(cp)) ;
174 fprintf(fp, "pushc\treplv\t%s\n",
175 repl_uncompile(cp)) ;
179 fprintf(fp,"pushc\tWEIRD\n") ; ;
185 fprintf(fp, "pushd\t%.6g\n", *(double *) p++->ptr) ;
189 STRING *sval = (STRING *) p++->ptr ;
190 fprintf(fp, "pushs\t\"%s\"\n", sval->str) ;
196 fprintf(fp, "match%d\t0x%lx\t/%s/\n",
197 p[-1].op == _MATCH1, (long) p->ptr,
198 re_uncompile(p->ptr)) ;
203 fprintf(fp, "pusha\t%s\n",
204 reverse_find(ST_VAR, &p++->ptr)) ;
208 cp = (CELL *) p++->ptr ;
209 if (cp == field) fprintf(fp, "pushi\t$0\n") ;
210 else if (cp == &fs_shadow)
211 fprintf(fp, "pushi\t@fs_shadow\n") ;
216 SAMESEG(cp, field) &&
218 cp > NF && cp <= LAST_PFIELD)
219 name = reverse_find(ST_FIELD, &cp) ;
220 else name = reverse_find(ST_VAR, &cp) ;
222 fprintf(fp, "pushi\t%s\n", name) ;
227 fprintf(fp, "l_pusha\t%d\n", p++->op) ;
231 fprintf(fp, "l_pushi\t%d\n", p++->op) ;
235 fprintf(fp, "lae_pushi\t%d\n", p++->op) ;
239 fprintf(fp, "lae_pusha\t%d\n", p++->op) ;
243 fprintf(fp, "la_pusha\t%d\n", p++->op) ;
247 cp = (CELL *) p++->ptr ;
250 SAMESEG(cp, field) &&
252 cp >= NF && cp <= LAST_PFIELD)
253 fprintf(fp, "f_pusha\t%s\n",
254 reverse_find(ST_FIELD, &cp)) ;
255 else fprintf(fp, "f_pusha\t$%d\n",
256 field_addr_to_index(cp)) ;
261 fprintf(fp, "f_pushi\t$%d\n", p++->op) ;
265 fprintf(fp, "ae_pusha\t%s\n",
266 reverse_find(ST_ARRAY, &p++->ptr)) ;
270 fprintf(fp, "ae_pushi\t%s\n",
271 reverse_find(ST_ARRAY, &p++->ptr)) ;
275 fprintf(fp, "a_pusha\t%s\n",
276 reverse_find(ST_ARRAY, &p++->ptr)) ;
280 fprintf(fp, "pushint\t%d\n", p++->op) ;
285 find_bi_name((PF_CP) p++->ptr)) ;
290 (PF_CP) p++->ptr == bi_printf
291 ? "printf" : "print") ;
295 fprintf(fp, jfmt, "jmp", tab2, (p - start) + p->op) ;
300 fprintf(fp, jfmt, "jnz", tab2, (p - start) + p->op) ;
305 fprintf(fp, jfmt, "jz", tab2, (p - start) + p->op) ;
310 fprintf(fp, jfmt, "ljz", tab2, (p - start) + p->op) ;
315 fprintf(fp, jfmt, "ljnz", tab2+1 , (p - start) + p->op) ;
320 fprintf(fp, "set_al\t%03d\n", p + p->op - start) ;
325 fprintf(fp, "aloop\t%03d\n", p - start + p->op) ;
330 fprintf(fp,"a_cat\t%d\n", p++->op) ;
334 fprintf(fp, "call\t%s\t%d\n",
335 ((FBLOCK *) p->ptr)->name, p[1].op) ;
340 fprintf(fp, "range\t%03d %03d %03d\n",
341 /* label for pat2, action, follow */
344 p - start + p[3].op) ;
349 struct sc *q = simple_code ;
350 int k = (p - 1)->op ;
352 while (q->op != _HALT && q->op != k) q++ ;
355 q->op != _HALT ? q->name : "bad instruction") ;
372 {bi_getline, "getline"},
375 {(PF_CP) 0, (char *) 0}
385 for (q = bi_funct; q->name; q++)
393 /* next check some special cases */
394 for (i = 0; special_cases[i].action; i++)
396 if (special_cases[i].action == p) return special_cases[i].name ;
399 return "unknown builtin" ;
406 } *fdump_list ; /* linked list of all user functions */
409 add_to_fdump_list(fbp)
412 struct fdump *p = ZMALLOC(struct fdump) ;
414 p->link = fdump_list ; fdump_list = p ;
420 register struct fdump *p, *q = fdump_list ;
426 fprintf(stdout, "function %s\n", p->fbp->name) ;
427 da(p->fbp->code, stdout) ;