⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parserfp.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* */
/* PARSERFP.C  -- Part of FRACTINT fractal drawer. */
/* */
/*   By Chuck Ebbert  CompuServe [76306,1226] */
/*                     internet: 76306.1226@compuserve.com  */
/* */
/* Fast floating-point parser code.  The functions beginning with */
/*    "fStk" are in PARSERA.ASM.  PARSER.C calls this code after */
/*    it has parsed the formula. */
/* */
/*   Converts the function pointers/load pointers/store pointers */
/*       built by parsestr() into an optimized array of function */
/*       pointer/operand pointer pairs. */
/* */
/* ******************************************************************* */
/*                                                                     */
/*  Copyright (C) 1992, 1993 Chuck Ebbert.  All rights reserved.       */
/*                                                                     */
/*    This code may be freely distributed and used in non-commercial   */
/*    programs provided the author is credited either during program   */
/*    execution or in the documentation, and this copyright notice     */
/*    is left intact.  Sale of this code, or its use in any commercial */
/*    product requires permission from the author.  Nominal            */
/*    distribution and handling fees may be charged by shareware and   */
/*    freeware distributors.                                           */
/*                                                                     */
/*       Chuck Ebbert                                                  */
/*       1915 Blust Ln.                                                */
/*       Enola, PA  17025                                              */
/*                                                                     */
/* ******************************************************************* */
/* */
/* Revised 12 July 1993 (for v18.1) by CAE to fix optimizer bug  */
/* */
/* Revised 22 MAR 1993 (for Fractint v18.0)  */
/* */
/* Uncomment the next line to enable debug. */
/*      #define TESTFP 1  */
/* */

#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <time.h>
#include "mpmath.h"
#include "prototyp.h"

extern union Arg *Arg1, *Arg2;
/* Some of these variables should be renamed for safety */
extern union Arg s[20], far * far *Store, far * far *Load;
extern int StoPtr, LodPtr, OpPtr;
extern int debugflag;
extern unsigned vsp, LastOp;
extern struct ConstArg far *v;
extern int inside; 	    /* "inside" color to use    */
extern int outside;	    /* "outside" color to use   */
extern int potflag;	    /* potential enabled? */
extern char useinitorbit;
extern int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;
extern void (far * far *f)(void);

struct fls { /* function, load, store pointers  CAE fp */
   void (near *function)(void);
   union Arg near *operand;
} far *pfls = (struct fls far *)0;

void  StkLod(void);
void  StkClr(void);
void  dStkAdd(void);
void  dStkSub(void);
void  dStkMul(void);
void  dStkDiv(void);
void  StkSto(void);
void  dStkSqr(void);
void  EndInit(void);
void  dStkMod(void);
void  dStkLTE(void);
void  dStkSin(void);
void  dStkCos(void);
void  dStkSinh(void);
void  dStkCosh(void);
void  dStkCosXX(void);
void  dStkTan(void);
void  dStkTanh(void);
void  dStkCoTan(void);
void  dStkCoTanh(void);
void  dStkLog(void);
void  dStkExp(void);
void  dStkPwr(void);
void  dStkLT(void);
void  dStkFlip(void);
void  dStkReal(void);
void  dStkImag(void);
void  dStkConj(void);
void  dStkNeg(void);
void  dStkAbs(void);
void  dStkRecip(void);
void  StkIdent(void);
void  dStkGT(void);
void  dStkGTE(void);
void  dStkNE(void);
void  dStkEQ(void);
void  dStkAND(void);
void  dStkOR(void);

#define fgf(x) pfls[(x)].function
#define opp(x) pfls[(x)].operand
#define NO_OPERAND (void near *)0
#define LastSqr v[4].a
#define MAX_ARGS 100
#define MAX_STACK 8
#define TWO_FREE 6

#ifndef XFRACT

