NetBSD/gnu/usr.bin/awk/da.c

371 lines
8.5 KiB
C

/********************************************
da.c
copyright 1991, Michael D. Brennan
This is a source file for mawk, an implementation of
the AWK programming language.
Mawk is distributed without warranty under the terms of
the GNU General Public License, version 2, 1991.
********************************************/
/* $Log: da.c,v $
/* Revision 1.2 1993/07/02 23:57:11 jtc
/* Updated to mawk 1.1.4
/*
* Revision 5.2 1992/07/25 21:35:25 brennan
* patch2
* fixed small typo on da of _PRE_DEC
*
* Revision 5.1 1991/12/05 07:55:45 brennan
* 1.1 pre-release
*
*/
/* da.c */
/* disassemble code */
/* This and new posix stuff won't fit in small model DOS */
#include "mawk.h"
#if ! SM_DOS
#include "code.h"
#include "bi_funct.h"
#include "repl.h"
#include "field.h"
static char *PROTO(find_bi_name, (PF_CP) ) ;
static struct sc {
char op ; char *name ;
} simple_code[] = {
_STOP, "stop",
FE_PUSHA, "fe_pusha",
FE_PUSHI, "fe_pushi",
A_TEST, "a_test",
A_DEL , "a_del",
A_CAT, "a_cat",
_POP, "pop",
_ADD, "add",
_SUB, "sub",
_MUL, "mul",
_DIV, "div",
_MOD, "mod",
_POW, "pow",
_NOT, "not",
_UMINUS, "uminus",
_UPLUS, "uplus",
_DUP, "dup",
_TEST, "test",
_CAT, "cat",
_ASSIGN, "assign",
_ADD_ASG, "add_asg",
_SUB_ASG, "sub_asg",
_MUL_ASG, "mul_asg",
_DIV_ASG, "div_asg",
_MOD_ASG, "mod_asg",
_POW_ASG, "pow_asg",
NF_PUSHI, "nf_pushi",
F_ASSIGN, "f_assign",
F_ADD_ASG, "f_add_asg",
F_SUB_ASG, "f_sub_asg",
F_MUL_ASG, "f_mul_asg",
F_DIV_ASG, "f_div_asg",
F_MOD_ASG, "f_mod_asg",
F_POW_ASG, "f_pow_asg",
_POST_INC, "post_inc",
_POST_DEC, "post_dec",
_PRE_INC, "pre_inc",
_PRE_DEC, "pre_dec",
F_POST_INC, "f_post_inc",
F_POST_DEC, "f_post_dec",
F_PRE_INC, "f_pre_inc",
F_PRE_DEC, "f_pre_dec",
_EQ, "eq",
_NEQ, "neq",
_LT, "lt",
_LTE, "lte",
_GT, "gt",
_GTE, "gte",
_MATCH2, "match2",
_EXIT, "exit",
_EXIT0, "exit0",
_NEXT, "next",
_RET, "ret",
_RET0, "ret0",
_OMAIN, "omain",
_JMAIN, "jmain",
OL_GL, "ol_gl",
OL_GL_NR, "ol_gl_nr",
_HALT , (char *) 0 } ;
void da(start, fp)
INST *start ;
FILE *fp ;
{ CELL *cp ;
register INST *p = start ;
char *name ;
while ( p->op != _HALT )
{ /* print the relative code address (label) */
fprintf(fp,"%03d ", p - start) ;
switch( p++->op )
{
case _PUSHC :
cp = (CELL *) p++->ptr ;
switch( cp->type )
{
case C_RE :
fprintf(fp,"pushc\t0x%lx\t/%s/\n" , (long) cp->ptr ,
re_uncompile(cp->ptr) ) ;
break ;
case C_SPACE :
fprintf(fp, "pushc\tspace split\n") ;
break ;
case C_SNULL :
fprintf(fp, "pushc\tnull split\n") ;
break ;
case C_REPL :
fprintf(fp, "pushc\trepl\t%s\n" ,
repl_uncompile(cp) ) ;
break ;
case C_REPLV :
fprintf(fp, "pushc\treplv\t%s\n" ,
repl_uncompile(cp) ) ;
break ;
default :
fprintf(fp,"pushc\tWEIRD\n") ; ;
break ;
}
break ;
case _PUSHD :
fprintf(fp,"pushd\t%.6g\n" , *(double*)p++->ptr) ;
break ;
case _PUSHS :
{ STRING *sval = (STRING *) p++->ptr ;
fprintf(fp,"pushs\t\"%s\"\n" , sval->str) ;
break ;
}
case _MATCH0 :
case _MATCH1 :
fprintf(fp, "match%d\t0x%lx\t/%s/\n" ,
p[-1].op == _MATCH1, (long) p->ptr,
re_uncompile(p->ptr) ) ;
p++ ;
break ;
case _PUSHA :
fprintf(fp,"pusha\t%s\n",
reverse_find(ST_VAR, & p++ -> ptr)) ;
break ;
case _PUSHI :
cp = (CELL *) p++ -> ptr ;
if ( cp == field )
fprintf(fp, "pushi\t$0\n") ;
else
if ( cp == &fs_shadow )
fprintf(fp, "pushi\t@fs_shadow\n") ;
else
{
if (
#if LM_DOS
SAMESEG(cp,field) &&
#endif
cp > NF && cp <= LAST_PFIELD )
name = reverse_find(ST_FIELD, &cp) ;
else
name = reverse_find(ST_VAR, &cp) ;
fprintf(fp, "pushi\t%s\n", name) ;
}
break ;
case L_PUSHA :
fprintf( fp, "l_pusha\t%d\n", p++->op) ;
break ;
case L_PUSHI :
fprintf( fp, "l_pushi\t%d\n", p++->op) ;
break ;
case LAE_PUSHI :
fprintf( fp, "lae_pushi\t%d\n", p++->op) ;
break ;
case LAE_PUSHA :
fprintf( fp, "lae_pusha\t%d\n", p++->op) ;
break ;
case LA_PUSHA :
fprintf( fp, "la_pusha\t%d\n", p++->op) ;
break ;
case F_PUSHA :
cp = (CELL *) p++ -> ptr ;
if (
#if LM_DOS
SAMESEG(cp,field) &&
#endif
cp >= NF && cp <= LAST_PFIELD )
fprintf(fp, "f_pusha\t%s\n",
reverse_find(ST_FIELD, &cp)) ;
else
fprintf(fp, "f_pusha\t$%d\n",
field_addr_to_index(cp)) ;
break ;
case F_PUSHI :
p++ ;
fprintf(fp, "f_pushi\t$%d\n", p++ -> op) ;
break ;
case AE_PUSHA :
fprintf(fp,"ae_pusha\t%s\n" ,
reverse_find(ST_ARRAY, & p++->ptr) ) ;
break ;
case AE_PUSHI :
fprintf(fp,"ae_pushi\t%s\n" ,
reverse_find(ST_ARRAY, & p++->ptr)) ;
break ;
case A_PUSHA :
fprintf(fp,"a_pusha\t%s\n" ,
reverse_find(ST_ARRAY, & p++->ptr)) ;
break ;
case _PUSHINT :
fprintf(fp,"pushint\t%d\n" , p++ -> op ) ;
break ;
case _BUILTIN :
fprintf(fp,"%s\n" ,
find_bi_name( (PF_CP) p++ -> ptr ) ) ;
break ;
case _PRINT :
fprintf(fp,"%s\n",
(PF_CP) p++ -> ptr == bi_printf
? "printf" : "print") ;
break ;
case _JMP :
case _JNZ :
case _JZ :
{ int j = (p-1)->op ;
char *s = j == _JMP ? "jmp" :
j == _JNZ ? "jnz" : "jz" ;
fprintf(fp,"%s\t\t%03d\n" , s ,
(p - start) + p->op ) ;
p++ ;
break ;
}
case SET_ALOOP :
fprintf(fp, "s_aloop\t%03d\n", p + p->op - start ) ;
p++ ;
break ;
case ALOOP :
fprintf(fp,"aloop\t%03d\n", p-start+p->op) ;
p += 2 ;
break ;
case _CALL :
fprintf(fp, "call\t%s\t%d\n",
((FBLOCK*)p->ptr)->name , p[1].op) ;
p += 2 ;
break ;
case _RANGE :
fprintf(fp, "range\t%03d %03d %03d\n",
/* label for pat2, action, follow */
p - start + p[1].op ,
p - start + p[2].op ,
p - start + p[3].op ) ;
p += 4 ;
break ;
default :
{
struct sc *q = simple_code ;
int k = (p-1)->op ;
while ( q->op != _HALT && q->op != k ) q++ ;
fprintf(fp, "%s\n",
q->op != _HALT ? q->name : "bad instruction") ;
}
break ;
}
}
}
static struct {
PF_CP action ;
char *name ;
} special_cases[] = {
bi_split, "split",
bi_match, "match",
bi_getline,"getline",
bi_sub, "sub",
bi_gsub , "gsub",
(PF_CP) 0, (char *) 0 } ;
static char *find_bi_name( p )
PF_CP p ;
{ BI_REC *q ;
int i ;
for( q = bi_funct ; q->name ; q++ )
if ( q->fp == p ) /* found */
return q->name ;
/* next check some special cases */
for( i = 0 ; special_cases[i].action ; i++)
if ( special_cases[i].action == p )
return special_cases[i].name ;
return "unknown builtin" ;
}
static struct fdump {
struct fdump *link ;
FBLOCK *fbp ;
} *fdump_list ; /* linked list of all user functions */
void add_to_fdump_list( fbp )
FBLOCK *fbp ;
{ struct fdump *p = (struct fdump *)zmalloc(sizeof(struct fdump)) ;
p->fbp = fbp ;
p->link = fdump_list ; fdump_list = p ;
}
void fdump()
{
register struct fdump *p, *q = fdump_list ;
while ( p = q )
{ q = p->link ;
fprintf(stderr, "function %s\n" , p->fbp->name) ;
da(p->fbp->code, stderr) ;
zfree(p, sizeof(struct fdump)) ;
}
}
#endif /* SM_DOS */