home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BURKS 2
/
BURKS_AUG97.ISO
/
BURKS
/
SOFTWARE
/
SOURCES
/
MAWK11AS.ZIP
/
EXECUTE.C
(
.txt
)
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-18
|
33KB
|
1,181 lines
/********************************************
execute.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: execute.c,v $
* Revision 5.1 91/12/05 07:55:50 brennan
* 1.1 pre-release
*
*/
#include "mawk.h"
#include "code.h"
#include "memory.h"
#include "symtype.h"
#include "field.h"
#include "bi_funct.h"
#include "bi_vars.h"
#include "regexp.h"
#include "repl.h"
#include "fin.h"
#include <math.h>
/* static functions */
static int PROTO( compare, (CELL *) ) ;
static void PROTO( eval_overflow, (void) ) ;
#if NOINFO_SIGFPE
static char dz_msg[] = "division by zero" ;
#endif
#ifdef DEBUG
#define inc_sp() if( ++sp == eval_stack+EVAL_STACK_SIZE )\
eval_overflow()
#else
/* If things are working, the eval stack should not overflow */
#define inc_sp() sp++
#endif
#define SAFETY 16
#define DANGER (EVAL_STACK_SIZE-SAFETY)
/* The stack machine that executes the code */
CELL eval_stack[EVAL_STACK_SIZE] ;
/* these can move for deep recursion */
static CELL *stack_base = eval_stack ;
static CELL *stack_danger = eval_stack + DANGER ;
#ifdef DEBUG
static void eval_overflow()
{ overflow("eval stack" , EVAL_STACK_SIZE) ; mawk_exit(1) ; }
#endif
static INST *restart_label ; /* control flow labels */
INST *next_label ;
static CELL tc ; /*useful temp */
void execute(cdp, sp, fp)
register INST *cdp ; /* code ptr, start execution here */
register CELL *sp ; /* eval_stack pointer */
CELL *fp ; /* frame ptr into eval_stack for
user defined functions */
{
/* some useful temporaries */
CELL *cp ;
int t ;
/* for moving the stack (deep recursion) */
CELL *old_stack_base ;
CELL *old_sp ;
#ifdef DEBUG
CELL *entry_sp = sp ;
#endif
if ( fp ) /* we are a function call, check for deep recursion */
{
if (sp > stack_danger)
{ /* change stacks */
old_stack_base = stack_base ;
old_sp = sp ;
stack_base = (CELL *) zmalloc(sizeof(CELL)*EVAL_STACK_SIZE) ;
stack_danger = stack_base + DANGER ;
sp = stack_base ;
/* waste 1 slot for ANSI, actually LM_DOS breaks in
RET if we don't */
#ifdef DEBUG
entry_sp = sp ;
#endif
}
else old_stack_base = (CELL*) 0 ;
}
while ( 1 )
switch( cdp++ -> op )
{
/* HALT only used by the disassemble now ; this remains
so compilers don't offset the jump table */
case _HALT :
case _STOP : /* only for range patterns */
#ifdef DEBUG
if ( sp != entry_sp+1 ) bozo("stop0") ;
#endif
return ;
case _PUSHC :
inc_sp() ;
(void) cellcpy(sp, cdp++ -> ptr) ;
break ;
case _PUSHD :
inc_sp() ;
sp->type = C_DOUBLE ;
sp->dval = *(double*) cdp++->ptr ;
break ;
case _PUSHS :
inc_sp() ;
sp->type = C_STRING ;
sp->ptr = cdp++->ptr ;
string(sp)->ref_cnt++ ;
break ;
case F_PUSHA :
if ( (CELL*)cdp->ptr != field && nf < 0 ) split_field0() ;
/* fall thru */
case _PUSHA :
case A_PUSHA :
inc_sp() ;
sp -> ptr = cdp++ -> ptr ;
break ;
case _PUSHI : /* put contents of next address on stack*/
inc_sp() ;
(void) cellcpy(sp, cdp++ -> ptr) ;
break ;
case L_PUSHI :
/* put the contents of a local var on stack,
cdp->op holds the offset from the frame pointer */
inc_sp() ;
(void) cellcpy(sp, fp + cdp++->op) ;
break ;
case L_PUSHA : /* put a local address on eval stack */
inc_sp() ;
sp->ptr = (PTR)(fp + cdp++->op) ;
break ;
case F_PUSHI :
/* push contents of $i
cdp[0] holds & $i , cdp[1] holds i */
inc_sp() ;
if ( nf < 0 ) split_field0() ;
cp = (CELL *) cdp->ptr ;
t = (cdp+1)->op ;
cdp += 2 ;
if ( t <= nf ) (void) cellcpy(sp, cp) ;
else /* an unset field */
{ sp->type = C_STRING ;
sp->ptr = (PTR) & null_str ;
null_str.ref_cnt++ ;
}
break ;
case NF_PUSHI :
inc_sp() ;
if ( nf < 0 ) split_field0() ;
(void) cellcpy(sp, NF) ;
break ;
case FE_PUSHA :
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
if ( (t = (int) sp->dval) < 0 )
rt_error( "negative field index $%d", t) ;
if ( t && nf < 0 ) split_field0() ;
sp->ptr = (PTR) field_ptr(t) ;
break ;
case FE_PUSHI :
if ( sp->type != C_DOUBLE ) cast1_to_d(sp) ;
if ( (t = (int) sp->dval) < 0 )
rt_error( "negative field index $%d", t) ;
if ( nf < 0) split_field0() ;
if ( t <= nf ) (void) cellcpy(sp, field_ptr(t)) ;
else
{ sp->type = C_STRING ;
sp->ptr = (PTR) & null_str ;
null_str.ref_cnt++ ;
}
break ;
case AE_PUSHA :
/* top of stack has an expr, cdp->ptr points at an
array, replace the expr with the cell address inside
the array */
cp = array_find((ARRAY)cdp++->ptr, sp, CREATE) ;
cell_destroy(sp) ;
sp->ptr = (PTR) cp ;
break ;
case AE_PUSHI :
/* top of stack has an expr, cdp->ptr points at an
array, replace the expr with the contents of the
cell inside the array */
cp = array_find((ARRAY) cdp++->ptr, sp, CREATE) ;
cell_destroy(sp) ;
(void) cellcpy(sp, cp) ;
break ;
case LAE_PUSHI :
/* sp[0] is an expression
cdp->op is offset from frame pointer of a CELL which
has an ARRAY in the ptr field, replace expr
with array[expr]
*/
cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp, CREATE) ;
cell_destroy(sp) ;
(void) cellcpy(sp, cp) ;
break ;
case LAE_PUSHA :
/* sp[0] is an expression
cdp->op is offset from frame pointer of a CELL which
has an ARRAY in the ptr field, replace expr
with & array[expr]
*/
cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp, CREATE) ;
cell_destroy(sp) ;
sp->ptr = (PTR) cp ;
break ;
case LA_PUSHA :
/* cdp->op is offset from frame pointer of a CELL which
has an ARRAY in the ptr field. Push this ARRAY
on the eval stack
*/
inc_sp() ;
sp->ptr = fp[cdp++->op].ptr ;
break ;
case SET_ALOOP :
{ ALOOP_STATE *ap = (ALOOP_STATE *)
(cdp + cdp->op + 2)->ptr ;
ap->var = (CELL *) sp[-1].ptr ;
ap->A = (ARRAY) sp->ptr ;
sp -= 2 ;
ap->index = -1 ;
if ( inc_aloop_state(ap) ) cdp++ ;
else cdp += cdp->op + 3 ;
}
break ;
case ALOOP :
if ( inc_aloop_state( (ALOOP_STATE*) cdp[1].ptr ) )
cdp += cdp->op ;
else cdp += 2 ;
break ;
case _POP :
cell_destroy(sp) ;
sp-- ;
break ;
case _DUP :
(void) cellcpy(sp+1, sp) ;
sp++ ; break