home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / frasrc18.zip / PARSERFP.C < prev    next >
C/C++ Source or Header  |  1993-03-28  |  36KB  |  1,199 lines

  1. /* */
  2. /* PARSERFP.C  -- Part of FRACTINT fractal drawer. */
  3. /* */
  4. /*   By Chuck Ebbert  CompuServe [76306,1226] */
  5. /*                     internet: 76306.1226@compuserve.com  */
  6. /* */
  7. /* Fast floating-point parser code.  The functions beginning with */
  8. /*    "fStk" are in PARSERA.ASM.  PARSER.C calls this code after */
  9. /*    it has parsed the formula. */
  10. /* */
  11. /*   Converts the function pointers/load pointers/store pointers */
  12. /*       built by parsestr() into an optimized array of function */
  13. /*       pointer/operand pointer pairs. */
  14. /* */
  15. /* ******************************************************************* */
  16. /*                                                                     */
  17. /*  (C) 1992, 1993 Chuck Ebbert.  All rights reserved.                 */
  18. /*                                                                     */
  19. /*    This code may be freely distributed and used in non-commercial   */
  20. /*    programs provided the author is credited either during program   */
  21. /*    execution or in the documentation, and this copyright notice     */
  22. /*    is left intact.  Sale of this code, or its use in any commercial */
  23. /*    product requires permission from the author.  Nominal            */
  24. /*    distribution and handling fees may be charged by shareware and   */
  25. /*    freeware distributors.                                           */
  26. /*                                                                     */
  27. /*       Chuck Ebbert                                                  */
  28. /*       1915 Blust Ln.                                                */
  29. /*       Enola, PA  17025                                              */
  30. /*                                                                     */
  31. /* ******************************************************************* */
  32. /* */
  33. /* Revised 22 MAR 1993 */
  34. /* */
  35. /* Uncomment the next line to enable debug. */
  36. /*      #define TESTFP 1  */
  37. /* */
  38.  
  39. #include <string.h>
  40. #include <ctype.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <float.h>
  44. #include <time.h>
  45. #include "mpmath.h"
  46. #include "prototyp.h"
  47.  
  48. extern union Arg *Arg1, *Arg2;
  49. /* Some of these variables should be renamed for safety */
  50. extern union Arg s[20], far * far *Store, far * far *Load;
  51. extern int StoPtr, LodPtr, OpPtr;
  52. extern int debugflag;
  53. extern unsigned vsp, LastOp;
  54. extern struct ConstArg far *v;
  55. extern int inside;         /* "inside" color to use    */
  56. extern int outside;        /* "outside" color to use   */
  57. extern int potflag;        /* potential enabled? */
  58. extern char useinitorbit;
  59. extern int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;
  60. extern void (far * far *f)(void);
  61.  
  62. struct fls { /* function, load, store pointers  CAE fp */
  63.    void (near *function)(void);
  64.    union Arg near *operand;
  65. } far *pfls = (struct fls far *)0;
  66.  
  67. void  StkLod(void);
  68. void  StkClr(void);
  69. void  dStkAdd(void);
  70. void  dStkSub(void);
  71. void  dStkMul(void);
  72. void  dStkDiv(void);
  73. void  StkSto(void);
  74. void  dStkSqr(void);
  75. void  EndInit(void);
  76. void  dStkMod(void);
  77. void  dStkLTE(void);
  78. void  dStkSin(void);
  79. void  dStkCos(void);
  80. void  dStkSinh(void);
  81. void  dStkCosh(void);
  82. void  dStkCosXX(void);
  83. void  dStkTan(void);
  84. void  dStkTanh(void);
  85. void  dStkCoTan(void);
  86. void  dStkCoTanh(void);
  87. void  dStkLog(void);
  88. void  dStkExp(void);
  89. void  dStkPwr(void);
  90. void  dStkLT(void);
  91. void  dStkFlip(void);
  92. void  dStkReal(void);
  93. void  dStkImag(void);
  94. void  dStkConj(void);
  95. void  dStkNeg(void);
  96. void  dStkAbs(void);
  97. void  dStkRecip(void);
  98. void  StkIdent(void);
  99. void  dStkGT(void);
  100. void  dStkGTE(void);
  101. void  dStkNE(void);
  102. void  dStkEQ(void);
  103. void  dStkAND(void);
  104. void  dStkOR(void);
  105.  
  106. #define fgf(x) pfls[(x)].function
  107. #define opp(x) pfls[(x)].operand
  108. #define NO_OPERAND (void near *)0
  109. #define LastSqr v[4].a
  110. #define MAX_ARGS 100
  111. #define MAX_STACK 8
  112. #define TWO_FREE 6
  113.  
  114. #ifndef XFRACT
  115.  
  116. void (near fStkPull2 )(void); /* pull up fpu stack from 2 to 4 */
  117. void (near fStkPush2 )(void); /* push down fpu stack from 8 to 6 */
  118. void (near fStkPush2a )(void); /* push down fpu stack from 6 to 4 */
  119. void (near fStkPush4 )(void); /* push down fpu stack from 8 to 4 */
  120. void (near fStkLodDup )(void); /* lod, dup */
  121. void (near fStkLodSqr )(void); /* lod, sqr, dont save magnitude */
  122. void (near fStkLodSqr2 )(void); /* lod, sqr, save magnitude */
  123. void (near fStkStoDup )(void); /* store, duplicate */
  124. void (near fStkStoSqr )(void); /* store, sqr, save lastsqr */
  125. void (near fStkStoSqr0 )(void); /* store, sqr, dont save lastsqr */
  126. void (near fStkLodDbl )(void); /* load, double */
  127. void (near fStkStoDbl )(void); /* store, double */
  128. void (near fStkReal2 )(void); /* fast ver. of real */
  129. void (near fStkSqr )(void); /* sqr, save magnitude in lastsqr */
  130. void (near fStkSqr0 )(void); /* sqr, no save magnitude */
  131. void (near fStkClr1 )(void); /* clear fpu */
  132. void (near fStkClr2 )(void); /* test stack top, clear fpu */
  133. void (near fStkStoClr1 )(void); /* store, clr1 */
  134. void (near fStkAdd )(void);
  135. void (near fStkSub )(void);
  136. void (near fStkSto )(void);
  137. void (near fStkSto2 )(void); /* fast ver. of sto */
  138. void (near fStkLod )(void);
  139. void (near fStkEndInit )(void);
  140. void (near fStkMod )(void);
  141. void (near fStkMod2 )(void);
  142. void (near fStkLodMod2 )(void);
  143. void (near fStkStoMod2 )(void);
  144. void (near fStkLTE )(void);
  145. void (near fStkLodLTEMul )(void);
  146. void (near fStkLTE2 )(void);
  147. void (near fStkLodLTE )(void);
  148. void (near fStkLodLTE2 )(void);
  149. void (near fStkLodLTEAnd2 )(void);
  150. void (near fStkLT )(void);
  151. void (near fStkLodLTMul )(void);
  152. void (near fStkLT2 )(void);
  153. void (near fStkLodLT )(void);
  154. void (near fStkLodLT2 )(void);
  155. void (near fStkGTE )(void);
  156. void (near fStkLodGTE )(void);
  157. void (near fStkLodGTE2 )(void);
  158. void (near fStkGT )(void);
  159. void (near fStkGT2 )(void);
  160. void (near fStkLodGT )(void);
  161. void (near fStkLodGT2 )(void);
  162. void (near fStkEQ )(void);
  163. void (near fStkLodEQ )(void);
  164. void (near fStkNE )(void);
  165. void (near fStkLodNE )(void);
  166. void (near fStkAND )(void);
  167. void (near fStkANDClr2 )(void);
  168. void (near fStkOR )(void);
  169. void (near fStkSin )(void);
  170. void (near fStkSinh )(void);
  171. void (near fStkCos )(void);
  172. void (near fStkCosXX )(void);
  173. void (near fStkCosh )(void);
  174. void (near fStkTan )(void);
  175. void (near fStkTanh )(void);
  176. void (near fStkCoTan )(void);
  177. void (near fStkCoTanh )(void);
  178. void (near fStkLog )(void);
  179. void (near fStkExp )(void);
  180. void (near fStkPwr )(void);
  181. void (near fStkMul )(void);
  182. void (near fStkDiv )(void);
  183. void (near fStkFlip )(void);
  184. void (near fStkReal )(void);
  185. void (near fStkImag )(void);
  186. void (near fStkRealFlip )(void);
  187. void (near fStkImagFlip )(void);
  188. void (near fStkConj )(void);
  189. void (near fStkNeg )(void);
  190. void (near fStkAbs )(void);
  191. void (near fStkRecip )(void);
  192. void (near fStkLodReal )(void);
  193. void (near fStkLodRealC )(void);
  194. void (near fStkLodImag )(void);
  195. void (near fStkLodRealFlip )(void);
  196. void (near fStkLodRealAbs )(void);
  197. void (near fStkLodRealMul )(void);
  198. void (near fStkLodRealAdd )(void);
  199. void (near fStkLodRealSub )(void);
  200. void (near fStkLodImagFlip )(void);
  201. void (near fStkLodImagAbs )(void);
  202. void (near fStkLodConj )(void);
  203. void (near fStkLodAdd )(void);
  204. void (near fStkLodSub )(void);
  205. void (near fStkLodSubMod )(void);
  206. void (near fStkLodMul )(void);
  207. void (near fStkPLodAdd )(void);
  208. void (near fStkPLodSub )(void);
  209. void (near Img_Setup )(void);
  210.  
  211.  
  212. static void (near *prevfptr )(void);
  213. static int stkcnt, prevstkcnt, cvtptrx, prevlodptr, lastsqrused;
  214.  
  215. static void CvtFptr(void (near * ffptr)(void), int MinStk, int MaxStk,
  216.       int Delta )
  217. /* (MinStk <= 4, MaxStk >= TWO_FREE) */
  218. {
  219.    char testconst = 0;
  220.  
  221.    if (stkcnt < MinStk ) { /* not enough operands on fpu stack */
  222. #ifdef TESTFP
  223.       stopmsg(0, "Inserted pull." );
  224. #endif
  225.       opp(cvtptrx) = NO_OPERAND;
  226.       fgf(cvtptrx++) = fStkPull2;  /* so adjust the stack, pull operand */
  227.       stkcnt += 2;
  228.    }
  229.    else if (stkcnt > MaxStk ) { /* too many operands */
  230. #ifdef TESTFP
  231.       stopmsg(0, "Inserted push." );
  232. #endif
  233.       opp(cvtptrx) = NO_OPERAND;
  234.       fgf(cvtptrx++) = fStkPush2;  /* push operand to adjust stack */
  235.       stkcnt -= 2;
  236.    }
  237.  
  238.    /* set the operand pointer here */
  239.    if (ffptr == fStkSto ){ /* this must be before test for load */
  240.       opp(cvtptrx) = (void near *)(Store[StoPtr++]);
  241.    }
  242.    else if (ffptr == fStkLod && debugflag == 322 ){
  243.       /* if disabling optimizer, set load pointer here */
  244.       opp(cvtptrx) = (void near *)(Load[LodPtr++]);
  245.    }
  246.    else {
  247.       opp(cvtptrx) = NO_OPERAND;
  248.    }
  249.  
  250.    if (debugflag == 322 ){
  251.       goto SkipOptimizer;
  252.    } /* --------------------------  begin optimizer  -------------- */
  253.  
  254.    /* For the following: */
  255.    /*   * == cvtptrx points to this */
  256.    /*  () == this is about to be added to the array */
  257.  
  258.    if (ffptr == fStkLod) { /* we are about to add Lod to the array */
  259.       if (prevfptr == fStkLod && Load[LodPtr-1] == Load[LodPtr] ) {
  260.          /* previous non-adjust operator was Lod of same operand */
  261.          /* i.e. found {? lodx ? (*lodx) } */
  262.          if (fgf(--cvtptrx) == fStkPush2 ){ /* prev fn was push */
  263.             /* {? lod *push (lod) } */
  264.             --cvtptrx; /* found {? *lod push (lod) } */
  265.             if (fgf(cvtptrx-1) == fStkPush2){ /* always more ops here */
  266. #ifdef TESTFP
  267.                stopmsg(0, "push *lod push (lod) -> push4 (*loddup)" );
  268. #endif
  269.                fgf(cvtptrx-1) = fStkPush4;
  270.             }
  271.             else { /* prev op not push */
  272. #ifdef TESTFP
  273.                stopmsg(0, "op *lod push (lod) -> op pusha(p=0) (*loddup)" );
  274. #endif
  275.                opp(cvtptrx) = NO_OPERAND; /* use 'alternate' push fn. */
  276.                fgf(cvtptrx++) = fStkPush2a; /* push with TWO_FREE on stack */
  277.                /* operand ptr will be set below */
  278.             }
  279.          }
  280.          else {  /* never {push *lod (lod) } so must be */
  281. #ifdef TESTFP
  282.             stopmsg(0, "op *lod (lod) -> op (*loddup)" );
  283. #endif
  284.          }
  285.          ffptr = fStkLodDup;
  286.       }
  287.       else if (prevfptr == fStkSto2
  288.                && Store[StoPtr-1] == Load[LodPtr] ){
  289.          /* store, load of same value */
  290.          /* only one operand on stack here when prev oper is Sto2 */
  291.          --cvtptrx;
  292. #ifdef TESTFP
  293.          stopmsg(0, "*sto2 (lod) -> (*stodup)" );
  294. #endif
  295.          ffptr = fStkStoDup;
  296.       }
  297.       /* This may cause roundoff problems when later operators */
  298.       /*  use the rounded value that was stored here, while the next */
  299.       /*  operator uses the more accurate internal value. */
  300.       else if (prevfptr == fStkStoClr1 && prevstkcnt == 2
  301.                && Store[StoPtr-1] == Load[LodPtr] ){
  302.          /* store, clear, load same value found */
  303.          /* only one operand was on stack so this is safe */
  304.          --cvtptrx;
  305. #ifdef TESTFP
  306.          stopmsg (0, "*StoClr1 (Lod) -> (*Sto2)" );
  307. #endif
  308.          ffptr = fStkSto2; /* use different Sto fn */
  309.       }
  310.       else {
  311.          /* the really awful hack below gets the first char of the name */
  312.          /*    of the variable being loaded */
  313.          testconst = **(((char * far *)Load[LodPtr] ) - 2 );
  314.          if ( !isalpha(testconst) && Load[LodPtr]->d.y == 0.0 ){
  315.             /* if first character not alpha, the var is a constant */
  316. #ifdef TESTFP
  317.             stopmsg (0, "(*lod) -> (*lodrealc)" );
  318. #endif
  319.             ffptr = fStkLodRealC; /* a real const is being loaded */
  320.          }
  321.       }
  322.       /* set the operand ptr here */
  323.       opp(cvtptrx) = (void near *)(Load[LodPtr++]);
  324.    }
  325.    else if (ffptr == fStkAdd ){
  326.       if (prevfptr == fStkLodDup ){ /* there is never a push before add */
  327.          --cvtptrx; /* found {? *loddup (add) } */
  328.          if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush2a ){
  329.             /* because {push lod lod } impossible so is {push loddup } */
  330. #ifdef TESTFP
  331.             stopmsg (0, "pusha *loddup (add) -> (*loddbl),stk+=2" );
  332. #endif
  333.             --cvtptrx;
  334.             opp(cvtptrx) = opp(cvtptrx+1); /* fix opptr */
  335.             stkcnt += 2;
  336.          }
  337.          else if (cvtptrx>0 && fgf(cvtptrx-1) == fStkPush4 ){
  338. #ifdef TESTFP
  339.             stopmsg (0, "push4 *loddup (add) -> push2 (*loddbl)" );
  340. #endif
  341.             fgf(cvtptrx-1) = fStkPush2;
  342.          }
  343.          else {
  344. #ifdef TESTFP
  345.             stopmsg (0, "op *loddup (add) -> {op (*loddbl)" );
  346. #endif
  347.          }
  348.          ffptr = fStkLodDbl;
  349.       }
  350.       else if (prevfptr == fStkStoDup ){
  351. #ifdef TESTFP
  352.          stopmsg (0, "stodup (add) -> (stodbl)" );
  353. #endif
  354.          /* there are always exactly 4 on stack here */
  355.          --cvtptrx;
  356.          ffptr = fStkStoDbl;
  357.       }
  358.       else if (prevfptr == fStkLod ){ /* have found {lod (*add) } */
  359.          --cvtptrx;    /* {? *lod (add) } */
  360.          if (fgf(cvtptrx-1) == fStkPush2 ){
  361. #ifdef TESTFP
  362.             stopmsg (0, "*push load (add) -> (*plodadd),stk+=2" );
  363. #endif
  364.             --cvtptrx;
  365.             stkcnt += 2; /* eliminated a push */
  366.             opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  367.             ffptr = fStkPLodAdd;
  368.          }
  369.          else {
  370. #ifdef TESTFP
  371.             stopmsg (0, "op *lod (add) -> op (*lodadd)" );
  372. #endif
  373.             ffptr = fStkLodAdd;
  374.          }
  375.       }
  376.       else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  377.          --cvtptrx; /* found {? *lodreal (add) } */
  378.          if (fgf(cvtptrx-1) == fStkPush2 ){
  379. #ifdef TESTFP
  380.          stopmsg (0, "*push lodreal (add) -> (*lodrealadd),stk+=2" );
  381. #endif
  382.             --cvtptrx;
  383.             stkcnt += 2;    /* push eliminated */
  384.             opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  385.          }
  386.          else {
  387. #ifdef TESTFP
  388.             stopmsg (0, "*lodreal (add) -> (*lodrealadd)" );
  389. #endif
  390.          }
  391.          ffptr = fStkLodRealAdd;
  392.       }
  393.    }
  394.    else if (ffptr == fStkSub ){
  395.       if (prevfptr == fStkLod ){
  396.          /* found {lod (*sub) } */
  397.          --cvtptrx; /* {*lod (sub) } */
  398.          /* there is never a sequence (lod push sub ) */
  399.          if (fgf(cvtptrx-1) == fStkPush2 ){
  400. #ifdef TESTFP
  401.             stopmsg (0, "*push lod (sub) -> (*plodsub),stk+=2" );
  402. #endif
  403.             --cvtptrx;
  404.             opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  405.             stkcnt += 2; /* push was deleted so adj. stkcnt */
  406.             ffptr = fStkPLodSub;
  407.          }
  408.          else {
  409. #ifdef TESTFP
  410.             stopmsg (0, "*lod (sub) -> (*lodsub)" );
  411. #endif
  412.             ffptr = fStkLodSub;
  413.          }
  414.       }
  415.       else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  416.          --cvtptrx; /* {? *lodreal (sub) } */
  417.          if (fgf(cvtptrx-1) == fStkPush2 ){
  418. #ifdef TESTFP
  419.             stopmsg (0, "*push lodreal (sub) -> (*lodrealsub),stk+=2" );
  420. #endif
  421.             --cvtptrx;
  422.             stkcnt += 2;    /* push eliminated */
  423.             opp(cvtptrx) = opp(cvtptrx+1); /* fix opptrs */
  424.          }
  425.          else {
  426. #ifdef TESTFP
  427.             stopmsg (0, "*lodreal (sub) -> (*lodrealsub)" );
  428. #endif
  429.          }
  430.          ffptr = fStkLodRealSub;
  431.       }
  432.    }
  433.    else if (ffptr == fStkMul ){
  434.       if (prevfptr == fStkLodDup ){
  435.          /* found {loddup ? (*mul) } */
  436.          if (fgf(--cvtptrx) == fStkPush2 ){
  437. #ifdef TESTFP
  438.             stopmsg (0, "loddup *push (mul) -> (*lodsqr),stk+=2" );
  439. #endif
  440.             stkcnt += 2; /* eliminate this push */
  441.             --cvtptrx;    /* prev is a LodDup */
  442.          }
  443.          else {
  444. #ifdef TESTFP
  445.             stopmsg (0, "*loddup (mul) -> (*lodsqr)" );
  446. #endif
  447.          }
  448.          ffptr = fStkLodSqr;
  449.       }
  450.       else if (prevfptr == fStkStoDup ){ /* no pushes here, 4 on stk. */
  451. #ifdef TESTFP
  452.          stopmsg (0, "stodup (mul) -> (*stosqr0)" );
  453. #endif
  454.          --cvtptrx;
  455.          ffptr = fStkStoSqr0; /* dont save lastsqr here ever */
  456.       }
  457.       else if (prevfptr == fStkLod ){
  458.          --cvtptrx; /* {lod *? (mul) } */
  459.          if (fgf(cvtptrx) == fStkPush2 ){ /* {lod *push (mul) } */
  460.             --cvtptrx; /* {? *lod push (mul) } */
  461.             if(fgf(cvtptrx-1) == fStkPush2 ){
  462. #ifdef TESTFP
  463.                stopmsg (0, "push *lod push (mul) -> push4 (*lodmul)" );
  464. #endif
  465.                fgf(cvtptrx-1) = fStkPush4;
  466.             }
  467.             else {
  468. #ifdef TESTFP
  469.                stopmsg (0, "op *lod push (mul) -> op pusha (*lodmul)" );
  470. #endif
  471.                opp(cvtptrx+1) = opp(cvtptrx); /* fix operand ptr */
  472.                fgf(cvtptrx) = fStkPush2a;
  473.                opp(cvtptrx++) = NO_OPERAND;
  474.             }
  475.          }
  476.          else {
  477. #ifdef TESTFP
  478.             stopmsg (0, "*lod (mul) -> (*lodmul)" );
  479. #endif
  480.          }
  481.          ffptr = fStkLodMul;
  482.       }
  483.       else if (prevfptr == fStkLodReal || prevfptr == fStkLodRealC ){
  484.          --cvtptrx; /* found {lodreal *? (mul) } */
  485.          if (fgf(cvtptrx) == fStkPush2 ){
  486. #ifdef TESTFP
  487.             stopmsg (0, "lodreal *push2 (mul) -> (*lodrealmul),stk+=2" );
  488. #endif
  489.             --cvtptrx;
  490.             stkcnt += 2;    /* stack ends with TWO_FREE, not 4 */
  491.          }
  492.          else {
  493. #ifdef TESTFP
  494.             stopmsg (0, "*lodreal (mul) }-> {(*lodrealmul)" );
  495. #endif
  496.          }
  497.          ffptr = fStkLodRealMul;
  498.       }
  499.       else if (prevfptr == fStkLodLT && fgf(cvtptrx-1) != fStkPull2 ){
  500.          /* this shortcut fails if {Lod LT Pull Mul } found */
  501. #ifdef TESTFP
  502.          stopmsg (0, "LodLT (*Mul) -> (*LodLTMul)" );
  503. #endif
  504.          --cvtptrx; /* never { lod LT Push Mul } here */
  505.          ffptr = fStkLodLTMul;
  506.       }
  507.       else if (prevfptr == fStkLodLTE && fgf(cvtptrx-1) != fStkPull2 ){
  508. #ifdef TESTFP
  509.          stopmsg (0, "LodLTE (*mul) -> (*LodLTEmul)" );
  510. #endif
  511.          --cvtptrx;
  512.          ffptr = fStkLodLTEMul;
  513.       }
  514.    }
  515.    else if (ffptr == fStkClr1 && prevfptr == fStkSto ){
  516. #ifdef TESTFP
  517.          stopmsg (0, "sto (*clr1) -> (*stoclr1)" );
  518. #endif
  519.       --cvtptrx;
  520.       ffptr = fStkStoClr1;
  521.    }
  522.    else if (ffptr == fStkDiv ){
  523.       if (prevfptr == fStkLodRealC && vsp < MAX_ARGS - 1 ){
  524.          /* have found a divide by a real constant */
  525.          /*  and there is space to create a new one */
  526.          /* {lodrealc ? (*div) } */
  527.          --cvtptrx; /* change '/ const' to '* 1/const' */
  528.          if (fgf(cvtptrx) == fStkPush2 ){
  529. #ifdef TESTFP
  530.             stopmsg (0, "lodrealc *push (div) -> (*lodrealmul),stk+=2" );
  531. #endif
  532.             --cvtptrx;
  533.             stkcnt += 2;
  534.          }
  535.          else {
  536. #ifdef TESTFP
  537.             stopmsg (0, "*lodrealc (div) -> {(*lodrealmul)" );
  538. #endif
  539.          }
  540.          v[vsp].s = (void near *)0; /* this constant has no name */
  541.          v[vsp].len = 0;
  542.          v[vsp].a.d.x = 1.0 / Load[LodPtr-1]->d.x;
  543.          v[vsp].a.d.y = 0.0;
  544.          opp(cvtptrx) = (void near *)&v[vsp++].a; /* isn't C fun! */
  545.          ffptr = fStkLodRealMul;
  546.       }
  547.    }
  548.    else if (ffptr == fStkReal ){
  549.       if (prevfptr == fStkLod ){
  550. #ifdef TESTFP
  551.          stopmsg (0, "lod (*real) -> (*lodreal)" );
  552. #endif
  553.          --cvtptrx;
  554.          ffptr = fStkLodReal;
  555.       }
  556.       else if (stkcnt < MAX_STACK ){
  557. #ifdef TESTFP
  558.          stopmsg (0, "(*real) -> (*real2)" );
  559. #endif
  560.          ffptr = fStkReal2;
  561.       }
  562.    }
  563.    else if (ffptr == fStkImag && prevfptr == fStkLod ){
  564. #ifdef TESTFP
  565.          stopmsg (0, "lod (*imag) -> lodimag" );
  566. #endif
  567.       --cvtptrx;
  568.       ffptr = fStkLodImag;
  569.    }
  570.    else if (ffptr == fStkConj && prevfptr == fStkLod ){
  571. #ifdef TESTFP
  572.          stopmsg (0, "lod (*conj) -> (*lodconj)" );
  573. #endif
  574.       --cvtptrx;
  575.       ffptr = fStkLodConj;
  576.    }
  577.    else if (ffptr == fStkMod && stkcnt < MAX_STACK ){
  578. #ifdef TESTFP
  579.       stopmsg (0, "(*mod) -> (*mod2)" );
  580. #endif
  581.       ffptr = fStkMod2; /* use faster version if room on stack */
  582.       if (prevfptr == fStkLod ){
  583. #ifdef TESTFP
  584.          stopmsg (0, "lod (*mod2) -> (*lodmod2)" );
  585. #endif
  586.          --cvtptrx;
  587.          ffptr = fStkLodMod2;
  588.       }
  589.       else if (prevfptr == fStkSto || prevfptr == fStkSto2 ){
  590. #ifdef TESTFP
  591.          stopmsg (0, "sto (*mod2) -> (*stomod2)" );
  592. #endif
  593.          --cvtptrx;
  594.          ffptr = fStkStoMod2;
  595.       }
  596.       else if (prevfptr == fStkLodSub ){
  597. #ifdef TESTFP
  598.          stopmsg (0, "lodsub (*mod2) -> (*lodsubmod)" );
  599. #endif
  600.          --cvtptrx;
  601.          ffptr = fStkLodSubMod;
  602.       }
  603.    }
  604.    else if (ffptr == fStkFlip ){
  605.       if (prevfptr == fStkReal || prevfptr == fStkReal2 ){
  606. #ifdef TESTFP
  607.          stopmsg (0, "real (*flip) -> (*realflip)" );
  608. #endif
  609.          --cvtptrx;
  610.          ffptr = fStkRealFlip;
  611.       }
  612.       else if (prevfptr == fStkImag ){
  613. #ifdef TESTFP
  614.          stopmsg (0, "imag (*flip) -> (*imagflip)" );
  615. #endif
  616.          --cvtptrx;
  617.          ffptr = fStkImagFlip;
  618.       }
  619.       else if (prevfptr == fStkLodReal ){
  620. #ifdef TESTFP
  621.          stopmsg (0, "lodreal (*flip) -> (*lodrealflip)" );
  622. #endif
  623.          --cvtptrx;
  624.          ffptr = fStkLodRealFlip;
  625.       }
  626.       else if (prevfptr == fStkLodImag ){
  627. #ifdef TESTFP
  628.          stopmsg (0, "lodimag (*flip) -> (*lodimagflip)" );
  629. #endif
  630.          --cvtptrx;
  631.          ffptr = fStkLodImagFlip;
  632.       }
  633.    }
  634.    else if (ffptr == fStkAbs ){
  635.       if (prevfptr == fStkLodReal ){
  636. #ifdef TESTFP
  637.          stopmsg (0, "lodreal (*abs) -> (*lodrealabs)" );
  638. #endif
  639.          --cvtptrx;
  640.          ffptr = fStkLodRealAbs;
  641.       }
  642.       else if (prevfptr == fStkLodImag ){
  643. #ifdef TESTFP
  644.          stopmsg (0, "lodimag (*abs) -> (*lodimagabs)" );
  645. #endif
  646.          --cvtptrx;
  647.          ffptr = fStkLodImagAbs;
  648.       }
  649.    }
  650.    else if (ffptr == fStkSqr ){
  651.       if (prevfptr == fStkLod && fgf(cvtptrx-1) != fStkPush2 ){
  652. #ifdef TESTFP
  653.          stopmsg (0, "lod (*sqr) -> (*lodsqr)" );
  654. #endif
  655.          --cvtptrx;
  656.          ffptr = fStkLodSqr; /* assume no need to save lastsqr */
  657.          if (lastsqrused) {
  658. #ifdef TESTFP
  659.             stopmsg (0, "(*lodsqr) -> (*lodsqr2)" );
  660. #endif
  661.             ffptr = fStkLodSqr2; /* lastsqr is being used */
  662.          }
  663.       }
  664.       else if (prevfptr == fStkSto2 ){
  665. #ifdef TESTFP
  666.          stopmsg (0, "sto2 (*sqr) -> (*stosqr0)" );
  667. #endif
  668.          --cvtptrx;
  669.          ffptr = fStkStoSqr0; /* assume no need to save lastsqr */
  670.          if (lastsqrused) {
  671. #ifdef TESTFP
  672.             stopmsg (0, "(*stosqr0) -> (*stosqr)" );
  673. #endif
  674.             ffptr = fStkStoSqr; /* save lastsqr */
  675.          }
  676.       }
  677.       else {
  678.          if (!lastsqrused) {
  679. #ifdef TESTFP
  680.             stopmsg (0, "(*sqr) -> (*sqr0)" );
  681. #endif
  682.             ffptr = fStkSqr0; /* don't save lastsqr */
  683.          }
  684.       }
  685.    }
  686.    else if (ffptr == fStkLTE && ( prevfptr == fStkLod
  687.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  688. #ifdef TESTFP
  689.       stopmsg(0, "Lod (*LTE) -> (*LodLTE)" );
  690. #endif
  691.       --cvtptrx;
  692.       ffptr = fStkLodLTE;
  693.    }
  694.    else if (ffptr == fStkLT && ( prevfptr == fStkLod
  695.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  696. #ifdef TESTFP
  697.       stopmsg(0, "Lod (*LT) -> (*LodLT)" );
  698. #endif
  699.       --cvtptrx;
  700.       ffptr = fStkLodLT;
  701.    }
  702.    else if (ffptr == fStkGT && ( prevfptr == fStkLod
  703.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  704. #ifdef TESTFP
  705.       stopmsg(0, "Lod (*GT) -> (*LodGT)" );
  706. #endif
  707.       --cvtptrx;
  708.       ffptr = fStkLodGT;
  709.    }
  710.    else if (ffptr == fStkGTE && ( prevfptr == fStkLod
  711.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  712. #ifdef TESTFP
  713.       stopmsg(0, "Lod (*GTE) -> (*LodGTE)" );
  714. #endif
  715.       --cvtptrx;
  716.       ffptr = fStkLodGTE;
  717.    }
  718.    else if (ffptr == fStkNE && ( prevfptr == fStkLod
  719.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  720. #ifdef TESTFP
  721.       stopmsg(0, "Lod (*NE) -> (*LodNE)" );
  722. #endif
  723.       --cvtptrx;
  724.       ffptr = fStkLodNE;
  725.    }
  726.    else if (ffptr == fStkEQ && ( prevfptr == fStkLod
  727.          || prevfptr == fStkLodReal || prevfptr == fStkLodRealC ) ){
  728. #ifdef TESTFP
  729.       stopmsg(0, "Lod (*EQ) -> (*LodEQ)" );
  730. #endif
  731.       --cvtptrx;
  732.       ffptr = fStkLodEQ;
  733.    }
  734.  
  735. SkipOptimizer:  /* -----------  end of optimizer code  ------------ */
  736.  
  737.    fgf(cvtptrx++) = prevfptr = ffptr;
  738.    prevstkcnt = stkcnt;
  739.  
  740.    if (Delta == 999 ){
  741.       stkcnt = 0;
  742.    }
  743.    else {
  744.       stkcnt += Delta;
  745.    }
  746.    return;
  747. }
  748.  
  749. int CvtStk() {    /* convert the array of ptrs */
  750.    extern int fform_per_pixel(void);    /* these fns are in parsera.asm */
  751.    extern int fFormula(void);
  752.    extern int BadFormula(void);
  753.    extern char FormName[];
  754.    void (far *ftst)(void);
  755.    void (near *ntst)(void);
  756.  
  757. #ifdef TESTFP
  758.    if (debugflag == 322) {
  759.       stopmsg(0, "Skipping optimizer." );
  760.    }
  761. #endif
  762.  
  763.    for (OpPtr = LodPtr = lastsqrused = 0; OpPtr < LastOp; OpPtr++) {
  764.       ftst = f[OpPtr];
  765.       if (ftst == StkLod && Load[LodPtr++] == &LastSqr ){
  766.          lastsqrused = 1; /* lastsqr is being used in the formula */
  767.       }
  768.       if (  ftst != StkLod  /* these are the supported parser fns */
  769.             && ftst != StkClr
  770.             && ftst != dStkAdd
  771.             && ftst != dStkSub
  772.             && ftst != dStkMul
  773.             && ftst != dStkDiv
  774.             && ftst != StkSto
  775.             && ftst != dStkSqr
  776.             && ftst != EndInit
  777.             && ftst != dStkMod
  778.             && ftst != dStkLTE
  779.             && ftst != dStkSin
  780.             && ftst != dStkCos
  781.             && ftst != dStkSinh
  782.             && ftst != dStkCosh
  783.             && ftst != dStkCosXX
  784.             && ftst != dStkTan
  785.             && ftst != dStkTanh
  786.             && ftst != dStkCoTan
  787.             && ftst != dStkCoTanh
  788.             && ftst != dStkLog
  789.             && ftst != dStkExp
  790.             && ftst != dStkPwr
  791.             && ftst != dStkLT
  792.             && ftst != dStkFlip
  793.             && ftst != dStkReal
  794.             && ftst != dStkImag
  795.             && ftst != dStkConj
  796.             && ftst != dStkNeg
  797.             && ftst != dStkAbs
  798.             && ftst != dStkRecip
  799.             && ftst != StkIdent
  800.             && ftst != dStkGT
  801.             && ftst != dStkGTE
  802.             && ftst != dStkNE
  803.             && ftst != dStkEQ
  804.             && ftst != dStkAND
  805.             && ftst != dStkOR ){
  806.          stopmsg(0, "Fast failure, using old code" );
  807.          return 1; /* Use old code */
  808.       }
  809.    }
  810.  
  811. #ifdef TESTFP
  812.    if (lastsqrused) {
  813.       stopmsg(0, "LastSqr used" );
  814.    }
  815.    else {
  816.       stopmsg(0, "LastSqr not used" );
  817.    }
  818. #endif
  819.  
  820.    if (f[LastOp-1] != StkClr ){ /* some formulas don't clear at the end! */
  821. #ifdef TESTFP
  822.       stopmsg (0, "clr added at end" );
  823. #endif
  824.       f[LastOp++] = StkClr;
  825.    }
  826.    prevfptr = (void (near *)(void))0;
  827.    prevstkcnt = 999; /* there was not previous stk cnt */
  828.    stkcnt = cvtptrx = 0;
  829.  
  830.    for (OpPtr = LodPtr = StoPtr = 0; OpPtr < LastOp; OpPtr++) {
  831.       ftst = f[OpPtr];
  832.       if (ftst == StkLod ) {
  833. #ifdef TESTFP
  834.          stopmsg(0, "lod,0,TWO_FREE,2" );
  835. #endif
  836.          CvtFptr(fStkLod, 0, TWO_FREE, 2 );
  837.          continue;
  838.       }
  839.       if (ftst == StkClr ) {
  840.          if (OpPtr == LastOp - 1 ){
  841. #ifdef TESTFP
  842.             stopmsg(0, "clr2,0,MAX_STACK,999" );
  843. #endif
  844.             CvtFptr(fStkClr2, 0, MAX_STACK, 999 );
  845.          } else {
  846. #ifdef TESTFP
  847.             stopmsg(0, "clr1,0,MAX_STACK,999" );
  848. #endif
  849.             CvtFptr(fStkClr1, 0, MAX_STACK, 999 );
  850.          }
  851.          continue;
  852.       }
  853.       if (ftst == dStkAdd ) {
  854. #ifdef TESTFP
  855.          stopmsg(0, "add,4,MAX_STACK,-2" );
  856. #endif
  857.          CvtFptr(fStkAdd, 4, MAX_STACK, -2 );
  858.          continue;
  859.       }
  860.       if (ftst == dStkSub ) {
  861. #ifdef TESTFP
  862.          stopmsg(0, "sub,4,MAX_STACK,-2" );
  863. #endif
  864.          CvtFptr(fStkSub, 4, MAX_STACK, -2 );
  865.          continue;
  866.       }
  867.       if (ftst == dStkDiv ) {
  868. #ifdef TESTFP
  869.          stopmsg(0, "div,4,TWO_FREE,-2" );
  870. #endif
  871.          CvtFptr(fStkDiv, 4, TWO_FREE, -2 );
  872.          continue;
  873.       }
  874.       if (ftst == dStkMul ) {
  875. #ifdef TESTFP
  876.          stopmsg(0, "mul,4,TWO_FREE,-2" );
  877. #endif
  878.          CvtFptr(fStkMul, 4, TWO_FREE, -2 );
  879.          continue;
  880.       }
  881.       if (ftst == StkSto ) {
  882. #ifdef TESTFP
  883.          stopmsg(0, "sto,2,MAX_STACK,0" );
  884. #endif
  885.          CvtFptr(fStkSto, 2, MAX_STACK, 0 );
  886.          continue;
  887.       }
  888.       if (ftst == dStkSqr ) {
  889. #ifdef TESTFP
  890.          stopmsg(0, "sqr,2,TWO_FREE,0" );
  891. #endif
  892.          CvtFptr(fStkSqr, 2, TWO_FREE, 0 );
  893.          continue;
  894.       }
  895.       if (ftst == EndInit) {
  896. #ifdef TESTFP
  897.          stopmsg(0, "endinit,0,MAX_STACK,999" );
  898. #endif
  899.          CvtFptr(fStkEndInit, 0, MAX_STACK, 999 );
  900.          continue;
  901.       }
  902.       if (ftst == dStkMod ) {
  903. #ifdef TESTFP
  904.          stopmsg(0, "mod,2,MAX_STACK,0" );
  905. #endif
  906.          CvtFptr(fStkMod, 2, MAX_STACK, 0 );
  907.          continue;
  908.       }
  909.       if (ftst == dStkLTE ) {
  910. #ifdef TESTFP
  911.          stopmsg(0, "LTE,4,MAX_STACK,-2" );
  912. #endif
  913.          CvtFptr(fStkLTE, 4, MAX_STACK, -2 );
  914.          continue;
  915.       }
  916.       if (ftst == dStkSin ) {
  917. #ifdef TESTFP
  918.          stopmsg(0, "sin,2,TWO_FREE,0" );
  919. #endif
  920.          CvtFptr(fStkSin, 2, TWO_FREE, 0 );
  921.          continue;
  922.       }
  923.       if (ftst == dStkCos ) {
  924. #ifdef TESTFP
  925.          stopmsg(0, "cos,2,TWO_FREE,0" );
  926. #endif
  927.          CvtFptr(fStkCos, 2, TWO_FREE, 0 );
  928.          continue;
  929.       }
  930.       if (ftst == dStkSinh ) {
  931. #ifdef TESTFP
  932.          stopmsg(0, "sinh,2,TWO_FREE,0" );
  933. #endif
  934.          CvtFptr(fStkSinh, 2, TWO_FREE, 0 );
  935.          continue;
  936.       }
  937.       if (ftst == dStkCosh ) {
  938. #ifdef TESTFP
  939.          stopmsg(0, "cosh,2,TWO_FREE,0" );
  940. #endif
  941.          CvtFptr(fStkCosh, 2, TWO_FREE, 0 );
  942.          continue;
  943.       }
  944.       if (ftst == dStkCosXX ) {
  945. #ifdef TESTFP
  946.          stopmsg(0, "cosxx,2,TWO_FREE,0" );
  947. #endif
  948.          CvtFptr(fStkCosXX, 2, TWO_FREE, 0 );
  949.          continue;
  950.       }
  951.       if (ftst == dStkTan ) {
  952. #ifdef TESTFP
  953.          stopmsg(0, "tan,2,TWO_FREE,0" );
  954. #endif
  955.          CvtFptr(fStkTan, 2, TWO_FREE, 0 );
  956.          continue;
  957.       }
  958.       if (ftst == dStkTanh ) {
  959. #ifdef TESTFP
  960.          stopmsg(0, "tanh,2,TWO_FREE,0" );
  961. #endif
  962.          CvtFptr(fStkTanh, 2, TWO_FREE, 0 );
  963.          continue;
  964.       }
  965.       if (ftst == dStkCoTan ) {
  966. #ifdef TESTFP
  967.          stopmsg(0, "cotan,2,TWO_FREE,0" );
  968. #endif
  969.          CvtFptr(fStkCoTan, 2, TWO_FREE, 0 );
  970.          continue;
  971.       }
  972.       if (ftst == dStkCoTanh ) {
  973. #ifdef TESTFP
  974.          stopmsg(0, "cotanh,2,TWO_FREE,0" );
  975. #endif
  976.          CvtFptr(fStkCoTanh, 2, TWO_FREE, 0 );
  977.          continue;
  978.       }
  979.       if (ftst == dStkExp ) {
  980. #ifdef TESTFP
  981.          stopmsg(0, "exp,2,TWO_FREE,0" );
  982. #endif
  983.          CvtFptr(fStkExp, 2, TWO_FREE, 0 );
  984.          continue;
  985.       }
  986.       if (ftst == dStkLog ) {
  987. #ifdef TESTFP
  988.          stopmsg(0, "log,2,TWO_FREE,0" );
  989. #endif
  990.          CvtFptr(fStkLog, 2, TWO_FREE, 0 );
  991.          continue;
  992.       }
  993.       if (ftst == dStkPwr ) {
  994. #ifdef TESTFP
  995.          stopmsg(0, "pwr,4,TWO_FREE,-2" );
  996. #endif
  997.          CvtFptr(fStkPwr, 4, TWO_FREE, -2 );
  998.          continue;
  999.       }
  1000.       if (ftst == dStkLT ) {
  1001. #ifdef TESTFP
  1002.          stopmsg(0, "LT,4,MAX_STACK,-2" );
  1003. #endif
  1004.          CvtFptr(fStkLT, 4, MAX_STACK, -2 );
  1005.          continue;
  1006.       }
  1007.       if (ftst == dStkFlip ) {
  1008. #ifdef TESTFP
  1009.          stopmsg(0, "flip,2,MAX_STACK,0" );
  1010. #endif
  1011.          CvtFptr(fStkFlip, 2, MAX_STACK, 0 );
  1012.          continue;
  1013.       }
  1014.       if (ftst == dStkReal ) {
  1015. #ifdef TESTFP
  1016.          stopmsg(0, "real,2,MAX_STACK,0" );
  1017. #endif
  1018.          CvtFptr(fStkReal, 2, MAX_STACK, 0 );
  1019.          continue;
  1020.       }
  1021.       if (ftst == dStkImag ) {
  1022. #ifdef TESTFP
  1023.          stopmsg(0, "imag,2,MAX_STACK,0" );
  1024. #endif
  1025.          CvtFptr(fStkImag, 2, MAX_STACK, 0 );
  1026.          continue;
  1027.       }
  1028.       if (ftst == dStkConj ) {
  1029. #ifdef TESTFP
  1030.          stopmsg(0, "conj,2,MAX_STACK,0" );
  1031. #endif
  1032.          CvtFptr(fStkConj, 2, MAX_STACK, 0 );
  1033.          continue;
  1034.       }
  1035.       if (ftst == dStkNeg ) {
  1036. #ifdef TESTFP
  1037.          stopmsg(0, "neg,2,MAX_STACK,0" );
  1038. #endif
  1039.          CvtFptr(fStkNeg, 2, MAX_STACK, 0 );
  1040.          continue;
  1041.       }
  1042.       if (ftst == dStkAbs ) {
  1043. #ifdef TESTFP
  1044.          stopmsg(0, "abs,2,MAX_STACK,0" );
  1045. #endif
  1046.          CvtFptr(fStkAbs, 2, MAX_STACK, 0 );
  1047.          continue;
  1048.       }
  1049.       if (ftst == dStkRecip ) {
  1050. #ifdef TESTFP
  1051.          stopmsg(0, "recip,2,TWO_FREE,0" );
  1052. #endif
  1053.          CvtFptr(fStkRecip, 2, TWO_FREE, 0 );
  1054.          continue;
  1055.       }
  1056.       if (ftst == StkIdent ) {
  1057. #ifdef TESTFP
  1058.          stopmsg(0, "ident skipped" );
  1059. #endif
  1060.          /* don't bother converting this one */
  1061.          continue;
  1062.       }
  1063.       if (ftst == dStkGT ) {
  1064. #ifdef TESTFP
  1065.          stopmsg(0, "GT,4,MAX_STACK,-2" );
  1066. #endif
  1067.          CvtFptr(fStkGT, 4, MAX_STACK, -2 );
  1068.          continue;
  1069.       }
  1070.       if (ftst == dStkGTE ) {
  1071. #ifdef TESTFP
  1072.          stopmsg(0, "GTE,4,MAX_STACK,-2" );
  1073. #endif
  1074.          CvtFptr(fStkGTE, 4, MAX_STACK, -2 );
  1075.          continue;
  1076.       }
  1077.       if (ftst == dStkEQ ) {
  1078. #ifdef TESTFP
  1079.          stopmsg(0, "EQ,4,MAX_STACK,-2" );
  1080. #endif
  1081.          CvtFptr(fStkEQ, 4, MAX_STACK, -2 );
  1082.          continue;
  1083.       }
  1084.       if (ftst == dStkNE ) {
  1085. #ifdef TESTFP
  1086.          stopmsg(0, "NE,4,MAX_STACK,-2" );
  1087. #endif
  1088.          CvtFptr(fStkNE, 4, MAX_STACK, -2 );
  1089.          continue;
  1090.       }
  1091.       if (ftst == dStkOR ) {
  1092. #ifdef TESTFP
  1093.          stopmsg(0, "OR,4,MAX_STACK,-2" );
  1094. #endif
  1095.          CvtFptr(fStkOR, 4, MAX_STACK, -2 );
  1096.          continue;
  1097.       }
  1098.       if (ftst == dStkAND ) {
  1099. #ifdef TESTFP
  1100.          stopmsg(0, "AND,4,MAX_STACK,-2" );
  1101. #endif
  1102.          CvtFptr(fStkAND, 4, MAX_STACK, -2 );
  1103.          continue;
  1104.       }
  1105.       stopmsg(0, "Fast failure, using old code." );
  1106.       return 1; /* this should never happen but is not fatal now */
  1107.    }
  1108.  
  1109.    if (debugflag == 322 ){
  1110.       /* skip these optimizations too */
  1111.       goto skipfinalopt;
  1112.    } /* ---------------------------------- final optimizations ---- */
  1113.  
  1114.    ntst = fgf(cvtptrx-2 ); /* cvtptrx -> one past last operator (clr2) */
  1115.    if (ntst == fStkLT ){
  1116. #ifdef TESTFP
  1117.       stopmsg (0, "LT Clr2 -> LT2" );
  1118. #endif
  1119.       --cvtptrx;
  1120.       fgf(cvtptrx-1) = fStkLT2;
  1121.    }
  1122.    else if (ntst == fStkLodLT ){
  1123. #ifdef TESTFP
  1124.       stopmsg (0, "LodLT Clr2 -> LodLT2" );
  1125. #endif
  1126.       --cvtptrx;
  1127.       fgf(cvtptrx-1) = fStkLodLT2;
  1128.    }
  1129.    else if (ntst == fStkLTE ){
  1130. #ifdef TESTFP
  1131.       stopmsg (0, "LTE Clr2 -> LTE2" );
  1132. #endif
  1133.       --cvtptrx;
  1134.       fgf(cvtptrx-1) = fStkLTE2;
  1135.    }
  1136.    else if (ntst == fStkLodLTE ){
  1137. #ifdef TESTFP
  1138.       stopmsg (0, "LodLTE Clr2 -> LodLTE2" );
  1139. #endif
  1140.       --cvtptrx;
  1141.       fgf(cvtptrx-1) = fStkLodLTE2;
  1142.    }
  1143.    else if (ntst == fStkGT ){
  1144. #ifdef TESTFP
  1145.       stopmsg (0, "GT Clr2 -> GT2" );
  1146. #endif
  1147.       --cvtptrx;
  1148.       fgf(cvtptrx-1) = fStkGT2;
  1149.    }
  1150.    else if (ntst == fStkLodGT ){
  1151. #ifdef TESTFP
  1152.       stopmsg (0, "LodGT Clr2 -> LodGT2" );
  1153. #endif
  1154.       --cvtptrx;
  1155.       fgf(cvtptrx-1) = fStkLodGT2;
  1156.    }
  1157.    else if (ntst == fStkLodGTE ){
  1158. #ifdef TESTFP
  1159.       stopmsg (0, "LodGTE Clr2 -> LodGTE2" );
  1160. #endif
  1161.       --cvtptrx;
  1162.       fgf(cvtptrx-1) = fStkLodGTE2;
  1163.    }
  1164.    else if (fgf(cvtptrx-2 ) == fStkAND ){
  1165. #ifdef TESTFP
  1166.       stopmsg (0, "AND Clr2 -> ANDClr2" );
  1167. #endif
  1168.       --cvtptrx;
  1169.       fgf(cvtptrx-1) = fStkANDClr2;
  1170.       ntst = fgf(cvtptrx-2);
  1171.       if (ntst == fStkLodLTE ){
  1172. #ifdef TESTFP
  1173.          stopmsg (0, "LodLTE ANDClr2 -> LodLTEAnd2" );
  1174. #endif
  1175.          --cvtptrx;
  1176.          fgf(cvtptrx-1) = fStkLodLTEAnd2;
  1177.       }
  1178.    }
  1179.  
  1180. skipfinalopt: /* ---------------- end of final optimizations ----- */
  1181.  
  1182.    LastOp = cvtptrx; /* save the new operator count */
  1183.    LastSqr.d.y = 0.0; /* do this once per image */
  1184.  
  1185.    /* now change the pointers */
  1186.    if (FormName[0] != 0 ){ /* but only if parse succeeded */
  1187.       curfractalspecific->per_pixel = fform_per_pixel;
  1188.       curfractalspecific->orbitcalc = fFormula;
  1189.    }
  1190.    else {
  1191.       curfractalspecific->per_pixel = BadFormula;
  1192.       curfractalspecific->orbitcalc = BadFormula;
  1193.    }
  1194.    Img_Setup(); /* call assembler setup code */
  1195.    return 1;
  1196. }
  1197.  
  1198. #endif
  1199.