void (near fStkPull2 )(void); /* pull up fpu stack from 2 to 4 */
void (near fStkPush2 )(void); /* push down fpu stack from 8 to 6 */
void (near fStkPush2a )(void); /* push down fpu stack from 6 to 4 */
void (near fStkPush4 )(void); /* push down fpu stack from 8 to 4 */
void (near fStkLodDup )(void); /* lod, dup */
void (near fStkLodSqr )(void); /* lod, sqr, dont save magnitude */
void (near fStkLodSqr2 )(void); /* lod, sqr, save magnitude */
void (near fStkStoDup )(void); /* store, duplicate */
void (near fStkStoSqr )(void); /* store, sqr, save lastsqr */
void (near fStkStoSqr0 )(void); /* store, sqr, dont save lastsqr */
void (near fStkLodDbl )(void); /* load, double */
void (near fStkStoDbl )(void); /* store, double */
void (near fStkReal2 )(void); /* fast ver. of real */
void (near fStkSqr )(void); /* sqr, save magnitude in lastsqr */
void (near fStkSqr0 )(void); /* sqr, no save magnitude */
void (near fStkClr1 )(void); /* clear fpu */
void (near fStkClr2 )(void); /* test stack top, clear fpu */
void (near fStkStoClr1 )(void); /* store, clr1 */
void (near fStkAdd )(void);
void (near fStkSub )(void);
void (near fStkSto )(void);
void (near fStkSto2 )(void); /* fast ver. of sto */
void (near fStkLod )(void);
void (near fStkEndInit )(void);
void (near fStkMod )(void);
void (near fStkMod2 )(void);
void (near fStkLodMod2 )(void);
void (near fStkStoMod2 )(void);
void (near fStkLTE )(void);
void (near fStkLodLTEMul )(void);
void (near fStkLTE2 )(void);
void (near fStkLodLTE )(void);
void (near fStkLodLTE2 )(void);
void (near fStkLodLTEAnd2 )(void);
void (near fStkLT )(void);
void (near fStkLodLTMul )(void);
void (near fStkLT2 )(void);
void (near fStkLodLT )(void);
void (near fStkLodLT2 )(void);
void (near fStkGTE )(void);
void (near fStkLodGTE )(void);
void (near fStkLodGTE2 )(void);
void (near fStkGT )(void);
void (near fStkGT2 )(void);
void (near fStkLodGT )(void);
void (near fStkLodGT2 )(void);
void (near fStkEQ )(void);
void (near fStkLodEQ )(void);
void (near fStkNE )(void);
void (near fStkLodNE )(void);
void (near fStkAND )(void);
void (near fStkANDClr2 )(void);
void (near fStkOR )(void);
void (near fStkSin )(void);
void (near fStkSinh )(void);
void (near fStkCos )(void);
void (near fStkCosXX )(void);
void (near fStkCosh )(void);
void (near fStkTan )(void);
void (near fStkTanh )(void);
void (near fStkCoTan )(void);
void (near fStkCoTanh )(void);
void (near fStkLog )(void);
void (near fStkExp )(void);
void (near fStkPwr )(void);
void (near fStkMul )(void);
void (near fStkDiv )(void);
void (near fStkFlip )(void);
void (near fStkReal )(void);
void (near fStkImag )(void);
void (near fStkRealFlip )(void);
void (near fStkImagFlip )(void);
void (near fStkConj )(void);
void (near fStkNeg )(void);
void (near fStkAbs )(void);
void (near fStkRecip )(void);
void (near fStkLodReal )(void);
void (near fStkLodRealC )(void);
void (near fStkLodImag )(void);
void (near fStkLodRealFlip )(void);
void (near fStkLodRealAbs )(void);
void (near fStkLodRealMul )(void);
void (near fStkLodRealAdd )(void);
void (near fStkLodRealSub )(void);
void (near fStkLodImagFlip )(void);
void (near fStkLodImagAbs )(void);
void (near fStkLodConj )(void);
void (near fStkLodAdd )(void);
void (near fStkLodSub )(void);
void (near fStkLodSubMod )(void);
void (near fStkLodMul )(void);
void (near fStkPLodAdd )(void);
void (near fStkPLodSub )(void);
void (near Img_Setup )(void);


static void (near *prevfptr )(void);
static int stkcnt, prevstkcnt, cvtptrx, prevlodptr, lastsqrused;

static void CvtFptr(void (near * ffptr)(void), int MinStk, int MaxStk,
      int Delta )
