home *** CD-ROM | disk | FTP | other *** search
/ BURKS 2 / BURKS_AUG97.ISO / BURKS / SOFTWARE / SOURCES / MAWK11AS.ZIP / EXECUTE.C (.txt) < prev    next >
C/C++ Source or Header  |  1991-12-18  |  33KB  |  1,181 lines

  1.  
  2. /********************************************
  3. execute.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /* $Log:    execute.c,v $
  14.  * Revision 5.1  91/12/05  07:55:50  brennan
  15.  * 1.1 pre-release
  16.  * 
  17. */
  18.  
  19.  
  20. #include "mawk.h"
  21. #include "code.h"
  22. #include "memory.h"
  23. #include "symtype.h"
  24. #include "field.h"
  25. #include "bi_funct.h"
  26. #include "bi_vars.h"
  27. #include "regexp.h"
  28. #include "repl.h"
  29. #include "fin.h"
  30. #include <math.h>
  31.  
  32. /* static functions */
  33. static int PROTO( compare, (CELL *) ) ;
  34. static void PROTO( eval_overflow, (void) ) ;
  35.  
  36.  
  37. #if   NOINFO_SIGFPE
  38. static char dz_msg[] = "division by zero" ;
  39. #endif
  40.  
  41. #ifdef   DEBUG
  42. #define  inc_sp()   if( ++sp == eval_stack+EVAL_STACK_SIZE )\
  43.                          eval_overflow()
  44. #else
  45.  
  46. /* If things are working, the eval stack should not overflow */
  47.  
  48. #define inc_sp()    sp++
  49. #endif
  50.  
  51. #define  SAFETY    16
  52. #define  DANGER    (EVAL_STACK_SIZE-SAFETY)
  53.  
  54. /*  The stack machine that executes the code */
  55.  
  56. CELL  eval_stack[EVAL_STACK_SIZE] ;
  57. /* these can move for deep recursion */
  58. static CELL  *stack_base = eval_stack ;
  59. static CELL  *stack_danger = eval_stack + DANGER ;      
  60.  
  61. #ifdef  DEBUG
  62. static void eval_overflow()
  63. { overflow("eval stack" , EVAL_STACK_SIZE) ; mawk_exit(1) ; }
  64. #endif
  65.  
  66. static INST *restart_label ; /* control flow labels */
  67. INST *next_label ;
  68. static CELL tc ; /*useful temp */
  69.  
  70. void  execute(cdp, sp, fp)
  71.   register INST *cdp ;  /* code ptr, start execution here */
  72.   register CELL *sp ;   /* eval_stack pointer */
  73.   CELL *fp ;            /* frame ptr into eval_stack for
  74.                            user defined functions */
  75.   /* some useful temporaries */
  76.   CELL *cp ;
  77.   int t ;
  78.  
  79.   /* for moving the stack (deep recursion) */
  80.   CELL *old_stack_base ;
  81.   CELL *old_sp ;
  82.  
  83. #ifdef  DEBUG
  84.   CELL *entry_sp = sp ;
  85. #endif
  86.  
  87.  
  88.   if ( fp )  /* we are a function call, check for deep recursion */
  89.   {
  90.     if (sp > stack_danger)
  91.     { /* change stacks */
  92.       old_stack_base = stack_base ;
  93.       old_sp = sp ;
  94.       stack_base = (CELL *) zmalloc(sizeof(CELL)*EVAL_STACK_SIZE) ;
  95.       stack_danger = stack_base + DANGER ;
  96.       sp = stack_base ;
  97.       /* waste 1 slot for ANSI, actually LM_DOS breaks in
  98.          RET if we don't */
  99. #ifdef  DEBUG 
  100.       entry_sp = sp ;
  101. #endif
  102.     }
  103.     else old_stack_base = (CELL*) 0 ;
  104.   }
  105.  
  106.   while ( 1 )
  107.     switch( cdp++ -> op )
  108.     {   
  109.  
  110. /* HALT only used by the disassemble now ; this remains
  111.    so compilers don't offset the jump table */
  112.         case  _HALT :
  113.  
  114.         case  _STOP :  /* only for range patterns */
  115. #ifdef  DEBUG
  116.                 if ( sp != entry_sp+1 ) bozo("stop0") ;
  117. #endif
  118.                 return ;
  119.  
  120.         case  _PUSHC :  
  121.             inc_sp() ;
  122.             (void) cellcpy(sp, cdp++ -> ptr) ;
  123.             break ;
  124.  
  125.         case _PUSHD  :
  126.             inc_sp() ;
  127.             sp->type = C_DOUBLE ;
  128.             sp->dval = *(double*) cdp++->ptr ;
  129.             break ;
  130.  
  131.         case  _PUSHS :
  132.             inc_sp() ;
  133.             sp->type = C_STRING ;
  134.             sp->ptr = cdp++->ptr ;
  135.             string(sp)->ref_cnt++ ;
  136.             break ;
  137.  
  138.         case  F_PUSHA :
  139.             if ( (CELL*)cdp->ptr != field && nf < 0 ) split_field0() ;
  140.             /* fall thru */
  141.  
  142.         case  _PUSHA :
  143.         case  A_PUSHA :
  144.             inc_sp() ;
  145.             sp -> ptr = cdp++ -> ptr ;
  146.             break ;
  147.  
  148.         case _PUSHI :  /* put contents of next address on stack*/
  149.             inc_sp() ;
  150.             (void) cellcpy(sp, cdp++ -> ptr) ;
  151.             break ;
  152.             
  153.         case L_PUSHI :  
  154.             /* put the contents of a local var on stack,
  155.                cdp->op holds the offset from the frame pointer */
  156.             inc_sp() ;
  157.             (void) cellcpy(sp, fp + cdp++->op) ;
  158.             break ;
  159.  
  160.         case L_PUSHA : /* put a local address on eval stack */
  161.             inc_sp() ;
  162.             sp->ptr = (PTR)(fp + cdp++->op) ;
  163.             break ;
  164.  
  165.  
  166.         case F_PUSHI :
  167.  
  168.         /* push contents of $i 
  169.            cdp[0] holds & $i , cdp[1] holds i */
  170.  
  171.             inc_sp() ;
  172.             if ( nf < 0 )  split_field0() ;
  173.             cp = (CELL *) cdp->ptr ;
  174.             t =  (cdp+1)->op ;
  175.             cdp += 2 ;
  176.  
  177.             if ( t <= nf ) (void) cellcpy(sp, cp) ;
  178.             else  /* an unset field */
  179.             { sp->type = C_STRING ;
  180.               sp->ptr = (PTR) & null_str ;
  181.               null_str.ref_cnt++ ;
  182.             }
  183.             break ;
  184.  
  185.         case NF_PUSHI :
  186.  
  187.             inc_sp() ;
  188.             if ( nf < 0 ) split_field0() ;
  189.             (void) cellcpy(sp, NF) ;
  190.             break ;
  191.  
  192.         case  FE_PUSHA :
  193.             if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  194.             if ( (t = (int) sp->dval) < 0 )
  195.                 rt_error( "negative field index $%d", t) ;
  196.             if ( t && nf < 0 )  split_field0() ;
  197.             sp->ptr = (PTR) field_ptr(t) ;
  198.             break ;
  199.  
  200.         case  FE_PUSHI :
  201.             if ( sp->type != C_DOUBLE )  cast1_to_d(sp) ;
  202.  
  203.             if ( (t = (int) sp->dval) < 0 )
  204.                   rt_error( "negative field index $%d", t) ;
  205.  
  206.             if ( nf < 0)  split_field0() ;
  207.             if ( t <= nf ) (void) cellcpy(sp, field_ptr(t)) ;
  208.             else
  209.             { sp->type = C_STRING ;
  210.               sp->ptr = (PTR) & null_str ;
  211.               null_str.ref_cnt++ ;
  212.             }
  213.             break ; 
  214.  
  215.  
  216.         case  AE_PUSHA :
  217.         /* top of stack has an expr, cdp->ptr points at an
  218.            array, replace the expr with the cell address inside
  219.            the array */
  220.  
  221.             cp = array_find((ARRAY)cdp++->ptr, sp, CREATE) ;
  222.             cell_destroy(sp) ;
  223.             sp->ptr = (PTR) cp ;
  224.             break ;
  225.  
  226.         case  AE_PUSHI :
  227.         /* top of stack has an expr, cdp->ptr points at an
  228.            array, replace the expr with the contents of the
  229.            cell inside the array */
  230.  
  231.             cp = array_find((ARRAY) cdp++->ptr, sp, CREATE) ;
  232.             cell_destroy(sp) ;
  233.             (void) cellcpy(sp, cp) ;
  234.             break ;
  235.  
  236.         case  LAE_PUSHI :
  237.         /*  sp[0] is an expression
  238.             cdp->op is offset from frame pointer of a CELL which
  239.                has an ARRAY in the ptr field, replace expr
  240.             with  array[expr]
  241.         */
  242.             cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp, CREATE) ;
  243.             cell_destroy(sp) ;
  244.             (void) cellcpy(sp, cp) ;
  245.             break ;
  246.             
  247.         case  LAE_PUSHA :
  248.         /*  sp[0] is an expression
  249.             cdp->op is offset from frame pointer of a CELL which
  250.                has an ARRAY in the ptr field, replace expr
  251.             with  & array[expr]
  252.         */
  253.             cp = array_find( (ARRAY)fp[cdp++->op].ptr, sp, CREATE) ;
  254.             cell_destroy(sp) ;
  255.             sp->ptr = (PTR) cp ;
  256.             break ;
  257.             
  258.         case  LA_PUSHA  :
  259.         /*  cdp->op is offset from frame pointer of a CELL which
  260.                has an ARRAY in the ptr field. Push this ARRAY
  261.                on the eval stack
  262.         */
  263.             inc_sp() ;
  264.             sp->ptr = fp[cdp++->op].ptr ;
  265.             break ;
  266.  
  267.         case  SET_ALOOP :
  268.             { ALOOP_STATE *ap = (ALOOP_STATE *)
  269.                             (cdp + cdp->op + 2)->ptr ;
  270.  
  271.               ap->var = (CELL *) sp[-1].ptr ;
  272.               ap->A = (ARRAY) sp->ptr ;
  273.               sp -= 2 ;
  274.  
  275.           ap->index = -1 ;
  276.               if ( inc_aloop_state(ap) )  cdp++ ;
  277.           else  cdp += cdp->op + 3 ;
  278.         }
  279.         break ;
  280.  
  281.         case  ALOOP :
  282.  
  283.         if ( inc_aloop_state( (ALOOP_STATE*) cdp[1].ptr ) )
  284.             cdp += cdp->op ;
  285.         else    cdp += 2 ;
  286.         break ;
  287.  
  288.         case  _POP : 
  289.             cell_destroy(sp) ;
  290.             sp-- ;
  291.             break ;
  292.  
  293.         case _DUP  :
  294.             (void) cellcpy(sp+1, sp) ;
  295.             sp++ ; break