home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 11
/
AUCD11B.iso
/
LANGUAGES
/
WraithSet
/
AwkStuff
/
MawkSrc
/
c
/
da
< prev
next >
Wrap
Text File
|
1995-06-18
|
8KB
|
432 lines
/********************************************
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) ;
}
}