Beispiel #1
0
Perl_yyparse (pTHX_ int gramtype)
#endif
{
    dVAR;
    int yystate;
    int yyn;
    int yyresult;

    /* Lookahead token as an internal (translated) token number.  */
    int yytoken = 0;

    yy_parser *parser;	    /* the parser object */
    yy_stack_frame  *ps;   /* current parser stack frame */

#define YYPOPSTACK   parser->ps = --ps
#define YYPUSHSTACK  parser->ps = ++ps

    /* The variable used to return semantic value and location from the
      action routines: ie $$.  */
    YYSTYPE yyval;

#ifndef PERL_IN_MADLY_C
#  ifdef PERL_MAD
    if (PL_madskills)
        return madparse(gramtype);
#  endif
#endif

    YYDPRINTF ((Perl_debug_log, "Starting parse\n"));

    parser = PL_parser;

    ENTER;  /* force parser state cleanup/restoration before we return */
    SAVEPPTR(parser->yylval.pval);
    SAVEINT(parser->yychar);
    SAVEINT(parser->yyerrstatus);
    SAVEINT(parser->stack_size);
    SAVEINT(parser->yylen);
    SAVEVPTR(parser->stack);
    SAVEVPTR(parser->ps);

    /* initialise state for this parse */
    parser->yychar = gramtype;
    parser->yyerrstatus = 0;
    parser->stack_size = YYINITDEPTH;
    parser->yylen = 0;
    Newx(parser->stack, YYINITDEPTH, yy_stack_frame);
    ps = parser->ps = parser->stack;
    ps->state = 0;
    SAVEDESTRUCTOR_X(S_clear_yystack, parser);

    /*------------------------------------------------------------.
    | yynewstate -- Push a new state, which is found in yystate.  |
    `------------------------------------------------------------*/
yynewstate:

    yystate = ps->state;

    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));

    parser->yylen = 0;

    {
        size_t size = ps - parser->stack + 1;

        /* grow the stack? We always leave 1 spare slot,
         * in case of a '' -> 'foo' reduction */

        if (size >= (size_t)parser->stack_size - 1) {
            /* this will croak on insufficient memory */
            parser->stack_size *= 2;
            Renew(parser->stack, parser->stack_size, yy_stack_frame);
            ps = parser->ps = parser->stack + size -1;

            YYDPRINTF((Perl_debug_log,
                       "parser stack size increased to %lu frames\n",
                       (unsigned long int)parser->stack_size));
        }
    }

    /* Do appropriate processing given the current state.  */
    /* Read a lookahead token if we need one and don't already have one.  */

    /* First try to decide what to do without reference to lookahead token.  */

    yyn = yypact[yystate];
    if (yyn == YYPACT_NINF)
        goto yydefault;

    /* Not known => get a lookahead token if don't already have one.  */

    /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
    if (parser->yychar == YYEMPTY) {
        YYDPRINTF ((Perl_debug_log, "Reading a token: "));
#ifdef PERL_IN_MADLY_C
        parser->yychar = PL_madskills ? madlex() : yylex();
#else
        parser->yychar = yylex();
#endif

#  ifdef EBCDIC
        if (parser->yychar >= 0 && parser->yychar < 255) {
            parser->yychar = NATIVE_TO_ASCII(parser->yychar);
        }
#  endif
    }

    if (parser->yychar <= YYEOF) {
        parser->yychar = yytoken = YYEOF;
        YYDPRINTF ((Perl_debug_log, "Now at end of input.\n"));
    }
    else {
        yytoken = YYTRANSLATE (parser->yychar);
        YYDSYMPRINTF ("Next token is", yytoken, &parser->yylval);
    }

    /* If the proper action on seeing token YYTOKEN is to reduce or to
      detect an error, take that action.  */
    yyn += yytoken;
    if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
        goto yydefault;
    yyn = yytable[yyn];
    if (yyn <= 0) {
        if (yyn == 0 || yyn == YYTABLE_NINF)
            goto yyerrlab;
        yyn = -yyn;
        goto yyreduce;
    }

    if (yyn == YYFINAL)
        YYACCEPT;

    /* Shift the lookahead token.  */
    YYDPRINTF ((Perl_debug_log, "Shifting token %s, ", yytname[yytoken]));

    /* Discard the token being shifted unless it is eof.  */
    if (parser->yychar != YYEOF)
        parser->yychar = YYEMPTY;

    YYPUSHSTACK;
    ps->state   = yyn;
    ps->val     = parser->yylval;
    ps->compcv  = (CV*)SvREFCNT_inc(PL_compcv);
    ps->savestack_ix = PL_savestack_ix;
#ifdef DEBUGGING
    ps->name    = (const char *)(yytname[yytoken]);
#endif

    /* Count tokens shifted since error; after three, turn off error
      status.  */
    if (parser->yyerrstatus)
        parser->yyerrstatus--;

    goto yynewstate;


    /*-----------------------------------------------------------.
    | yydefault -- do the default action for the current state.  |
    `-----------------------------------------------------------*/
yydefault:
    yyn = yydefact[yystate];
    if (yyn == 0)
        goto yyerrlab;
    goto yyreduce;


    /*-----------------------------.
    | yyreduce -- Do a reduction.  |
    `-----------------------------*/
yyreduce:
    /* yyn is the number of a rule to reduce with.  */
    parser->yylen = yyr2[yyn];

    /* If YYLEN is nonzero, implement the default value of the action:
      "$$ = $1".

      Otherwise, the following line sets YYVAL to garbage.
      This behavior is undocumented and Bison
      users should not rely upon it.  Assigning to YYVAL
      unconditionally makes the parser a bit smaller, and it avoids a
      GCC warning that YYVAL may be used uninitialized.  */
    yyval = ps[1-parser->yylen].val;

    YY_STACK_PRINT(parser);
    YY_REDUCE_PRINT (yyn);

    switch (yyn) {


#define dep() deprecate("\"do\" to call subroutines")

#ifdef PERL_IN_MADLY_C
#  define IVAL(i) (i)->tk_lval.ival
#  define PVAL(p) (p)->tk_lval.pval
#  define TOKEN_GETMAD(a,b,c) token_getmad((a),(b),(c))
#  define TOKEN_FREE(a) token_free(a)
#  define OP_GETMAD(a,b,c) op_getmad((a),(b),(c))
#  define IF_MAD(a,b) (a)
#  define DO_MAD(a) a
#  define MAD
#else
#  define IVAL(i) (i)
#  define PVAL(p) (p)
#  define TOKEN_GETMAD(a,b,c)
#  define TOKEN_FREE(a)
#  define OP_GETMAD(a,b,c)
#  define IF_MAD(a,b) (b)
#  define DO_MAD(a)
#  undef MAD
#endif

        /* contains all the rule actions; auto-generated from perly.y */
#include "perly.act"

    }

    {
        int i;
        for (i=0; i< parser->yylen; i++) {
            SvREFCNT_dec(ps[-i].compcv);
        }
    }

    parser->ps = ps -= (parser->yylen-1);

    /* Now shift the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */

    ps->val     = yyval;
    ps->compcv  = (CV*)SvREFCNT_inc(PL_compcv);
    ps->savestack_ix = PL_savestack_ix;
#ifdef DEBUGGING
    ps->name    = (const char *)(yytname [yyr1[yyn]]);
#endif

    yyn = yyr1[yyn];

    yystate = yypgoto[yyn - YYNTOKENS] + ps[-1].state;
    if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == ps[-1].state)
        yystate = yytable[yystate];
    else
        yystate = yydefgoto[yyn - YYNTOKENS];
    ps->state = yystate;

    goto yynewstate;


    /*------------------------------------.
    | yyerrlab -- here on detecting error |
    `------------------------------------*/