/* (MinStk <= 4, MaxStk >= TWO_FREE) */
{
   char testconst = 0;

   if (stkcnt < MinStk ) { /* not enough operands on fpu stack */
#ifdef TESTFP
      stopmsg(0, "Inserted pull." );
#endif
      opp(cvtptrx) = NO_OPERAND;
      fgf(cvtptrx++) = fStkPull2;  /* so adjust the stack, pull operand */
      stkcnt += 2;
   }
   else if (stkcnt > MaxStk ) { /* too many operands */
#ifdef TESTFP
      stopmsg(0, "Inserted push." );
#endif
      opp(cvtptrx) = NO_OPERAND;
      fgf(cvtptrx++) = fStkPush2;  /* push operand to adjust stack */
      stkcnt -= 2;
   }

   /* set the operand pointer here */
   if (ffptr == fStkSto ){ /* this must be before test for load */
      opp(cvtptrx) = (void near *)(Store[StoPtr++]);
   }
   else if (ffptr == fStkLod && debugflag == 322 ){
      /* if disabling optimizer, set load pointer here */
      opp(cvtptrx) = (void near *)(Load[LodPtr++]);
   }
   else {
      opp(cvtptrx) = NO_OPERAND;
   }

   if (debugflag == 322 ){
      goto SkipOptimizer;
   } /* --------------------------  begin optimizer  -------------- */

   /* For the following: */
   /*   * == cvtptrx points to this */
   /*  () == this is about to be added to the array */

   if (ffptr == fStkLod) { /* we are about to add Lod to the array */
      if (prevfptr == fStkLod && Load[LodPtr-1] == Load[LodPtr] ) {
         /* previous non-adjust operator was Lod of same operand */
         /* i.e. found {? lodx ? (*lodx) } */
         if (fgf(--cvtptrx) == fStkPush2 ){ /* prev fn was push */
            /* {? lod *push (lod) } */
            --cvtptrx; /* found {? *lod push (lod) } */
            if (fgf(cvtptrx-1) == fStkPush2){ /* always more ops here */
#ifdef TESTFP
               stopmsg(0, "push *lod push (lod) -> push4 (*loddup)" );
#endif
               fgf(cvtptrx-1) = fStkPush4;
            }
            else { /* prev op not push */
#ifdef TESTFP
               stopmsg(0, "op *lod push (lod) -> op pusha(p=0) (*loddup)" );
#endif
               opp(cvtptrx) = NO_OPERAND; /* use 'alternate' push fn. */
               fgf(cvtptrx++) = fStkPush2a; /* push with TWO_FREE on stack */
               /* operand ptr will be set below */
            }
         }
         else {  /* never {push *lod (lod) } so must be */
#ifdef TESTFP
            stopmsg(0, "op *lod (lod) -> op (*loddup)" );
#endif
         }
         ffptr = fStkLodDup;
      }
      else if (prevfptr == fStkSto2
               && Store[StoPtr-1] == Load[LodPtr] ){
         /* store, load of same value */
         /* only one operand on stack here when prev oper is Sto2 */
         --cvtptrx;
#ifdef TESTFP
         stopmsg(0, "*sto2 (lod) -> (*stodup)" );
#endif
         ffptr = fStkStoDup;
      }
      /* This may cause roundoff problems when later operators */
      /*  use the rounded value that was stored here, while the next */
      /*  operator uses the more accurate internal value. */
      else if (prevfptr == fStkStoClr1 && prevstkcnt == 2
               && Store[StoPtr-1] == Load[LodPtr] ){
         /* store, clear, load same value found */
         /* only one operand was on stack so this is safe */
         --cvtptrx;
#ifdef TESTFP
         stopmsg (0, "*StoClr1 (Lod) -> (*Sto2)" );
#endif
         ffptr = fStkSto2; /* use different Sto fn */
      }
      else {
         /* the really awful hack below gets the first char of the name */
         /*    of the variable being loaded */
         testconst = **(((char * far *)Load[LodPtr] ) - 2 );
         if ( !isalpha(testconst) && Load[LodPtr]->d.y == 0.0 ){
            /* if first character not alpha, the var is a constant */
#ifdef TESTFP
            stopmsg (0, "(*lod) -> (*lodrealc)" );
#endif
            ffptr = fStkLodRealC; /* a real const is being loaded */
         }
      }
      /* set the operand ptr here */
      opp(cvtptrx) = (void near *)(Load[LodPtr++]);
   }
   else if (ffptr == fStkAdd ){
      if (prevfptr == fStkLodDup ){ /* there is never a push before add */
         --cvtptrx; /* found {? *loddup (add) } */
         if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush2a ){
            /* because {push lod lod } impossible so is {push loddup } */
#ifdef TESTFP
            stopmsg (0, "pusha *loddup (add) -> (*loddbl),stk+=2" );
#endif
            --cvtptrx;
            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptr */
            stkcnt += 2;
         }
         else if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush4 ){
#ifdef TESTFP
            stopmsg (0, "push4 *loddup (add) -> push2 (*loddbl),stk+=2" );
#endif
            fgf(cvtptrx-1) = fStkPush2;
            stkcnt += 2;  /*  CAE added 12 July 1993 to fix bug  */
         }
         else {
#ifdef TESTFP
            stopmsg (0, "op *loddup (add) -> {op (*loddbl)" );
#endif
         }
         ffptr = fStkLodDbl;
      }
      else if (prevfptr == fStkStoDup ){
#ifdef TESTFP
         stopmsg (0, "stodup (add) -> (stodbl)" );
#endif
         /* there are always exactly 4 on stack here */
         --cvtptrx;
         ffptr = fStkStoDbl;
      }
      else if (prevfptr == fStkLod ){ /* have found {lod (*add) } */
         --cvtptrx;	/* {? *lod (add) } */
         if (fgf(cvtptrx-1) == fStkPush2 ){
#ifdef TESTFP
            stopmsg (0, "*push load (add) -> (*plodadd),stk+=2" );
#endif
            --cvtptrx;
            stkcnt += 2; /* eliminated a push */
            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
            ffptr = fStkPLodAdd;
         }
         else {
#ifdef TESTFP
            stopmsg (0, "op *lod (add) -> op (*lodadd)" );
#endif
            ffptr = fStkLodAdd;
         }
      }
      else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
         --cvtptrx; /* found {? *lodreal (add) } */
         if (fgf(cvtptrx-1) == fStkPush2 ){
#ifdef TESTFP
         stopmsg (0, "*push lodreal (add) -> (*lodrealadd),stk+=2" );
#endif
            --cvtptrx;
            stkcnt += 2;	/* push eliminated */
            opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
         }
         else {
#ifdef TESTFP
            stopmsg (0, "*lodreal (add) -> (*lodrealadd)" );
#endif
         }
         ffptr = fStkLodRealAdd;
      }
   }
   else if (ffptr == fStkSub ){
      if (prevfptr == fStkLod ){
         /* found {lod (*sub) } */
         --cvtptrx; /* {*lod (sub) } */
         /* there is never a sequence (lod push sub ) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -