Logo Search packages:      
Sourcecode: mawk version File versions  Download package

da.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.6  1995/06/18  19:19:59  mike
 * remove use of comma operator that broke some sysVr3 compilers
 *
 * Revision 1.5  1994/12/13  00:12:08  mike
 * delete A statement to delete all of A at once
 *
 * Revision 1.4  1994/10/08  19:15:32  mike
 * remove SM_DOS
 *
 * Revision 1.3  1993/12/01  14:25:10  mike
 * reentrant array loops
 *
 * Revision 1.2  1993/07/22  00:04:05  mike
 * new op code _LJZ _LJNZ
 *
 * Revision 1.1.1.1  1993/07/03      18:58:10  mike
 * move source to cvs
 *
 * Revision 5.4    1993/01/09  19:05:48  mike
 * dump code to stdout and exit(0)
 *
 * Revision 5.3    1993/01/07  02:50:33  mike
 * relative vs absolute code
 *
 * 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 */



#include  "mawk.h"


#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",
   DEL_A, "del_a",
   POP_AL, "pop_al",
   _POP, "pop",
   _ADD, "add",
   _SUB, "sub",
   _MUL, "mul",
   _DIV, "div",
   _MOD, "mod",
   _POW, "pow",
   _NOT, "not",
   _UMINUS, "uminus",
   _UPLUS, "uplus",
   _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
} ;

static char *jfmt = "%s%s%03d\n" ; 
   /* format to print jumps */
static char *tab2 = "\t\t" ;

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 (
#ifdef  MSDOS
                 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 (
#ifdef  MSDOS
              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:
          fprintf(fp, jfmt, "jmp", tab2, (p - start) + p->op) ;
          p++ ;
          break ;

       case _JNZ:
          fprintf(fp, jfmt, "jnz", tab2, (p - start) + p->op) ;
          p++ ;
          break ;

       case _JZ:
          fprintf(fp, jfmt, "jz", tab2, (p - start) + p->op) ;
          p++ ;
          break ;

       case _LJZ:
          fprintf(fp, jfmt, "ljz", tab2, (p - start) + p->op) ;
          p++ ;
          break ;

       case _LJNZ:
          fprintf(fp, jfmt, "ljnz", tab2+1 , (p - start) + p->op) ;
          p++ ;
          break ;

       case SET_ALOOP:
          fprintf(fp, "set_al\t%03d\n", p + p->op - start) ;
          p++ ;
          break ;

       case ALOOP:
          fprintf(fp, "aloop\t%03d\n", p - start + p->op) ;
          p++ ;
          break ;

       case  A_CAT :
          fprintf(fp,"a_cat\t%d\n", p++->op) ;
          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 ;
      }
   }
   fflush(fp) ;
}

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 = ZMALLOC(struct fdump) ;
   p->fbp = fbp ;
   p->link = fdump_list ;  fdump_list = p ;
}

void
fdump()
{
   register struct fdump *p, *q = fdump_list ;

   while (q)
   {
      p = q ;
      q = p->link ;
      fprintf(stdout, "function %s\n", p->fbp->name) ;
      da(p->fbp->code, stdout) ;
      ZFREE(p) ;
   }
}


Generated by  Doxygen 1.6.0   Back to index