yyerrlab:
    /* If not already recovering from an error, report this error.  */
    if (!parser->yyerrstatus) {
        yyerror ("syntax error");
    }


    if (parser->yyerrstatus == 3) {
        /* If just tried and failed to reuse lookahead token after an
              error, discard it.  */

        /* Return failure if at end of input.  */
        if (parser->yychar == YYEOF) {
            /* Pop the error token.  */
            SvREFCNT_dec(ps->compcv);
            YYPOPSTACK;
            /* Pop the rest of the stack.  */
            while (ps > parser->stack) {
                YYDSYMPRINTF ("Error: popping", yystos[ps->state], &ps->val);
                LEAVE_SCOPE(ps->savestack_ix);
                if (yy_type_tab[yystos[ps->state]] == toketype_opval
                        && ps->val.opval)
                {
                    YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
                    if (ps->compcv != PL_compcv) {
                        PL_compcv = ps->compcv;
                        PAD_SET_CUR_NOSAVE(CvPADLIST(PL_compcv), 1);
                    }
                    op_free(ps->val.opval);
                }
                SvREFCNT_dec(ps->compcv);
                YYPOPSTACK;
            }
            YYABORT;
        }

        YYDSYMPRINTF ("Error: discarding", yytoken, &parser->yylval);
        parser->yychar = YYEMPTY;

    }

    /* Else will try to reuse lookahead token after shifting the error
      token.  */
    goto yyerrlab1;


    /*----------------------------------------------------.
    | yyerrlab1 -- error raised explicitly by an action.  |
    `----------------------------------------------------*/
yyerrlab1:
    parser->yyerrstatus = 3;	/* Each real token shifted decrements this.  */

    for (;;) {
        yyn = yypact[yystate];
        if (yyn != YYPACT_NINF) {
            yyn += YYTERROR;
            if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) {
                yyn = yytable[yyn];
                if (0 < yyn)
                    break;
            }
        }

        /* Pop the current state because it cannot handle the error token.  */
        if (ps == parser->stack)
            YYABORT;

        YYDSYMPRINTF ("Error: popping", yystos[ps->state], &ps->val);
        LEAVE_SCOPE(ps->savestack_ix);
        if (yy_type_tab[yystos[ps->state]] == toketype_opval && ps->val.opval) {
            YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
            if (ps->compcv != PL_compcv) {
                PL_compcv = ps->compcv;
                PAD_SET_CUR_NOSAVE(CvPADLIST(PL_compcv), 1);
            }
            op_free(ps->val.opval);
        }
        SvREFCNT_dec(ps->compcv);
        YYPOPSTACK;
        yystate = ps->state;

        YY_STACK_PRINT(parser);
    }

    if (yyn == YYFINAL)
        YYACCEPT;

    YYDPRINTF ((Perl_debug_log, "Shifting error token, "));

    YYPUSHSTACK;
    ps->state   = yyn;
    ps->val     = parser->yylval;
    ps->compcv  = (CV*)SvREFCNT_inc(PL_compcv);
    ps->savestack_ix = PL_savestack_ix;
#ifdef DEBUGGING
    ps->name    ="<err>";
#endif

    goto yynewstate;


    /*-------------------------------------.
    | yyacceptlab -- YYACCEPT comes here.  |
    `-------------------------------------*/
yyacceptlab:
    yyresult = 0;
    for (ps=parser->ps; ps > parser->stack; ps--) {
        SvREFCNT_dec(ps->compcv);
    }
    parser->ps = parser->stack; /* disable cleanup */
    goto yyreturn;

    /*-----------------------------------.
    | yyabortlab -- YYABORT comes here.  |
    `-----------------------------------*/
yyabortlab:
    yyresult = 1;
    goto yyreturn;

yyreturn:
    LEAVE;	/* force parser stack cleanup before we return */
    return yyresult;
}
Beispiel #2
0
START_MY_CXT
 
#define fdebug          (MY_CXT.x_fdebug)
#define current_idx     (MY_CXT.x_current_idx)


static I32
filter_call(pTHX_ int idx, SV *buf_sv, int maxlen)
{
    dMY_CXT;
    SV   *my_sv = FILTER_DATA(idx);
    char *nl = "\n";
    char *p;
    char *out_ptr;
    int n;

    if (fdebug)
	warn("**** In filter_call - maxlen = %d, out len buf = %d idx = %d my_sv = %d [%s]\n", 
		maxlen, SvCUR(buf_sv), idx, SvCUR(my_sv), SvPVX(my_sv) ) ;

    while (1) {

	/* anything left from last time */
	if ((n = SvCUR(my_sv))) {

	    out_ptr = SvPVX(my_sv) + BUF_OFFSET(my_sv) ;

	    if (maxlen) { 
		/* want a block */ 
		if (fdebug)
		    warn("BLOCK(%d): size = %d, maxlen = %d\n", 
			idx, n, maxlen) ;

	        sv_catpvn(buf_sv, out_ptr, maxlen > n ? n : maxlen );
		if(n <= maxlen) {
		    BUF_OFFSET(my_sv) = 0 ;
	            SET_LEN(my_sv, 0) ;
		}
		else {
		    BUF_OFFSET(my_sv) += maxlen ;
	            SvCUR_set(my_sv, n - maxlen) ;
		}
	        return SvCUR(buf_sv);
	    }
	    else {
		/* want lines */
                if ((p = ninstr(out_ptr, out_ptr + n, nl, nl + 1))) {

	            sv_catpvn(buf_sv, out_ptr, p - out_ptr + 1);

	            n = n - (p - out_ptr + 1);
		    BUF_OFFSET(my_sv) += (p - out_ptr + 1);
	            SvCUR_set(my_sv, n) ;
	            if (fdebug)
		        warn("recycle %d - leaving %d, returning %d [%s]", 
				idx, n, SvCUR(buf_sv), SvPVX(buf_sv)) ;

	            return SvCUR(buf_sv);
	        }
	        else /* no EOL, so append the complete buffer */
	            sv_catpvn(buf_sv, out_ptr, n) ;
	    }
	    
	}


	SET_LEN(my_sv, 0) ;
	BUF_OFFSET(my_sv) = 0 ;

	if (FILTER_ACTIVE(my_sv))
	{
    	    dSP ;
    	    int count ;

            if (fdebug)
		warn("gonna call %s::filter\n", PERL_MODULE(my_sv)) ;

    	    ENTER ;
    	    SAVETMPS;
	
	    SAVEINT(current_idx) ; 	/* save current idx */
	    current_idx = idx ;

	    SAVESPTR(DEFSV) ;	/* save $_ */
	    /* make $_ use our buffer */
	    DEFSV = sv_2mortal(newSVpv("", 0)) ; 

    	    PUSHMARK(sp) ;

	    if (CODE_REF(my_sv)) {
	    /* if (SvROK(PERL_OBJECT(my_sv)) && SvTYPE(SvRV(PERL_OBJECT(my_sv))) == SVt_PVCV) { */
    	        count = perl_call_sv((SV*)PERL_OBJECT(my_sv), G_SCALAR);
	    }
	    else {
                XPUSHs((SV*)PERL_OBJECT(my_sv)) ;  
	
    	        PUTBACK ;

    	        count = perl_call_method("filter", G_SCALAR);
	    }

    	    SPAGAIN ;

            if (count != 1)
	        croak("Filter::Util::Call - %s::filter returned %d values, 1 was expected \n", 
			PERL_MODULE(my_sv), count ) ;
    
	    n = POPi ;

	    if (fdebug)
	        warn("status = %d, length op buf = %d [%s]\n",
		     n, SvCUR(DEFSV), SvPVX(DEFSV) ) ;
	    if (SvCUR(DEFSV))
	        sv_setpvn(my_sv, SvPVX(DEFSV), SvCUR(DEFSV)) ; 

    	    PUTBACK ;
    	    FREETMPS ;
    	    LEAVE ;
	}
	else
	    n = FILTER_READ(idx + 1, my_sv, maxlen) ;

 	if (n <= 0)
	{
	    /* Either EOF or an error */

	    if (fdebug) 
	        warn ("filter_read %d returned %d , returning %d\n", idx, n,
	            (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n);

	    /* PERL_MODULE(my_sv) ; */
	    /* PERL_OBJECT(my_sv) ; */
	    filter_del(filter_call); 

	    /* If error, return the code */
	    if (n < 0)
		return n ;

	    /* return what we have so far else signal eof */
	    return (SvCUR(buf_sv)>0) ? SvCUR(buf_sv) : n;
	}

    }
}
Beispiel #3
0
thStatus thExecuteCode(char *blockname,CODEPTR code, CODEPTR codelimit)
{
#ifdef PHILDEBUG
#ifdef NOTPOSIX
#warning Phil says NOTPOSIX!
#else
#warning Phil says not NOTPOSIX! i.e. POSIX!!
#endif
#ifdef POINTER64
#warning Phil says POINTER64!
#else
#warning Phil says not POINTER64!
#endif
#ifdef USEMEMCPY
#warning Phil says USEMEMCPY!
#else
#warning Phil says not USEMEMCPY!
#endif
#endif
  register CODEPTR pc;
  CODE rawopcode,opcode,ltype,rtype,lrtypes;
  DAINT nargs,result;
  register DAINT *sp;
  DAINT i,il,ir,*pi;
  DAFLOAT f,fl,fr,*pf;
  DADOUBLE d,dl,dr,*pd;
  DAINT index;

  sp = stack;
  pc = code;

  while(pc < codelimit){
/*    printf("PC=%x, Op code %x, Stack=%x, SP=%x\n",pc,*pc,stack,sp);*/
    rawopcode = *pc++;
    if(rawopcode >= OPLP){		/* New style */
      ltype = (rawopcode & OPLEFTTYPEMASK) >> 8;
      rtype = (rawopcode & OPRIGHTTYPEMASK) >> 4;
/*      lrtypes = opcode & OPLRTYPEMASK;*/
      opcode = rawopcode & OPCODEMASK;
      switch(opcode & OPGROUPMASK)
	{
	case OPPUSHGROUP:		/* Pushes */
	  switch(opcode)
	    {
#ifdef USEMEMCPY
	      void *tmpptr;
#endif
	    case OPPUSHINT:	/* Float included in pushes */
	      if((rawopcode & OPRESTYPEMASK) == OPRDOUBLE){
/*		printf("sp=%x, pc=%x\n",sp,pc);*/
#ifdef USEMEMCPY
		memcpy((void *)&d,((DADOUBLE *)pc)++,sizeof(DADOUBLE));
		PUSHDOUBLE(d);
#else
#ifdef __sgi
		PUSHDOUBLE(*((DADOUBLE *)pc)); pc++; pc++;
#else
		PUSHDOUBLE(*(DADOUBLE *)pc);/*phil*/
                pc = (CODEPTR) (DADOUBLE *) ((DADOUBLE *)pc + 1);
#endif
#endif
/*		printf("sp=%x, pc=%x\n",sp,pc);*/
	      } else {
		PUSHINT(*pc++);
	      }
	      break;
	    case OPPUSHPINT:	/*Push a pointer*/
#ifdef USEMEMCPY
	      PUSHPOINTER((memcpy(&tmpptr,(((DAINT **)pc)++),sizeof(void *))
			  ,tmpptr));
#else
              PUSHPOINTER(*(DAINT **)pc); /*phil*/
              pc = (CODEPTR)(DAINT **) ((DAINT **)pc + 1);
#endif
	      break;
	    case OPPUSHINTP:    /*Push what a pointer points to */
	      if((rawopcode & OPRESTYPEMASK) == OPRDOUBLE){
#ifdef USEMEMCPY
		memcpy(&tmpptr,(((DAINT **)pc)++),sizeof(void *));
		d = *(DADOUBLE *) tmpptr;
#else
		d = **(DADOUBLE **)pc;/*phil*/
                pc = (CODEPTR) (DADOUBLE **) ((DADOUBLE **)pc + 1);
#endif	      
		PUSHDOUBLE(d);/*phil*/
	      } else {
#ifdef USEMEMCPY
		memcpy(&tmpptr,(((DAINT **)pc)++),sizeof(void *));
		PUSHINT(*(DAINT *) tmpptr);
#else		
		PUSHINT(**(DAINT **)pc);/*phil*/
                pc = (CODEPTR) (DAINT **) ((DAINT **)pc + 1);
#endif
	      }
	      break;
	    case OPPUSHFUNCTION:	/*Push a intrinsic function code */
	      PUSHINT(*pc++);
	      break;
	    }
	  break;
	case OPEOLGROUP:
	  sp--;		/* Should empty the stack */
	  if(rtype == OPRDOUBLE) sp--; /* Double is two entries on stack */
	  break;
	case OPLINDEXGROUP:
	  if(opcode==OPLFARG) {
	    if(rtype==OPRINT) {POPINT(i);}
	    else if(rtype==OPRFLOAT) {POPFLOAT(f);}/*phil*/
	    else {POPDOUBLE(d);}/*phil*/
	    POPINT(index);	/* Pop the function code */
	    switch(index)
	      {
	      case 0:		/* abs */
		if(rtype==OPRINT) {
		  if(i<0) i = -i;
		  PUSHINT(i);
		} else if(rtype==OPRFLOAT) {
		  if(f<0.0) f = -f;
		  PUSHFLOAT(f);/*phil*/
		} else {
		  if(d<0.0) d = -d;
		  PUSHDOUBLE(d);/*phil*/
		}
		break;
	      case 1:		/* sqrt */
		if(rtype==OPRINT) d = i;
		else if(rtype==OPRFLOAT) d = f;
		if(d>=0) d = sqrt(d);
		else {
		  fprintf(STDERR,"Test block %s: sqrt(%f)\n",blockname,d);
		  d = 0;
		}
		PUSHDOUBLE(d);/*phil*/
		break;
	      case 2:		/* exp */
		if(rtype==OPRINT) d = i;
		else if(rtype==OPRFLOAT) d = f;
		d = exp(d);
		PUSHDOUBLE(d);/*phil*/
		break;
	      case 3:		/* sin */
		if(rtype==OPRINT) d = i;
		else if(rtype==OPRFLOAT) d = f;
		d = sin(d);
		PUSHDOUBLE(d);/*phil*/
		break;
	      case 4:		/* cos */
		if(rtype==OPRINT) d = i;
		else if(rtype==OPRFLOAT) d = f;
		d = cos(d);
		PUSHDOUBLE(d);/*phil*/
		break;
	      case 5:		/* tan */
		if(rtype==OPRINT) d = i;
		else if(rtype==OPRFLOAT) d = f;
		d = tan(d);
		PUSHDOUBLE(d);/*phil*/
		break;
	      }
	    break;
	  }
	  if(rtype==OPRFLOAT) {	/* Floating point index */
	    POPFLOAT(f);/*phil*/
	    index = floatToLong(f);
	  } else if(rtype==OPRDOUBLE) {	/* Double */
	    POPDOUBLE(d);/*phil*/
	    index = floatToLong(d);
	  } else {
	    POPINT(index);
	  }
	  index -= ((opcode & 0xF000) == 0x1000 ? 0 : 1);
	  /* ltype should always be == restype */
	  if(opcode == OPLINDEX || opcode == OPLINDEXB){
	    if(ltype == OPRDOUBLE) {
	      FETCHDARRAY(d);/*phil*/
	      PUSHDOUBLE(d);/*phil*/
	    } else if (ltype == OPRFLOAT) {
              FETCHFARRAY(f);/*phil*/
              PUSHFLOAT(f);/*phil*/
	    } else {
              FETCHIARRAY(i);/*phil*/
	      PUSHINT(i);
	    }
	  } else { /*pointer on stack*/
	    sp--;
#ifdef POINTER64
	    sp--;
#endif
	    if(ltype == OPRDOUBLE) {
	      /*	      *((DADOUBLE **)sp)++ =  (*((DADOUBLE **)sp)+index);*/
	      /* The following works better on the alpha */
	      pd = *((DADOUBLE **)sp);
	      pd += index;
	      PUSHPOINTER(pd);/*phil*/
	    } else {		/* Assume INT and FLOAT the same size */
	      /**((DAINT **)sp)++ =  (*((DAINT **)sp)+index);*/
	      /* The following works better on the alpha */
	      pi = *((DAINT **)sp);
	      pi += index;
	      PUSHPOINTER(pi);/*phil*/
	    }
	  }
	  break;
	case OPEQUAL:		/* Big ugly matrix of type conversions */
	  if(rtype==OPRINT) {
	    POPINT(i);
	    if(ltype==OPRINT) {
	      SAVEINT(i); /* Save result in result variable *//*phil*/
	      PUSHINT(i);	/* Put result back on stack */
	    } else if(ltype==OPRFLOAT) {
	      f = i;	/* Convert to floating */
	      SAVEFLOAT(f); /* Save variable *//*phil*/
	      PUSHFLOAT(f); /* Put back on stack *//*phil*/
	    } else {		/* if(ltype==OPRDOUBLE) */
	      d = i;
	      SAVEDOUBLE(d);/*phil*/
	      PUSHDOUBLE(d);/*phil*/
	    }
	  } else if(rtype==OPRFLOAT) {
	    POPFLOAT(f);/*phil*/
	    if(ltype==OPRINT) {
	      i = floatToLong(f);
	      SAVEINT(i); /* Save result in result variable *//*phil*/
	      *sp++ = i;
	    } else if(ltype==OPRFLOAT) {
	      SAVEFLOAT(f); /* Save variable *//*phil*/
	      *sp++ = *(DAINT *)&f;
	    } else {		/* if(ltype==OPRDOUBLE) */
	      d = f;
	      SAVEDOUBLE(d);/*phil*/
	      PUSHDOUBLE(d);/*phil*/
	    }
	  } else {		/* if(rtype==OPRDOUBLE) */
	    POPDOUBLE(d);/*phil*/
	    if(ltype==OPRINT) {
	      i = floatToLong(d);
	      SAVEINT(i); /* Save result in result variable *//*phil*/
	      *sp++ = i;
	    } else if(ltype==OPRFLOAT) {
	      f = d;
	      SAVEFLOAT(f); /* Save variable *//*phil*/
	      *sp++ = *(DAINT *)&f;
	    } else {		/* if(ltype==OPRDOUBLE) */
 	      SAVEDOUBLE(d);/*phil*/
	      PUSHDOUBLE(d);/*phil*/
	    }
	  }
	  break;
	case OPLOGGROUP:		/* Logic and Bit operations */
	case OPSHIFTGROUP:		/* Logic and Bit operations */
	  if(rtype==OPRINT) {
	    POPINT(ir);
	  } else if(rtype==OPRFLOAT) {
	    POPFLOAT(f);/*phil*/
	    ir = floatToLong(f);
	  } else {
	    POPDOUBLE(d);/*phil*/
	    ir = floatToLong(d);
	  }
	  if(ltype==OPRINT) {
	    POPINT(il);
	  } else if(ltype==OPRFLOAT) {
	    POPFLOAT(f);/*phil*/
	    il = floatToLong(f);
	  } else {
	    POPDOUBLE(d);/*phil*/
	    il = floatToLong(d);
	  }
	  switch(opcode)
	    {
	    case OPLOGOR:
	      *sp++ = il || ir;
	      break;
	    case OPLOGXOR:
	      *sp++ = (il != 0) ^ (ir != 0);
	      break;
	    case OPLOGAND:
	      *sp++ = il && ir;
	      break;
	    case OPBITOR:
	      *sp++ = il | ir;
	      break;
	    case OPBITXOR:
	      *sp++ = il ^ ir;
	      break;
	    case OPBITAND:
	      *sp++ = il & ir;
	      break;
	    case OPSHL:
	      *sp++ = il << ir;
	      break;
	    case OPSHR:
	      *sp++ = il >> ir;
	      break;
	    }
	  break;
	case OPCOMPGROUP:		/* Logic comparisons */
/* Result of Add amd MUL groups should now always be double */
	case OPADDGROUP:	/* Add and Subtract */
	case OPMULGROUP:	/* * / and % */
	  if(rtype==OPRINT) {
	    POPINT(ir);
	    dr = ir;
	  } else if (rtype==OPRFLOAT) {
	    POPFLOAT(fr);/*phil*/
	    dr = fr;
	  } else {
	    POPDOUBLE(dr);/*phil*/
	  }
	  if(ltype==OPRINT) {
	    POPINT(il);
	    dl = il;
	  } else if (ltype==OPRFLOAT) {
	    POPFLOAT(fl);/*phil*/
	    dl = fl;
	  } else {
	    POPDOUBLE(dl);/*phil*/
	  }
	  if(rtype!=OPRINT || ltype!=OPRINT){
	    switch(opcode)
	      {
	      case OPISEQUAL:
		*sp++ = dl == dr;
		break;
	      case OPISNOTEQUAL:
		*sp++ = dl != dr;
		break;
	      case OPISLT:
		*sp++ = dl < dr;
		break;
	      case OPISGT:
		*sp++ = dl > dr;
		break;
	      case OPISLE:
		*sp++ = dl <= dr;
		break;
	      case OPISGE:
		*sp++ = dl >= dr;
		break;
	      case OPADD:
		d = dl + dr;
		PUSHDOUBLE(d);/*phil*/
		break;
	      case OPSUB:
		d = dl - dr;
		PUSHDOUBLE(d);/*phil*/
		break;
	      case OPTIMES:
		d = dl * dr;	/* Need to deal with overflow */
		PUSHDOUBLE(d);/*phil*/
		break;
	      case OPIDIV:
/*		printf("OP=%x\n",rawopcode);*/
		if(dr == 0.0) {
		  fprintf(STDERR,"Test block %s: %f/0.0\n",blockname,dl);
		  d = 0.0;
		} else {
		  d = dl / dr;	/* Need to deal with overflow and div 0 */
		}
		*sp++ = floatToLong(d);
		break;
	      case OPDIV:
		if(dr == 0.0) {
		  fprintf(STDERR,"Test block %s: %f/0.0\n",blockname,dl);
		  d = 0.0;
		} else {
		  d = dl / dr;	/* Need to deal with overflow and div 0 */
		}
		PUSHDOUBLE(d);/*phil*/
		break;
	      case OPMOD:
		d = fmod(dl,dr);
		PUSHDOUBLE(d);/*phil*/
		break;
	      }
	  } else {		/* Both left and right are int */
	    switch(opcode)
	      {
	      case OPISEQUAL:
		*sp++ = il == ir;
		break;
	      case OPISNOTEQUAL:
		*sp++ = il != ir;
		break;
	      case OPISLT:
		*sp++ = il < ir;
		break;
	      case OPISGT:
		*sp++ = il > ir;
		break;
	      case OPISLE:
		*sp++ = il <= ir;
		break;
	      case OPISGE:
		*sp++ = il >= ir;
		break;
	      case OPADD:
		*sp++ = il + ir;
		break;
	      case OPSUB:
		*sp++ = il - ir;
		break;
	      case OPTIMES:
		*sp++ = il * ir; /* Need to deal with overflow */
		break;
	      case OPIDIV:
/*		printf("At OPIDIV all int branch\n");*/
		if(ir == 0) {
		  fprintf(STDERR,"Test block %s: %d/0.0\n",blockname,il);
		  *sp++ = 0;
		} else {
		  *sp++ = il / ir;
		}
		break;
	      case OPDIV:
		if(ir == 0) {
		  fprintf(STDERR,"Test block %s: %d/0.0\n",blockname,il);
		  d = 0.0;
		} else
		  d = dl / dr; /* Need to deal with overflow and div 0 */
		PUSHDOUBLE(d);/*phil*/
		break;
	      case OPMOD:
		*sp++ = il % ir; /* Need to deal with overflow and div 0 */
		break;
	      }
	  }
	  break;
	case OPUNARY:		/* Unary Operators */
	  switch(opcode)
	    {
	    case OPNEG:
	      if(rtype==OPRINT) {
		i = -(*--sp);
	        *sp++ = i;
	      } else if (rtype==OPRFLOAT) {
		f = *(DAFLOAT *)(--sp);
		f = -f;
		*sp++ = *(DAINT *)&f;
	      } else {
		POPDOUBLE(d);/*phil*/
		d = -d;
		PUSHDOUBLE(d);/*phil*/
	      }
	      break;
	    case OPNOT:
	    case OPCOMP:
	      if(rtype==OPRINT) {
		POPINT(i);
	      } else if(rtype==OPRFLOAT) {
		POPFLOAT(f);/*phil*/
		i = floatToLong(f);
	      } else {
		POPDOUBLE(d);/*phil*/
		i = floatToLong(d);
	      }
	      i = (opcode == OPNOT ? !i : ~i);
	      *sp++ = i;
	      break;
	    }
	  break;
	default:
	  fprintf(STDERR,"Test block %s: Operator %x not yet implimented\n",
		  blockname,opcode);
	  break;
	} /* Terminates switch */
    } else {	/* terminates if(rawopcode >=OPLP) *//* Old Style, May not work anymore */
      switch(*pc++)