home *** CD-ROM | disk | FTP | other *** search
/ Fractal Creations (Second Edition) / FRACTALS_2E.iso / frasrc.exe / PARSER.C < prev    next >
C/C++ Source or Header  |  1993-07-13  |  56KB  |  2,251 lines

  1. /* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
  2.    All rights reserved.
  3.  
  4.    Code may be used in any program provided the author is credited
  5.     either during program execution or in the documentation.  Source
  6.     code may be distributed only in combination with public domain or
  7.     shareware source code.  Source code may be modified provided the
  8.     copyright notice and this message is left unchanged and all
  9.     modifications are clearly documented.
  10.  
  11.     I would appreciate a copy of any work which incorporates this code,
  12.     however this is optional.
  13.  
  14.     Mark C. Peterson
  15.     405-C Queen St. Suite #181
  16.     Southington, CT 06489
  17.     (203) 276-9721
  18. */
  19.  
  20. /*    Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp'    */
  21. /*   for fast 387 floating-point math.  See PARSERA.ASM and PARSERFP.C */
  22. /*   (13 Dec 1992.)  */
  23. /* */
  24. /*   Modified 12 July 1993 by CAE to fix crash when formula not found.  */
  25.  
  26. #include <string.h>
  27. #include <ctype.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <float.h>                              /* TIW 04-22-91 */
  31. #include <time.h>
  32. #include "mpmath.h"
  33. #include "prototyp.h"
  34.  
  35. extern int CvtStk(void);    /* CAE fp */
  36. extern int Transparent3D;                         /* MCP 5-30-91 */
  37.  
  38. #ifdef WATCH_MP
  39. double x1, y1, x2, y2;
  40. #endif
  41.  
  42. MATH_TYPE MathType = D_MATH;
  43. /* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */
  44.  
  45. /* PB 910417 added MAX_OPS and MAX_ARGS defines */
  46. #define MAX_ARGS 100
  47. #define MAX_OPS 250
  48. struct PEND_OP {
  49.    void (far *f)(void);
  50.    int p;
  51. };
  52. /* CAE fp added MAX_STORES and LOADS */
  53. #define MAX_STORES 125  /* at most only half the ops can be stores */
  54. #define MAX_LOADS  200  /* and 80% can be loads */
  55.  
  56. /* PB 901103 made some of the following static for safety */
  57. static struct PEND_OP far *o;
  58.  
  59. static void parser_allocate(void);
  60.  
  61. union Arg *Arg1, *Arg2;
  62. /* PB 910417 removed unused "a" array */
  63.  
  64. /* CAE fp  made some of the following non-static for PARSERA.ASM */
  65. /* Some of these variables should be renamed for safety */
  66. union Arg s[20], far * far *Store, far * far *Load;    /* static CAE fp */
  67. int StoPtr, LodPtr, OpPtr;    /* static CAE fp */
  68.  
  69. struct fls { /* function, load, store pointers  CAE fp */
  70.    void (near *function)(void);
  71.    union Arg near *operand;
  72. };
  73. extern struct fls far *pfls; /* init in parserfp.c  CAE fp */
  74. void (far * far *f)(void) = (void(far * far *)(void))0;    /* static CAE fp */
  75.  
  76. unsigned vsp, LastOp;    /* CAE fp made non-static */
  77. static unsigned n, ErrPtr, posp, NextOp, InitN;
  78. static int paren, SyntaxErr, ExpectingArg;
  79. struct ConstArg far *v = (struct ConstArg far *)0;    /* was static CAE fp */
  80. int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;    /* was static CAE fp */
  81. static int Delta16;
  82. double fgLimit;           /* TIW 05-04-91 */
  83. static double fg;
  84. static int ShiftBack;     /* TIW 06-18-90 */
  85. static int SetRandom;     /* MCP 11-21-91 */
  86. static int Randomized;
  87. static unsigned long RandNum;
  88.  
  89. extern int bitshift;
  90. extern int bitshiftless1;
  91. extern int symmetry;          /* symmetry flag for calcmand()  */
  92. extern double param[];
  93.  
  94. extern int debugflag;         /* BDT for debugging */
  95. extern char boxx[8192];       /* PB 4-9-91, good place for the formula string */
  96. extern int row, col, overflow, cpu, fpu;
  97. extern _CMPLX old, new;
  98. extern double far *dx0, far *dy0;
  99. extern long far *lx0, far *ly0;     /* BDT moved these to FAR */
  100.  
  101. #ifndef TESTING_MATH
  102. extern double far *dx1, far *dy1;
  103. extern long far *lx1, far *ly1;
  104. #define dShiftx dx1[row]
  105. #define dShifty dy1[col]
  106. #define lShiftx lx1[row]
  107. #define lShifty ly1[col]
  108. #else
  109. #define dShiftx 0.0
  110. #define dShifty 0.0
  111. #define lShiftx 0L
  112. #define lShifty 0L
  113. #endif
  114.  
  115. extern _LCMPLX lold, lnew;
  116. extern char FormName[];
  117.  
  118. extern VOIDFARPTR typespecific_workarea;
  119.  
  120. #define LastSqr v[4].a
  121.  
  122. static char far * far ErrStrings[] = {   /* TIW 03-31-91 added far */
  123.    "Should be an Argument",
  124.    "Should be an Operator",
  125.    "')' needs a matching '('",
  126.    "Need more ')'",
  127.    "Undefined Operator",
  128.    "Undefined Function",
  129.    "More than one ','",
  130.    "Table overflow"
  131. };
  132.  
  133. unsigned SkipWhiteSpace(char *Str) {
  134.    unsigned n, Done;
  135.  
  136.    for(Done = n = 0; !Done; n++) {
  137.       switch(Str[n]) {
  138.       case ' ':
  139.       case '\t':
  140.       case '\n':
  141.       case '\r':
  142.          break;
  143.       default:
  144.          Done = 1;
  145.       }
  146.    }
  147.    return(n - 1);
  148. }
  149.  
  150. /* Random number code, MCP 11-21-91 */
  151.  
  152. unsigned long NewRandNum(void)
  153. {
  154.    return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
  155. }
  156.  
  157. void lRandom(void)
  158. {
  159.    v[7].a.l.x = NewRandNum() >> (32 - bitshift);
  160.    v[7].a.l.y = NewRandNum() >> (32 - bitshift);
  161. }
  162.  
  163. void dRandom(void)
  164. {
  165.    long x, y;
  166.  
  167.    /* Use the same algorithm as for fixed math so that they will generate
  168.       the same fractals when the srand() function is used. */
  169.    x = NewRandNum() >> (32 - bitshift);
  170.    y = NewRandNum() >> (32 - bitshift);
  171.    v[7].a.d.x = ((double)x / (1L << bitshift));
  172.    v[7].a.d.y = ((double)y / (1L << bitshift));
  173. }
  174.  
  175. #ifndef XFRACT
  176. void mRandom(void)
  177. {
  178.    long x, y;
  179.  
  180.    /* Use the same algorithm as for fixed math so that they will generate
  181.       the same fractals when the srand() function is used. */
  182.    x = NewRandNum() >> (32 - bitshift);
  183.    y = NewRandNum() >> (32 - bitshift);
  184.    v[7].a.m.x = *fg2MP(x, bitshift);
  185.    v[7].a.m.y = *fg2MP(y, bitshift);
  186. }
  187. #endif
  188.  
  189. void SetRandFnct(void)
  190. {
  191.    unsigned Seed;
  192.  
  193.    if(!SetRandom)
  194.       RandNum = Arg1->l.x ^ Arg1->l.y;
  195.  
  196.    Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
  197.    srand(Seed);
  198.    SetRandom = 1;
  199.  
  200.    /* Clear out the seed */
  201.    NewRandNum();
  202.    NewRandNum();
  203.    NewRandNum();
  204. }
  205.  
  206. void RandomSeed(void)
  207. {
  208.    time_t ltime;
  209.  
  210.    /* Use the current time to randomize the random number sequence. */
  211.    time(<ime);
  212.    srand((unsigned int)ltime);
  213.  
  214.    NewRandNum();
  215.    NewRandNum();
  216.    NewRandNum();
  217.    Randomized = 1;
  218. }
  219.  
  220. #ifndef XFRACT
  221. void lStkSRand(void)
  222. {
  223.    SetRandFnct();
  224.    lRandom();
  225.    Arg1->l = v[7].a.l;
  226. }
  227. #endif
  228.  
  229. #ifndef XFRACT
  230. void mStkSRand(void)
  231. {
  232.    Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
  233.    Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
  234.    SetRandFnct();
  235.    mRandom();
  236.    Arg1->m = v[7].a.m;
  237. }
  238. #endif
  239.  
  240. void dStkSRand(void)
  241. {
  242.    Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
  243.    Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
  244.    SetRandFnct();
  245.    dRandom();
  246.    Arg1->d = v[7].a.d;
  247. }
  248.  
  249. void (*StkSRand)(void) = dStkSRand;
  250.  
  251. void dStkAbs(void) {
  252.    Arg1->d.x = fabs(Arg1->d.x);
  253.    Arg1->d.y = fabs(Arg1->d.y);
  254. }
  255.  
  256. #ifndef XFRACT
  257. void mStkAbs(void) {
  258.    if(Arg1->m.x.Exp < 0)
  259.       Arg1->m.x.Exp = -Arg1->m.x.Exp;
  260.    if(Arg1->m.y.Exp < 0)
  261.       Arg1->m.y.Exp = -Arg1->m.y.Exp;
  262. }
  263.  
  264. void lStkAbs(void) {
  265.    Arg1->l.x = labs(Arg1->l.x);
  266.    Arg1->l.y = labs(Arg1->l.y);
  267. }
  268. #endif
  269.  
  270. void (*StkAbs)(void) = dStkAbs;
  271.  
  272. void dStkSqr(void) {
  273.    LastSqr.d.x = Arg1->d.x * Arg1->d.x;
  274.    LastSqr.d.y = Arg1->d.y * Arg1->d.y;
  275.    Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
  276.    Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
  277.    LastSqr.d.x += LastSqr.d.y;
  278.    LastSqr.d.y = 0;
  279. }
  280.  
  281. #ifndef XFRACT
  282. void mStkSqr(void) {
  283.    LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
  284.    LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
  285.    Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
  286.    Arg1->m.y.Exp++;
  287.    Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
  288.    LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
  289.    LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
  290. }
  291.  
  292. void lStkSqr(void) {
  293.    LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
  294.    LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
  295.    Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
  296.    Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
  297.    LastSqr.l.x += LastSqr.l.y;
  298.    LastSqr.l.y = 0L;
  299. }
  300. #endif
  301.  
  302. void (*StkSqr)(void) = dStkSqr;
  303.  
  304. void dStkAdd(void) {
  305.    Arg2->d.x += Arg1->d.x;
  306.    Arg2->d.y += Arg1->d.y;
  307.    Arg1--;
  308.    Arg2--;
  309. }
  310.  
  311. #ifndef XFRACT
  312. void mStkAdd(void) {
  313.    Arg2->m = MPCadd(Arg2->m, Arg1->m);
  314.    Arg1--;
  315.    Arg2--;
  316. }
  317.  
  318. void lStkAdd(void) {
  319.    Arg2->l.x += Arg1->l.x;
  320.    Arg2->l.y += Arg1->l.y;
  321.    Arg1--;
  322.    Arg2--;
  323. }
  324. #endif
  325.  
  326. void (*StkAdd)(void) = dStkAdd;
  327.  
  328. void dStkSub(void) {
  329.    Arg2->d.x -= Arg1->d.x;
  330.    Arg2->d.y -= Arg1->d.y;
  331.    Arg1--;
  332.    Arg2--;
  333. }
  334.  
  335. #ifndef XFRACT
  336. void mStkSub(void) {
  337.    Arg2->m = MPCsub(Arg2->m, Arg1->m);
  338.    Arg1--;
  339.    Arg2--;
  340. }
  341.  
  342. void lStkSub(void) {
  343.    Arg2->l.x -= Arg1->l.x;
  344.    Arg2->l.y -= Arg1->l.y;
  345.    Arg1--;
  346.    Arg2--;
  347. }
  348. #endif
  349.  
  350. void (*StkSub)(void) = dStkSub;
  351.  
  352. void dStkConj(void) {
  353.    Arg1->d.y = -Arg1->d.y;
  354. }
  355.  
  356. #ifndef XFRACT
  357. void mStkConj(void) {
  358.    Arg1->m.y.Exp ^= 0x8000;
  359. }
  360.  
  361. void lStkConj(void) {
  362.    Arg1->l.y = -Arg1->l.y;
  363. }
  364. #endif
  365.  
  366. void dStkZero(void) {
  367.    Arg1->d.y = Arg1->d.x = 0.0;
  368. }
  369.  
  370. #ifndef XFRACT
  371. void mStkZero(void) {
  372.    Arg1->m.x.Mant = Arg1->m.x.Exp = 0;
  373.    Arg1->m.y.Mant = Arg1->m.y.Exp = 0;
  374. }
  375.  
  376. void lStkZero(void) {
  377.    Arg1->l.y = Arg1->l.x = 0.0;
  378. }
  379. #endif
  380.  
  381. void (*StkConj)(void) = dStkConj;
  382.  
  383. void dStkReal(void) {
  384.    Arg1->d.y = 0.0;
  385. }
  386.  
  387. #ifndef XFRACT
  388. void mStkReal(void) {
  389.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  390. }
  391.  
  392. void lStkReal(void) {
  393.    Arg1->l.y = 0l;
  394. }
  395. #endif
  396.  
  397. void (*StkReal)(void) = dStkReal;
  398.  
  399. void dStkImag(void) {
  400.    Arg1->d.x = Arg1->d.y;
  401.    Arg1->d.y = 0.0;
  402. }
  403.  
  404. #ifndef XFRACT
  405. void mStkImag(void) {
  406.    Arg1->m.x = Arg1->m.y;
  407.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  408. }
  409.  
  410. void lStkImag(void) {
  411.    Arg1->l.x = Arg1->l.y;
  412.    Arg1->l.y = 0l;
  413. }
  414. #endif
  415.  
  416. void (*StkImag)(void) = dStkImag;
  417.  
  418. void dStkNeg(void) {
  419.    Arg1->d.x = -Arg1->d.x;
  420.    Arg1->d.y = -Arg1->d.y;
  421. }
  422.  
  423. #ifndef XFRACT
  424. void mStkNeg(void) {
  425.    Arg1->m.x.Exp ^= 0x8000;
  426.    Arg1->m.y.Exp ^= 0x8000;
  427. }
  428.  
  429. void lStkNeg(void) {
  430.    Arg1->l.x = -Arg1->l.x;
  431.    Arg1->l.y = -Arg1->l.y;
  432. }
  433. #endif
  434.  
  435. void (*StkNeg)(void) = dStkNeg;
  436.  
  437. void dStkMul(void) {
  438.    FPUcplxmul(&Arg2->d, &Arg1->d, &Arg2->d);
  439.    Arg1--;
  440.    Arg2--;
  441. }
  442.  
  443. #ifndef XFRACT
  444. void mStkMul(void) {
  445.    Arg2->m = MPCmul(Arg2->m, Arg1->m);
  446.    Arg1--;
  447.    Arg2--;
  448. }
  449.  
  450. void lStkMul(void) {
  451.    long x, y;
  452.  
  453.    x = multiply(Arg2->l.x, Arg1->l.x, bitshift) -
  454.    multiply(Arg2->l.y, Arg1->l.y, bitshift);
  455.    y = multiply(Arg2->l.y, Arg1->l.x, bitshift) +
  456.    multiply(Arg2->l.x, Arg1->l.y, bitshift);
  457.    Arg2->l.x = x;
  458.    Arg2->l.y = y;
  459.    Arg1--;
  460.    Arg2--;
  461. }
  462. #endif
  463.  
  464. void (*StkMul)(void) = dStkMul;
  465.  
  466. void dStkDiv(void) {
  467.    FPUcplxdiv(&Arg2->d, &Arg1->d, &Arg2->d);
  468.    Arg1--;
  469.    Arg2--;
  470. }
  471.  
  472. #ifndef XFRACT
  473. void mStkDiv(void) {
  474.    Arg2->m = MPCdiv(Arg2->m, Arg1->m);
  475.    Arg1--;
  476.    Arg2--;
  477. }
  478.  
  479. void lStkDiv(void) {
  480.    long x, y, mod, x2, y2;
  481.  
  482.    mod = multiply(Arg1->l.x, Arg1->l.x, bitshift) +
  483.    multiply(Arg1->l.y, Arg1->l.y, bitshift);
  484.    x = divide(Arg1->l.x, mod, bitshift);
  485.    y = -divide(Arg1->l.y, mod, bitshift);
  486.    /* pb 900617 changed next 4 lines to use x2,y2 instead of x,y */
  487.    x2 = multiply(Arg2->l.x, x, bitshift) - multiply(Arg2->l.y, y, bitshift);
  488.    y2 = multiply(Arg2->l.y, x, bitshift) + multiply(Arg2->l.x, y, bitshift);
  489.    Arg2->l.x = x2;
  490.    Arg2->l.y = y2;
  491.    Arg1--;
  492.    Arg2--;
  493. }
  494. #endif
  495.  
  496. void (*StkDiv)(void) = dStkDiv;
  497.  
  498. void StkSto(void) {
  499.    *Store[StoPtr++] = *Arg1;
  500. }
  501.  
  502. void StkLod(void) {
  503.    Arg1++;
  504.    Arg2++;
  505.    *Arg1 = *Load[LodPtr++];
  506. }
  507.  
  508. void dStkMod(void) {
  509.    Arg1->d.x = (Arg1->d.x * Arg1->d.x) + (Arg1->d.y * Arg1->d.y);
  510.    Arg1->d.y = 0.0;
  511. }
  512.  
  513. #ifndef XFRACT
  514. void mStkMod(void) {
  515.    Arg1->m.x = MPCmod(Arg1->m);
  516.    Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0);
  517. }
  518.  
  519. void lStkMod(void) {
  520.    Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) +
  521.    multiply(Arg2->l.y, Arg1->l.y, bitshift);
  522.    if(Arg1->l.x < 0)
  523.       overflow = 1;
  524.    Arg1->l.y = 0L;
  525. }
  526. #endif
  527.  
  528. void (*StkMod)(void) = dStkMod;
  529.  
  530. void StkClr(void) {
  531.    s[0] = *Arg1;
  532.    Arg1 = &s[0];
  533.    Arg2 = Arg1;
  534.    Arg2--;
  535. }
  536.  
  537.  
  538. /* MCP 4-9-91, Added Flip() */
  539.  
  540. void dStkFlip(void) {
  541.    double t;
  542.  
  543.    t = Arg1->d.x;
  544.    Arg1->d.x = Arg1->d.y;
  545.    Arg1->d.y = t;
  546. }
  547.  
  548. #ifndef XFRACT
  549. void mStkFlip(void) {
  550.    struct MP t;
  551.  
  552.    t = Arg1->m.x;
  553.    Arg1->m.x = Arg1->m.y;
  554.    Arg1->m.y = t;
  555. }
  556.  
  557. void lStkFlip(void) {
  558.    long t;
  559.  
  560.    t = Arg1->l.x;
  561.    Arg1->l.x = Arg1->l.y;
  562.    Arg1->l.y = t;
  563. }
  564. #endif
  565.  
  566. void (*StkFlip)(void) = dStkFlip;
  567.  
  568. void dStkSin(void) {
  569.    double sinx, cosx, sinhy, coshy;
  570.  
  571.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  572.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  573.    Arg1->d.x = sinx*coshy;
  574.    Arg1->d.y = cosx*sinhy;
  575. }
  576.  
  577. #ifndef XFRACT
  578. void mStkSin(void) {
  579.    Arg1->d = MPC2cmplx(Arg1->m);
  580.    dStkSin();
  581.    Arg1->m = cmplx2MPC(Arg1->d);
  582. }
  583.  
  584. void lStkSin(void) {
  585.    long x, y, sinx, cosx, sinhy, coshy;
  586.    x = Arg1->l.x >> Delta16;
  587.    y = Arg1->l.y >> Delta16;
  588.    SinCos086(x, &sinx, &cosx);
  589.    SinhCosh086(y, &sinhy, &coshy);
  590.    Arg1->l.x = multiply(sinx, coshy, ShiftBack); /* TIW 06-18-90 */
  591.    Arg1->l.y = multiply(cosx, sinhy, ShiftBack); /* TIW 06-18-90 */
  592. }
  593. #endif
  594.  
  595. void (*StkSin)(void) = dStkSin;
  596.  
  597. /* The following functions are supported by both the parser and for fn
  598.    variable replacement. TIW 04-22-91 */
  599.  
  600. void dStkTan(void) {
  601.    double sinx, cosx, sinhy, coshy, denom;
  602.    Arg1->d.x *= 2;
  603.    Arg1->d.y *= 2;
  604.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  605.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  606.    denom = cosx + coshy;
  607.    if(fabs(denom) <= DBL_MIN) return;
  608.    Arg1->d.x = sinx/denom;
  609.    Arg1->d.y = sinhy/denom;
  610. }
  611.  
  612. #ifndef XFRACT
  613. void mStkTan(void) {
  614.    Arg1->d = MPC2cmplx(Arg1->m);
  615.    dStkTan();
  616.    Arg1->m = cmplx2MPC(Arg1->d);
  617. }
  618.  
  619. void lStkTan(void) {
  620.    long x, y, sinx, cosx, sinhy, coshy, denom;
  621.    x = Arg1->l.x >> Delta16;
  622.    x = x << 1;
  623.    y = Arg1->l.y >> Delta16;
  624.    y = y << 1;
  625.    SinCos086(x, &sinx, &cosx);
  626.    SinhCosh086(y, &sinhy, &coshy);
  627.    denom = cosx + coshy;
  628.    if(denom == 0) return;
  629.    Arg1->l.x = divide(sinx,denom,bitshift);
  630.    Arg1->l.y = divide(sinhy,denom,bitshift);
  631. }
  632. #endif
  633.  
  634. void (*StkTan)(void) = dStkTan;
  635.  
  636. void dStkTanh(void) {
  637.    double siny, cosy, sinhx, coshx, denom;
  638.    Arg1->d.x *= 2;
  639.    Arg1->d.y *= 2;
  640.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  641.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  642.    denom = coshx + cosy;
  643.    if(fabs(denom) <= DBL_MIN) return;
  644.    Arg1->d.x = sinhx/denom;
  645.    Arg1->d.y = siny/denom;
  646. }
  647.  
  648. #ifndef XFRACT
  649. void mStkTanh(void) {
  650.    Arg1->d = MPC2cmplx(Arg1->m);
  651.    dStkTanh();
  652.    Arg1->m = cmplx2MPC(Arg1->d);
  653. }
  654.  
  655. void lStkTanh(void) {
  656.    long x, y, siny, cosy, sinhx, coshx, denom;
  657.    x = Arg1->l.x >> Delta16;
  658.    x = x << 1;
  659.    y = Arg1->l.y >> Delta16;
  660.    y = y << 1;
  661.    SinCos086(y, &siny, &cosy);
  662.    SinhCosh086(x, &sinhx, &coshx);
  663.    denom = coshx + cosy;
  664.    if(denom == 0) return;
  665.    Arg1->l.x = divide(sinhx,denom,bitshift);
  666.    Arg1->l.y = divide(siny,denom,bitshift);
  667. }
  668. #endif
  669.  
  670. void (*StkTanh)(void) = dStkTanh;
  671.  
  672. void dStkCoTan(void) {
  673.    double sinx, cosx, sinhy, coshy, denom;
  674.    Arg1->d.x *= 2;
  675.    Arg1->d.y *= 2;
  676.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  677.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  678.    denom = coshy - cosx;
  679.    if(fabs(denom) <= DBL_MIN) return;
  680.    Arg1->d.x = sinx/denom;
  681.    Arg1->d.y = -sinhy/denom;
  682. }
  683.  
  684. #ifndef XFRACT
  685. void mStkCoTan(void) {
  686.    Arg1->d = MPC2cmplx(Arg1->m);
  687.    dStkCoTan();
  688.    Arg1->m = cmplx2MPC(Arg1->d);
  689. }
  690.  
  691. void lStkCoTan(void) {
  692.    long x, y, sinx, cosx, sinhy, coshy, denom;
  693.    x = Arg1->l.x >> Delta16;
  694.    x = x << 1;
  695.    y = Arg1->l.y >> Delta16;
  696.    y = y << 1;
  697.    SinCos086(x, &sinx, &cosx);
  698.    SinhCosh086(y, &sinhy, &coshy);
  699.    denom = coshy - cosx;
  700.    if(denom == 0) return;
  701.    Arg1->l.x = divide(sinx,denom,bitshift);
  702.    Arg1->l.y = -divide(sinhy,denom,bitshift);
  703. }
  704. #endif
  705.  
  706. void (*StkCoTan)(void) = dStkCoTan;
  707.  
  708. void dStkCoTanh(void) {
  709.    double siny, cosy, sinhx, coshx, denom;
  710.    Arg1->d.x *= 2;
  711.    Arg1->d.y *= 2;
  712.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  713.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  714.    denom = coshx - cosy;
  715.    if(fabs(denom) <= DBL_MIN) return;
  716.    Arg1->d.x = sinhx/denom;
  717.    Arg1->d.y = -siny/denom;
  718. }
  719.  
  720. #ifndef XFRACT
  721. void mStkCoTanh(void) {
  722.    Arg1->d = MPC2cmplx(Arg1->m);
  723.    dStkCoTanh();
  724.    Arg1->m = cmplx2MPC(Arg1->d);
  725. }
  726.  
  727. void lStkCoTanh(void) {
  728.    long x, y, siny, cosy, sinhx, coshx, denom;
  729.    x = Arg1->l.x >> Delta16;
  730.    x = x << 1;
  731.    y = Arg1->l.y >> Delta16;
  732.    y = y << 1;
  733.    SinCos086(y, &siny, &cosy);
  734.    SinhCosh086(x, &sinhx, &coshx);
  735.    denom = coshx - cosy;
  736.    if(denom == 0) return;
  737.    Arg1->l.x = divide(sinhx,denom,bitshift);
  738.    Arg1->l.y = -divide(siny,denom,bitshift);
  739. }
  740. #endif
  741.  
  742. void (*StkCoTanh)(void) = dStkCoTanh;
  743.  
  744. /* The following functions are not directly used by the parser - support
  745.    for the parser was not provided because the existing parser language
  746.    represents these quite easily. They are used for fn variable support
  747.    in miscres.c but are placed here because they follow the pattern of
  748.    the other parser functions. TIW 04-22-91 */
  749.  
  750. void dStkRecip(void) {
  751.    double mod;
  752.    mod =Arg1->d.x * Arg1->d.x + Arg1->d.y * Arg1->d.y;
  753.    if(mod <= DBL_MIN) return;
  754.    Arg1->d.x =  Arg1->d.x/mod;
  755.    Arg1->d.y = -Arg1->d.y/mod;
  756. }
  757.  
  758. #ifndef XFRACT
  759. void mStkRecip(void) {
  760.    struct MP mod;
  761.    mod = *MPadd(*MPmul(Arg1->m.x, Arg1->m.x),*MPmul(Arg1->m.y, Arg1->m.y));
  762.    if(mod.Mant <= 0L) return;
  763.    Arg1->m.x = *MPdiv(Arg1->m.x,mod);
  764.    Arg1->m.y = *MPdiv(Arg1->m.y,mod);
  765.    Arg1->m.y.Exp ^= 0x8000;
  766. }
  767.  
  768. void lStkRecip(void) {
  769.    long mod;
  770.    mod = multiply(Arg1->l.x,Arg1->l.x,bitshift)
  771.       + multiply(Arg1->l.y,Arg1->l.y,bitshift);
  772.    if(mod<=0L) return;
  773.    Arg1->l.x =  divide(Arg1->l.x,mod,bitshift);
  774.    Arg1->l.y = -divide(Arg1->l.y,mod,bitshift);
  775. }
  776. #endif
  777.  
  778. void StkIdent(void) { /* do nothing - the function Z */
  779. }
  780. /* End TIW 04-22-91 */
  781.  
  782. void dStkSinh(void) {
  783.    double siny, cosy, sinhx, coshx;
  784.  
  785.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  786.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  787.    Arg1->d.x = sinhx*cosy;
  788.    Arg1->d.y = coshx*siny;
  789. }
  790.  
  791. #ifndef XFRACT
  792. void mStkSinh(void) {
  793.    Arg1->d = MPC2cmplx(Arg1->m);
  794.    dStkSinh();
  795.    Arg1->m = cmplx2MPC(Arg1->d);
  796. }
  797.  
  798. void lStkSinh(void) {
  799.    long x, y, sinhx, coshx, siny, cosy;
  800.  
  801.    x = Arg1->l.x >> Delta16;
  802.    y = Arg1->l.y >> Delta16;
  803.    SinCos086(y, &siny, &cosy);
  804.    SinhCosh086(x, &sinhx, &coshx);
  805.    Arg1->l.x = multiply(cosy, sinhx, ShiftBack); /* TIW 06-18-90 */
  806.    Arg1->l.y = multiply(siny, coshx, ShiftBack); /* TIW 06-18-90 */
  807. }
  808. #endif
  809.  
  810. void (*StkSinh)(void) = dStkSinh;
  811.  
  812. void dStkCos(void) {
  813.    double sinx, cosx, sinhy, coshy;
  814.  
  815.    FPUsincos(&Arg1->d.x, &sinx, &cosx);
  816.    FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy);
  817.    Arg1->d.x = cosx*coshy;
  818.    Arg1->d.y = -sinx*sinhy; /* TIW 04-25-91 sign */
  819. }
  820.  
  821. #ifndef XFRACT
  822. void mStkCos(void) {
  823.    Arg1->d = MPC2cmplx(Arg1->m);
  824.    dStkCos();
  825.    Arg1->m = cmplx2MPC(Arg1->d);
  826. }
  827.  
  828. void lStkCos(void) {
  829.    long x, y, sinx, cosx, sinhy, coshy;
  830.  
  831.    x = Arg1->l.x >> Delta16;
  832.    y = Arg1->l.y >> Delta16;
  833.    SinCos086(x, &sinx, &cosx);
  834.    SinhCosh086(y, &sinhy, &coshy);
  835.    Arg1->l.x = multiply(cosx, coshy, ShiftBack); /* TIW 06-18-90 */
  836.    Arg1->l.y = -multiply(sinx, sinhy, ShiftBack); /* TIW 04-25-91 sign */
  837. }
  838. #endif
  839.  
  840. void (*StkCos)(void) = dStkCos;
  841.  
  842. /* Bogus version of cos, to replicate bug which was in regular cos till v16: */
  843.  
  844. void dStkCosXX(void) {
  845.    dStkCos();
  846.    Arg1->d.y = -Arg1->d.y;
  847. }
  848.  
  849. #ifndef XFRACT
  850. void mStkCosXX(void) {
  851.    Arg1->d = MPC2cmplx(Arg1->m);
  852.    dStkCosXX();
  853.    Arg1->m = cmplx2MPC(Arg1->d);
  854. }
  855.  
  856. void lStkCosXX(void) {
  857.    lStkCos();
  858.    Arg1->l.y = -Arg1->l.y;
  859. }
  860. #endif
  861.  
  862. void (*StkCosXX)(void) = dStkCosXX;
  863.  
  864. void dStkCosh(void) {
  865.    double siny, cosy, sinhx, coshx;
  866.  
  867.    FPUsincos(&Arg1->d.y, &siny, &cosy);
  868.    FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx);
  869.    Arg1->d.x = coshx*cosy;
  870.    Arg1->d.y = sinhx*siny;
  871. }
  872.  
  873. #ifndef XFRACT
  874. void mStkCosh(void) {
  875.    Arg1->d = MPC2cmplx(Arg1->m);
  876.    dStkCosh();
  877.    Arg1->m = cmplx2MPC(Arg1->d);
  878. }
  879.  
  880. void lStkCosh(void) {
  881.    long x, y, sinhx, coshx, siny, cosy;
  882.  
  883.    x = Arg1->l.x >> Delta16;
  884.    y = Arg1->l.y >> Delta16;
  885.    SinCos086(y, &siny, &cosy);
  886.    SinhCosh086(x, &sinhx, &coshx);
  887.    Arg1->l.x = multiply(cosy, coshx, ShiftBack); /* TIW 06-18-90 */
  888.    Arg1->l.y = multiply(siny, sinhx, ShiftBack); /* TIW 06-18-90 */
  889. }
  890. #endif
  891.  
  892. void (*StkCosh)(void) = dStkCosh;
  893.  
  894. void dStkLT(void) {
  895.    Arg2->d.x = (double)(Arg2->d.x < Arg1->d.x);
  896.    Arg2->d.y = 0.0;
  897.    Arg1--;
  898.    Arg2--;
  899. }
  900.  
  901. #ifndef XFRACT
  902. void mStkLT(void) {
  903.    Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == -1), 0);
  904.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  905.    Arg1--;
  906.    Arg2--;
  907. }
  908.  
  909. void lStkLT(void) {
  910.    Arg2->l.x = Arg2->l.x < Arg1->l.x;
  911.    Arg2->l.y = 0l;
  912.    Arg1--;
  913.    Arg2--;
  914. }
  915. #endif
  916.  
  917. void (*StkLT)(void) = dStkLT;
  918.  
  919. void dStkGT(void) {
  920.    Arg2->d.x = (double)(Arg2->d.x > Arg1->d.x);
  921.    Arg2->d.y = 0.0;
  922.    Arg1--;
  923.    Arg2--;
  924. }
  925.  
  926. #ifndef XFRACT
  927. void mStkGT(void) {
  928.    Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == 1), 0);
  929.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  930.    Arg1--;
  931.    Arg2--;
  932. }
  933.  
  934. void lStkGT(void) {
  935.    Arg2->l.x = Arg2->l.x > Arg1->l.x;
  936.    Arg2->l.y = 0l;
  937.    Arg1--;
  938.    Arg2--;
  939. }
  940. #endif
  941.  
  942. void (*StkGT)(void) = dStkGT;
  943.  
  944. void dStkLTE(void) {
  945.    Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x);
  946.    Arg2->d.y = 0.0;
  947.    Arg1--;
  948.    Arg2--;
  949. }
  950.  
  951. #ifndef XFRACT
  952. void mStkLTE(void) {
  953.    int comp;
  954.  
  955.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  956.    Arg2->m.x = *fg2MP((long)(comp == -1 || comp == 0), 0);
  957.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  958.    Arg1--;
  959.    Arg2--;
  960. }
  961.  
  962. void lStkLTE(void) {
  963.    Arg2->l.x = Arg2->l.x <= Arg1->l.x;
  964.    Arg2->l.y = 0l;
  965.    Arg1--;
  966.    Arg2--;
  967. }
  968. #endif
  969.  
  970. void (*StkLTE)(void) = dStkLTE;
  971.  
  972. void dStkGTE(void) {
  973.    Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x);
  974.    Arg2->d.y = 0.0;
  975.    Arg1--;
  976.    Arg2--;
  977. }
  978.  
  979. #ifndef XFRACT
  980. void mStkGTE(void) {
  981.    int comp;
  982.  
  983.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  984.    Arg2->m.x = *fg2MP((long)(comp == 1 || comp == 0), 0);
  985.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  986.    Arg1--;
  987.    Arg2--;
  988. }
  989.  
  990. void lStkGTE(void) {
  991.    Arg2->l.x = Arg2->l.x >= Arg1->l.x;
  992.    Arg2->l.y = 0l;
  993.    Arg1--;
  994.    Arg2--;
  995. }
  996. #endif
  997.  
  998. void (*StkGTE)(void) = dStkGTE;
  999.  
  1000. void dStkEQ(void) {
  1001.    Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x);
  1002.    Arg2->d.y = 0.0;
  1003.    Arg1--;
  1004.    Arg2--;
  1005. }
  1006.  
  1007. #ifndef XFRACT
  1008. void mStkEQ(void) {
  1009.    int comp;
  1010.  
  1011.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1012.    Arg2->m.x = *fg2MP((long)(comp == 0), 0);
  1013.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1014.    Arg1--;
  1015.    Arg2--;
  1016. }
  1017.  
  1018. void lStkEQ(void) {
  1019.    Arg2->l.x = Arg2->l.x == Arg1->l.x;
  1020.    Arg2->l.y = 0l;
  1021.    Arg1--;
  1022.    Arg2--;
  1023. }
  1024. #endif
  1025.  
  1026. void (*StkEQ)(void) = dStkEQ;
  1027.  
  1028. void dStkNE(void) {
  1029.    Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x);
  1030.    Arg2->d.y = 0.0;
  1031.    Arg1--;
  1032.    Arg2--;
  1033. }
  1034.  
  1035. #ifndef XFRACT
  1036. void mStkNE(void) {
  1037.    int comp;
  1038.  
  1039.    comp = MPcmp(Arg2->m.x, Arg1->m.x);
  1040.    Arg2->m.x = *fg2MP((long)(comp != 0), 0);
  1041.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1042.    Arg1--;
  1043.    Arg2--;
  1044. }
  1045.  
  1046. void lStkNE(void) {
  1047.    Arg2->l.x = Arg2->l.x != Arg1->l.x;
  1048.    Arg2->l.y = 0l;
  1049.    Arg1--;
  1050.    Arg2--;
  1051. }
  1052. #endif
  1053.  
  1054. void (*StkNE)(void) = dStkNE;
  1055.  
  1056. void dStkOR(void) {
  1057.    Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x);
  1058.    Arg2->d.y = 0.0;
  1059.    Arg1--;
  1060.    Arg2--;
  1061. }
  1062.  
  1063. #ifndef XFRACT
  1064. void mStkOR(void) {
  1065.    Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant || Arg1->m.x.Mant), 0);
  1066.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1067.    Arg1--;
  1068.    Arg2--;
  1069. }
  1070.  
  1071. void lStkOR(void) {
  1072.    Arg2->l.x = Arg2->l.x || Arg1->l.x;
  1073.    Arg2->l.y = 0l;
  1074.    Arg1--;
  1075.    Arg2--;
  1076. }
  1077. #endif
  1078.  
  1079. void (*StkOR)(void) = dStkOR;
  1080.  
  1081. void dStkAND(void) {
  1082.    Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x);
  1083.    Arg2->d.y = 0.0;
  1084.    Arg1--;
  1085.    Arg2--;
  1086. }
  1087.  
  1088. #ifndef XFRACT
  1089. void mStkAND(void) {
  1090.    Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant && Arg1->m.x.Mant), 0);
  1091.    Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0);
  1092.    Arg1--;
  1093.    Arg2--;
  1094. }
  1095.  
  1096. void lStkAND(void) {
  1097.    Arg2->l.x = Arg2->l.x && Arg1->l.x;
  1098.    Arg2->l.y = 0l;
  1099.    Arg1--;
  1100.    Arg2--;
  1101. }
  1102. #endif
  1103.  
  1104. void (*StkAND)(void) = dStkAND;
  1105.  
  1106. void dStkLog(void) {
  1107.    FPUcplxlog(&Arg1->d, &Arg1->d);
  1108. }
  1109.  
  1110. #ifndef XFRACT
  1111. void mStkLog(void) {
  1112.    Arg1->d = MPC2cmplx(Arg1->m);
  1113.    dStkLog();
  1114.    Arg1->m = cmplx2MPC(Arg1->d);
  1115. }
  1116.  
  1117. void lStkLog(void) {
  1118.    _CMPLX x;
  1119.  
  1120.    x.x = (double)Arg1->l.x / fg;
  1121.    x.y = (double)Arg1->l.y / fg;
  1122.    FPUcplxlog(&x, &x);
  1123.    if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  1124.       Arg1->l.x = (long)(x.x * fg);
  1125.       Arg1->l.y = (long)(x.y * fg);
  1126.    }
  1127.    else
  1128.       overflow = 1;
  1129. }
  1130. #endif
  1131.  
  1132. void (*StkLog)(void) = dStkLog;
  1133.  
  1134. void FPUcplxexp(_CMPLX *x, _CMPLX *z) {
  1135.    double e2x, siny, cosy;
  1136.  
  1137.    if(fpu == 387)
  1138.       FPUcplxexp387(x, z);
  1139.    else {
  1140.       e2x = exp(x->x);
  1141.       FPUsincos(&x->y, &siny, &cosy);
  1142.       z->x = e2x * cosy;
  1143.       z->y = e2x * siny;
  1144.    }
  1145. }
  1146.  
  1147.    void dStkExp(void) {
  1148.       FPUcplxexp(&Arg1->d, &Arg1->d);
  1149.    }
  1150.  
  1151. #ifndef XFRACT
  1152. void mStkExp(void) {
  1153.    Arg1->d = MPC2cmplx(Arg1->m);
  1154.    FPUcplxexp(&Arg1->d, &Arg1->d);
  1155.    Arg1->m = cmplx2MPC(Arg1->d);
  1156. }
  1157.  
  1158. void lStkExp(void) {
  1159.    _CMPLX x;
  1160.  
  1161.    x.x = (double)Arg1->l.x / fg;
  1162.    x.y = (double)Arg1->l.y / fg;
  1163.    FPUcplxexp(&x, &x);
  1164.    if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  1165.       Arg1->l.x = (long)(x.x * fg);
  1166.       Arg1->l.y = (long)(x.y * fg);
  1167.    }
  1168.    else
  1169.       overflow = 1;
  1170. }
  1171. #endif
  1172.  
  1173. void (*StkExp)(void) = dStkExp;
  1174.  
  1175. void dStkPwr(void) {
  1176.    Arg2->d = ComplexPower(Arg2->d, Arg1->d);
  1177.    Arg1--;
  1178.    Arg2--;
  1179. }
  1180.  
  1181. #ifndef XFRACT
  1182. void mStkPwr(void) {
  1183.    _CMPLX x, y;
  1184.  
  1185.    x = MPC2cmplx(Arg2->m);
  1186.    y = MPC2cmplx(Arg1->m);
  1187.    x = ComplexPower(x, y);
  1188.    Arg2->m = cmplx2MPC(x);
  1189.    Arg1--;
  1190.    Arg2--;
  1191. }
  1192.  
  1193. void lStkPwr(void) {
  1194.    _CMPLX x, y;
  1195.  
  1196.    x.x = (double)Arg2->l.x / fg;
  1197.    x.y = (double)Arg2->l.y / fg;
  1198.    y.x = (double)Arg1->l.x / fg;
  1199.    y.y = (double)Arg1->l.y / fg;
  1200.    x = ComplexPower(x, y);
  1201.    if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) {
  1202.       Arg2->l.x = (long)(x.x * fg);
  1203.       Arg2->l.y = (long)(x.y * fg);
  1204.    }
  1205.    else
  1206.       overflow = 1;
  1207.    Arg1--;
  1208.    Arg2--;
  1209. }
  1210. #endif
  1211.  
  1212. void (*StkPwr)(void) = dStkPwr;
  1213.  
  1214. void EndInit(void) {
  1215.    LastInitOp = OpPtr;
  1216. }
  1217.  
  1218. struct ConstArg far *isconst(char *Str, int Len) {
  1219.    _CMPLX z;
  1220.    unsigned n, j;
  1221.  
  1222.    for(n = 0; n < vsp; n++) {
  1223.       if(v[n].len == Len) {
  1224.          if(!strnicmp(v[n].s, Str, Len))
  1225.          {
  1226.             if(n == 7)        /* The formula uses 'rand'. */
  1227.                RandomSeed();
  1228.             return(&v[n]);
  1229.          }
  1230.       }
  1231.    }
  1232.    v[vsp].s = Str;
  1233.    v[vsp].len = Len;
  1234.    v[vsp].a.d.x = v[vsp].a.d.y = 0.0;
  1235.    if(isdigit(Str[0]) || Str[0] == '.') {
  1236.       if(o[posp-1].f == StkNeg) {
  1237.          posp--;
  1238.          Str = Str - 1;
  1239.          InitN--;
  1240.          v[vsp].len++;
  1241.       }
  1242.       for(n = 1; isdigit(Str[n]) || Str[n] == '.'; n++);
  1243.       if(Str[n] == ',') {
  1244.          j = n + SkipWhiteSpace(&Str[n+1]) + 1;
  1245.          if(isdigit(Str[j]) || (Str[j] == '-' && isdigit(Str[j+1]))) {
  1246.             z.y = atof(&Str[j]);
  1247.             for(; isdigit(Str[j]) || Str[j] == '.' || Str[j] == '-'; j++);
  1248.             v[vsp].len = j;
  1249.          }
  1250.          else
  1251.             z.y = 0.0;
  1252.       }
  1253.       else
  1254.          z.y = 0.0;
  1255.       z.x = atof(Str);
  1256.       switch(MathType) {
  1257.       case D_MATH:
  1258.          v[vsp].a.d = z;
  1259.          break;
  1260. #ifndef XFRACT
  1261.       case M_MATH:
  1262.          v[vsp].a.m = cmplx2MPC(z);
  1263.          break;
  1264.       case L_MATH:
  1265.          v[vsp].a.l.x = (long)(z.x * fg);
  1266.          v[vsp].a.l.y = (long)(z.y * fg);
  1267.          break;
  1268. #endif
  1269.       }
  1270.       v[vsp].s = Str;
  1271.    }
  1272.    return(&v[vsp++]);
  1273. }
  1274.  
  1275. struct FNCT_LIST {
  1276.    char far *s;              /* TIW 03-31-91 added far */
  1277.    void (**ptr)(void);
  1278. };
  1279.  
  1280. /* TIW 03-30-91 START */
  1281. extern BYTE trigndx[];
  1282.  
  1283. #if 0
  1284. extern void (*ltrig0)(void);
  1285. extern void (*ltrig1)(void);
  1286. extern void (*ltrig2)(void);
  1287. extern void (*ltrig3)(void);
  1288. extern void (*dtrig0)(void);
  1289. extern void (*dtrig1)(void);
  1290. extern void (*dtrig2)(void);
  1291. extern void (*dtrig3)(void);
  1292. extern void (*mtrig0)(void);
  1293. extern void (*mtrig1)(void);
  1294. extern void (*mtrig2)(void);
  1295. extern void (*mtrig3)(void);
  1296. #endif
  1297.  
  1298. void (*StkTrig0)(void) = dStkSin;
  1299. void (*StkTrig1)(void) = dStkSqr;
  1300. void (*StkTrig2)(void) = dStkSinh;
  1301. void (*StkTrig3)(void) = dStkCosh;
  1302.  
  1303. char maxfn = 0;
  1304. /* TIW 03-30-91 STOP */
  1305.  
  1306. struct FNCT_LIST far FnctList[] = {   /* TIW 03-31-91 added far */
  1307.    "sin",  &StkSin,
  1308.    "sinh", &StkSinh,
  1309.    "cos",  &StkCos,
  1310.    "cosh", &StkCosh,
  1311.    "sqr",  &StkSqr,
  1312.    "log",  &StkLog,
  1313.    "exp",  &StkExp,
  1314.    "abs",  &StkAbs,
  1315.    "conj", &StkConj,
  1316.    "real", &StkReal,
  1317.    "imag", &StkImag,
  1318.    "fn1",  &StkTrig0,   /* TIW 03-30-91 */
  1319.    "fn2",  &StkTrig1,   /* TIW 03-30-91 */
  1320.    "fn3",  &StkTrig2,   /* TIW 03-30-91 */
  1321.    "fn4",  &StkTrig3,   /* TIW 03-30-91 */
  1322.    "flip", &StkFlip,    /* MCP 4-9-91 */
  1323.    "tan",  &StkTan,     /* TIW 04-22-91 */
  1324.    "tanh", &StkTanh,    /* TIW 04-22-91 */
  1325.    "cotan",  &StkCoTan, /* TIW 04-24-91 */
  1326.    "cotanh", &StkCoTanh,/* TIW 04-24-91 */
  1327.    "cosxx", &StkCosXX,  /* PB  04-28-91 */
  1328.    "srand", &StkSRand,  /* MCP 11-21-91 */
  1329. };
  1330.  
  1331. void NotAFnct(void) { }
  1332. void FnctNotFound(void) { }
  1333.  
  1334. /* determine if s names a function and if so which one */
  1335. /* TIW 04-22-91 */
  1336. whichfn(char *s, int len)
  1337. {
  1338.    int out;
  1339.    if(len != 3)
  1340.       out = 0;
  1341.    else if(strnicmp(s,"fn",2))
  1342.       out = 0;
  1343.    else
  1344.       out = atoi(s+2);
  1345.    if(out < 1 || out > 4)
  1346.       out = 0;
  1347.    return(out);
  1348. }
  1349.  
  1350. #ifndef XFRACT
  1351. void (far *isfunct(char *Str, int Len))(void)
  1352. #else
  1353. void (*isfunct(Str, Len))()
  1354. char *Str;
  1355. int Len;
  1356. #endif
  1357. {
  1358.    unsigned n;
  1359.    int functnum;    /* TIW 04-22-91 */
  1360.  
  1361.    n = SkipWhiteSpace(&Str[Len]);
  1362.    if(Str[Len+n] == '(') {
  1363.       for(n = 0; n < sizeof(FnctList) / sizeof(struct FNCT_LIST); n++) {
  1364.          if(far_strlen(FnctList[n].s) == Len) {        /* TIW 03-31-91 added far */
  1365.             if(!far_strnicmp(FnctList[n].s, Str, Len)) {  /* TIW 03-31-91 added far */
  1366.                /* count function variables */
  1367.                if((functnum = whichfn(Str, Len)) != 0)    /* TIW 04-22-91 */
  1368.                   if(functnum > maxfn)                  /* TIW 04-22-91 */
  1369.                      maxfn = functnum;                  /* TIW 04-22-91 */
  1370.                return(*FnctList[n].ptr);
  1371.             }
  1372.          }
  1373.       }
  1374.       return(FnctNotFound);
  1375.    }
  1376.    return(NotAFnct);
  1377. }
  1378.  
  1379. void RecSortPrec(void) {
  1380.    int ThisOp = NextOp++;
  1381.  
  1382.    while(o[ThisOp].p > o[NextOp].p && NextOp < posp)
  1383.       RecSortPrec();
  1384.    f[OpPtr++] = o[ThisOp].f;
  1385. }
  1386.  
  1387. static char *Constants[] = {
  1388.    "pixel",        /* v[0] */
  1389.    "p1",           /* v[1] */
  1390.    "p2",           /* v[2] */
  1391.    "z",            /* v[3] */
  1392.    "LastSqr",      /* v[4] */
  1393.    "xy",           /* v[5] */
  1394.    "zt",           /* v[6] */
  1395.    "rand",         /* v[7] */
  1396. };
  1397.  
  1398. struct SYMETRY {
  1399.    char *s;
  1400.    int n;
  1401. } SymStr[] = {
  1402.    "NOSYM",         0,
  1403.    "XAXIS_NOPARM", -1,
  1404.    "XAXIS",         1,
  1405.    "YAXIS_NOPARM", -2,
  1406.    "YAXIS",         2,
  1407.    "XYAXIS_NOPARM",-3,
  1408.    "XYAXIS",        3,
  1409.    "ORIGIN_NOPARM",-4,
  1410.    "ORIGIN",        4,
  1411.    "PI_SYM_NOPARM",-5,
  1412.    "PI_SYM",        5,
  1413.    "NOPLOT",       99,
  1414.    "", 0
  1415. };
  1416.  
  1417. int ParseStr(char *Str) {
  1418.    struct ConstArg far *c;
  1419.    int ModFlag = 999, Len, Equals = 0, Mod[20], mdstk = 0;
  1420.    int NewStatement;
  1421.    struct ERROR { int n, s; } far *e;
  1422.  
  1423.    SetRandom = Randomized = 0;
  1424.    e = (struct ERROR far *)farmemalloc(sizeof(struct ERROR) * 100L);
  1425.    /* PB 910417 changed "o" to be a temporary alloc, during ParseStr only */
  1426.    o = (struct PEND_OP far *)farmemalloc(sizeof(struct PEND_OP) * (long)MAX_OPS);
  1427.    if(!e || !o || !typespecific_workarea) {
  1428.       static char far msg[]={"Insufficient memory to run fractal type 'formula'"};
  1429.       stopmsg(0,msg);
  1430.       return(1);
  1431.    }
  1432.    switch(MathType) {
  1433.    case D_MATH:
  1434.       StkAdd = dStkAdd;
  1435.       StkSub = dStkSub;
  1436.       StkNeg = dStkNeg;
  1437.       StkMul = dStkMul;
  1438.       StkSin = dStkSin;
  1439.       StkSinh = dStkSinh;
  1440.       StkLT = dStkLT;
  1441.       StkLTE = dStkLTE;
  1442.       StkMod = dStkMod;
  1443.       StkSqr = dStkSqr;
  1444.       StkCos = dStkCos;
  1445.       StkCosh = dStkCosh;
  1446.       StkLog = dStkLog;
  1447.       StkExp = dStkExp;
  1448.       StkPwr = dStkPwr;
  1449.       StkDiv = dStkDiv;
  1450.       StkAbs = dStkAbs;
  1451.       StkReal = dStkReal;
  1452.       StkImag = dStkImag;
  1453.       StkConj = dStkConj;
  1454.       StkTrig0 = dtrig0;   /* TIW 03-30-91 */
  1455.       StkTrig1 = dtrig1;   /* TIW 03-30-91 */
  1456.       StkTrig2 = dtrig2;   /* TIW 03-30-91 */
  1457.       StkTrig3 = dtrig3;   /* TIW 03-30-91 */
  1458.       StkFlip = dStkFlip;
  1459.       StkTan = dStkTan;    /* TIW 04-22-91 */
  1460.       StkTanh = dStkTanh;  /* TIW 04-22-91 */
  1461.       StkCoTan = dStkCoTan;    /* TIW 04-24-91 */
  1462.       StkCoTanh = dStkCoTanh;  /* TIW 04-24-91 */
  1463.       StkCosXX = dStkCosXX;    /* PB  04-28-91 */
  1464.       StkGT  = dStkGT;         /* MCP 11-3-91 */
  1465.       StkGTE = dStkGTE;        /* MCP 11-3-91 */
  1466.       StkEQ  = dStkEQ;         /* MCP 11-3-91 */
  1467.       StkNE  = dStkNE;         /* MCP 11-3-91 */
  1468.       StkAND = dStkAND;        /* MCP 11-3-91 */
  1469.       StkOR  = dStkOR ;        /* MCP 11-3-91 */
  1470.       StkSRand = dStkSRand;    /* MCP 11-21-91 */
  1471.       break;
  1472. #ifndef XFRACT
  1473.    case M_MATH:
  1474.       StkAdd = mStkAdd;
  1475.       StkSub = mStkSub;
  1476.       StkNeg = mStkNeg;
  1477.       StkMul = mStkMul;
  1478.       StkSin = mStkSin;
  1479.       StkSinh = mStkSinh;
  1480.       StkLT = mStkLT;
  1481.       StkLTE = mStkLTE;
  1482.       StkMod = mStkMod;
  1483.       StkSqr = mStkSqr;
  1484.       StkCos = mStkCos;
  1485.       StkCosh = mStkCosh;
  1486.       StkLog = mStkLog;
  1487.       StkExp = mStkExp;
  1488.       StkPwr = mStkPwr;
  1489.       StkDiv = mStkDiv;
  1490.       StkAbs = mStkAbs;
  1491.       StkReal = mStkReal;
  1492.       StkImag = mStkImag;
  1493.       StkConj = mStkConj;
  1494.       StkTrig0 = mtrig0;  /* TIW 03-30-91 */
  1495.       StkTrig1 = mtrig1;  /* TIW 03-30-91 */
  1496.       StkTrig2 = mtrig2;  /* TIW 03-30-91 */
  1497.       StkTrig3 = mtrig3;  /* TIW 03-30-91 */
  1498.       StkFlip = mStkFlip;
  1499.       StkTan  = mStkTan;  /* TIW 04-22-91 */
  1500.       StkTanh  = mStkTanh;/* TIW 04-22-91 */
  1501.       StkCoTan  = mStkCoTan;  /* TIW 04-24-91 */
  1502.       StkCoTanh  = mStkCoTanh;/* TIW 04-24-91 */
  1503.       StkCosXX = mStkCosXX;   /* PB  04-28-91 */
  1504.       StkGT  = mStkGT;         /* MCP 11-3-91 */
  1505.       StkGTE = mStkGTE;        /* MCP 11-3-91 */
  1506.       StkEQ  = mStkEQ;         /* MCP 11-3-91 */
  1507.       StkNE  = mStkNE;         /* MCP 11-3-91 */
  1508.       StkAND = mStkAND;        /* MCP 11-3-91 */
  1509.       StkOR  = mStkOR ;        /* MCP 11-3-91 */
  1510.       StkSRand = mStkSRand;    /* MCP 11-21-91 */
  1511.       break;
  1512.    case L_MATH:
  1513.       Delta16 = bitshift - 16;
  1514.       ShiftBack = 32 - bitshift; /* TW 06-18-90 */
  1515.       StkAdd = lStkAdd;
  1516.       StkSub = lStkSub;
  1517.       StkNeg = lStkNeg;
  1518.       StkMul = lStkMul;
  1519.       StkSin = lStkSin;
  1520.       StkSinh = lStkSinh;
  1521.       StkLT = lStkLT;
  1522.       StkLTE = lStkLTE;
  1523.       StkMod = lStkMod;
  1524.       StkSqr = lStkSqr;
  1525.       StkCos = lStkCos;
  1526.       StkCosh = lStkCosh;
  1527.       StkLog = lStkLog;
  1528.       StkExp = lStkExp;
  1529.       StkPwr = lStkPwr;
  1530.       StkDiv = lStkDiv;
  1531.       StkAbs = lStkAbs;
  1532.       StkReal = lStkReal;
  1533.       StkImag = lStkImag;
  1534.       StkConj = lStkConj;
  1535.       StkTrig0 = ltrig0;   /* TIW 03-30-91 */
  1536.       StkTrig1 = ltrig1;   /* TIW 03-30-91 */
  1537.       StkTrig2 = ltrig2;   /* TIW 03-30-91 */
  1538.       StkTrig3 = ltrig3;   /* TIW 03-30-91 */
  1539.       StkFlip = lStkFlip;
  1540.       StkTan  = lStkTan;   /* TIW 04-22-91 */
  1541.       StkTanh  = lStkTanh; /* TIW 04-22-91 */
  1542.       StkCoTan  = lStkCoTan;   /* TIW 04-24-91 */
  1543.       StkCoTanh  = lStkCoTanh; /* TIW 04-24-91 */
  1544.       StkCosXX = lStkCosXX;    /* PB  04-28-91 */
  1545.       StkGT  = lStkGT;         /* MCP 11-3-91 */
  1546.       StkGTE = lStkGTE;        /* MCP 11-3-91 */
  1547.       StkEQ  = lStkEQ;         /* MCP 11-3-91 */
  1548.       StkNE  = lStkNE;         /* MCP 11-3-91 */
  1549.       StkAND = lStkAND;        /* MCP 11-3-91 */
  1550.       StkOR  = lStkOR ;        /* MCP 11-3-91 */
  1551.       StkSRand = lStkSRand;    /* MCP 11-21-91 */
  1552.       break;
  1553. #endif
  1554.    }
  1555.    maxfn = 0;   /* TIW 03-30-91 */
  1556.    for(vsp = 0; vsp < sizeof(Constants) / sizeof(char*); vsp++) {
  1557.       v[vsp].s = Constants[vsp];
  1558.       v[vsp].len = strlen(Constants[vsp]);
  1559.    }
  1560.  
  1561.    v[6].a.d.x = v[6].a.d.y = 0.0;
  1562.    v[7].a = v[6].a;
  1563.  
  1564.    switch(MathType) {
  1565.    case D_MATH:
  1566.       v[1].a.d.x = param[0];
  1567.       v[1].a.d.y = param[1];
  1568.       v[2].a.d.x = param[2];
  1569.       v[2].a.d.y = param[3];
  1570.       break;
  1571. #ifndef XFRACT
  1572.    case M_MATH:
  1573.       v[1].a.m.x = *d2MP(param[0]);
  1574.       v[1].a.m.y = *d2MP(param[1]);
  1575.       v[2].a.m.x = *d2MP(param[2]);
  1576.       v[2].a.m.y = *d2MP(param[3]);
  1577.       break;
  1578.    case L_MATH:
  1579.       v[1].a.l.x = (long)(param[0] * fg);
  1580.       v[1].a.l.y = (long)(param[1] * fg);
  1581.       v[2].a.l.x = (long)(param[2] * fg);
  1582.       v[2].a.l.y = (long)(param[3] * fg);
  1583.       break;
  1584. #endif
  1585.    }
  1586.  
  1587.    LastInitOp = ErrPtr = paren = OpPtr = LodPtr = StoPtr = posp = 0;
  1588.    NewStatement = 1;
  1589.    SyntaxErr = -1;
  1590.    ExpectingArg = 1;
  1591.    for(n = 0; Str[n]; n++) {
  1592.       if(!Str[n])
  1593.          break;
  1594.       InitN = n;
  1595.       switch(Str[n]) {
  1596.       case ' ':
  1597.       case '\t':
  1598.       case '\r':
  1599.       case '\n':
  1600.          break;
  1601.       case '(':
  1602.          paren++;
  1603.          if(!ExpectingArg)
  1604.             SyntaxErr = 1;
  1605.          break;
  1606.       case ')':
  1607.          if(paren)
  1608.             paren--;
  1609.          else
  1610.             SyntaxErr = 2;
  1611.          if(ExpectingArg) {
  1612.             e[ErrPtr].n = InitN;
  1613.             e[ErrPtr++].s = 0;
  1614.          }
  1615.          break;
  1616.       case '|':
  1617.          if(Str[n+1] == '|') {
  1618.             if(ExpectingArg)
  1619.                SyntaxErr = 0;
  1620.             ExpectingArg = 1;
  1621.             n++;
  1622.             o[posp].f = StkOR;
  1623.             o[posp++].p = 7 - (paren + Equals)*15;
  1624.          }
  1625.          else if(ModFlag == paren-1) {
  1626.             if(ExpectingArg)
  1627.                SyntaxErr = 0;
  1628.             paren--;
  1629.             ModFlag = Mod[--mdstk];
  1630.          }
  1631.          else {
  1632.             if(!ExpectingArg)
  1633.                SyntaxErr = 1;
  1634.             Mod[mdstk++] = ModFlag;
  1635.             o[posp].f = StkMod;
  1636.             o[posp++].p = 2 - (paren + Equals)*15;
  1637.             ModFlag = paren++;
  1638.          }
  1639.          break;
  1640.       case ',':
  1641.       case ';':
  1642.          if(paren) {
  1643.             e[ErrPtr].n = InitN;
  1644.             e[ErrPtr++].s = 3;
  1645.          }
  1646.          if(!ExpectingArg) {
  1647.             NewStatement = 1;
  1648.             ExpectingArg = 1;
  1649.             o[posp].f = (void(far*)(void))0;
  1650.             o[posp++].p = 15;
  1651.             o[posp].f = StkClr;
  1652.             o[posp++].p = -30000;
  1653.             Equals = paren = 0;
  1654.          }
  1655.          else if(!NewStatement)
  1656.             SyntaxErr = 0;
  1657.          break;
  1658.       case ':':
  1659.          if(paren) {
  1660.             e[ErrPtr].n = InitN;
  1661.             e[ErrPtr++].s = 3;
  1662.          }
  1663.          if(ExpectingArg)
  1664.             SyntaxErr = 0;
  1665.          else
  1666.             ExpectingArg = 1;
  1667.          o[posp].f = (void(far*)(void))0;
  1668.          o[posp++].p = 15;
  1669.          o[posp].f = EndInit;
  1670.          o[posp++].p = -30000;
  1671.          Equals = paren = 0;
  1672.          LastInitOp = 10000;
  1673.          NewStatement = 1;
  1674.          break;
  1675.       case '+':
  1676.          if(ExpectingArg)
  1677.             SyntaxErr = 0;
  1678.          ExpectingArg = 1;
  1679.          o[posp].f = StkAdd;
  1680.          o[posp++].p = 4 - (paren + Equals)*15;
  1681.          break;
  1682.       case '-':
  1683.          if(ExpectingArg) {
  1684.             o[posp].f = StkNeg;
  1685.             o[posp++].p = 2 - (paren + Equals)*15;
  1686.          }
  1687.          else {
  1688.             o[posp].f = StkSub;
  1689.             o[posp++].p = 4 - (paren + Equals)*15;
  1690.             ExpectingArg = 1;
  1691.          }
  1692.          break;
  1693.       case '&':
  1694.          if(ExpectingArg)
  1695.             SyntaxErr = 0;
  1696.          ExpectingArg = 1;
  1697.          if(Str[n+1] == '&') {
  1698.             n++;
  1699.             o[posp].f = StkAND;
  1700.             o[posp++].p = 7 - (paren + Equals)*15;
  1701.          }
  1702.          else
  1703.             SyntaxErr = 4;
  1704.          break;
  1705.       case '!':
  1706.          if(Str[n+1] == '=') {
  1707.             if(ExpectingArg)
  1708.                SyntaxErr = 0;
  1709.             ExpectingArg = 1;
  1710.             n++;
  1711.             o[posp].f = StkNE;
  1712.             o[posp++].p = 6 - (paren + Equals)*15;
  1713.          }
  1714.          else
  1715.             SyntaxErr = 4;
  1716.          break;
  1717.       case '<':
  1718.          if(ExpectingArg)
  1719.             SyntaxErr = 0;
  1720.          ExpectingArg = 1;
  1721.          if(Str[n+1] == '=') {
  1722.             n++;
  1723.             o[posp].f = StkLTE;
  1724.          }
  1725.          else
  1726.             o[posp].f = StkLT;
  1727.          o[posp++].p = 6 - (paren + Equals)*15;
  1728.          break;
  1729.       case '>':
  1730.          if(ExpectingArg)
  1731.             SyntaxErr = 0;
  1732.          ExpectingArg = 1;
  1733.          if(Str[n+1] == '=') {
  1734.             n++;
  1735.             o[posp].f = StkGTE;
  1736.          }
  1737.          else
  1738.             o[posp].f = StkGT;
  1739.          o[posp++].p = 6 - (paren + Equals)*15;
  1740.          break;
  1741.       case '*':
  1742.          if(ExpectingArg)
  1743.             SyntaxErr = 0;
  1744.          ExpectingArg = 1;
  1745.          o[posp].f = StkMul;
  1746.          o[posp++].p = 3 - (paren + Equals)*15;
  1747.          break;
  1748.       case '/':
  1749.          if(ExpectingArg)
  1750.             SyntaxErr = 0;
  1751.          ExpectingArg = 1;
  1752.          o[posp].f = StkDiv;
  1753.          o[posp++].p = 3 - (paren + Equals)*15;
  1754.          break;
  1755.       case '^':
  1756.          if(ExpectingArg)
  1757.             SyntaxErr = 0;
  1758.          ExpectingArg = 1;
  1759.          o[posp].f = StkPwr;
  1760.          o[posp++].p = 2 - (paren + Equals)*15;
  1761.          break;
  1762.       case '=':
  1763.          if(ExpectingArg)
  1764.             SyntaxErr = 0;
  1765.          ExpectingArg = 1;
  1766.          if(Str[n+1] == '=') {
  1767.             n++;
  1768.             o[posp].f = StkEQ;
  1769.             o[posp++].p = 6 - (paren + Equals)*15;
  1770.          }
  1771.          else
  1772.          {
  1773.             o[posp-1].f = StkSto;
  1774.             o[posp-1].p = 5 - (paren + Equals)*15;
  1775.             Store[StoPtr++] = Load[--LodPtr];
  1776.             Equals++;
  1777.          }
  1778.          break;
  1779.       default:
  1780.          if(isalnum(Str[n]) || Str[n] == '.') {
  1781.             while(isalnum(Str[n+1]) || Str[n+1] == '.')
  1782.                n++;
  1783.             if(!ExpectingArg) {
  1784.                SyntaxErr = 1;
  1785.             }
  1786.             NewStatement = ExpectingArg = 0;
  1787.             Len = (n+1)-InitN;
  1788.             o[posp].f = isfunct(&Str[InitN], Len);
  1789.             if(o[posp].f != NotAFnct) {
  1790.                if(o[posp].f == FnctNotFound) {
  1791.                   e[ErrPtr].n = InitN;
  1792.                   e[ErrPtr++].s = 5;
  1793.                }
  1794.                else
  1795.                   o[posp++].p = 1 - (paren + Equals)*15;
  1796.                ExpectingArg = 1;
  1797.             }
  1798.             else {
  1799.                c = isconst(&Str[InitN], Len);
  1800.                Load[LodPtr++] = &(c->a);
  1801.                o[posp].f = StkLod;
  1802.                o[posp++].p = 1 - (paren + Equals)*15;
  1803.                n = InitN + c->len - 1;
  1804.                if(vsp >= MAX_ARGS-1) { /* PB 910417 safety test */
  1805.                   e[ErrPtr].n = InitN;
  1806.                   e[ErrPtr++].s = 7;
  1807.                   break;
  1808.                }
  1809.             }
  1810.          }
  1811.          else {
  1812.             if(ExpectingArg)
  1813.                SyntaxErr = 0;
  1814.             ExpectingArg = 1;
  1815.             e[ErrPtr].n = InitN;
  1816.             e[ErrPtr++].s = 4;
  1817.          }
  1818.          break;
  1819.       }
  1820.       if(SyntaxErr >= 0) {
  1821.          e[ErrPtr].n = InitN;
  1822.          e[ErrPtr++].s = SyntaxErr;
  1823.          SyntaxErr = -1;
  1824.       }
  1825.       if(posp >= MAX_OPS-1) { /* PB 901103 added safety test here */
  1826.          e[ErrPtr].n = InitN;
  1827.          e[ErrPtr++].s = 7;
  1828.          break;
  1829.       }
  1830.       if(ErrPtr > 50)         /* PB 910417 safety test */
  1831.          break;
  1832.    }
  1833.  
  1834.    o[posp].f = (void(far*)(void))0;
  1835.    o[posp++].p = 16;
  1836.    if(paren > 0) {
  1837.       e[ErrPtr].n = n;
  1838.       e[ErrPtr++].s = 3;
  1839.    }
  1840.    if (ErrPtr) {
  1841.       int i, j, k, m;
  1842.       char msgbuf[700];  /* PB replaced printf loop by build msgbuf & stopmsg */
  1843.       /* stopmsg defined to have max 9 lines, show at most first 3 errors */
  1844.       msgbuf[0] = 0;
  1845.       for(n = 0; n < ErrPtr && n < 3; n++) {
  1846.          if (n)
  1847.             strcat(msgbuf,"\n");
  1848. #ifndef XFRACT
  1849.          sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %Fs\n  ", e[n].s, /*TIW 03-31-91 added %Fs*/
  1850.             ErrStrings[e[n].s]);
  1851. #else
  1852.          sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %s\n  ", e[n].s,
  1853.             ErrStrings[e[n].s]);
  1854. #endif
  1855.          j = 24;
  1856.          if ((i = e[n].n - j) < 0) {
  1857.             j = e[n].n;
  1858.             i = 0;
  1859.          }
  1860.          else {
  1861.             strcat(msgbuf,"...");
  1862.             j += 3;
  1863.          }
  1864.          k = strlen(msgbuf);
  1865.          m = i + 66;
  1866.          while (i < m && Str[i]) {
  1867.             if ((msgbuf[k] = Str[i]) == '\n' || msgbuf[k] == '\t')
  1868.                msgbuf[k] = ' ';
  1869.             ++i;
  1870.             ++k;
  1871.          }
  1872.          if (Str[i]) {
  1873.             msgbuf[k++] = '.';
  1874.             msgbuf[k++] = '.';
  1875.             msgbuf[k++] = '.';
  1876.          }
  1877.          msgbuf[k++] = '\n';
  1878.          while (--j >= -2)
  1879.             msgbuf[k++] = ' ';
  1880.          msgbuf[k++] = '^';
  1881.          msgbuf[k] = 0;
  1882.       }
  1883.       stopmsg(8,msgbuf);
  1884.    }
  1885.    if(!ErrPtr) {
  1886.       NextOp = 0;
  1887.       LastOp = posp;
  1888.       while(NextOp < posp) {
  1889.          if(o[NextOp].f)
  1890.             RecSortPrec();
  1891.          else {
  1892.             NextOp++;
  1893.             LastOp--;
  1894.          }
  1895.       }
  1896.    }
  1897.    else
  1898.       posp = 0;
  1899.    farmemfree(o);
  1900.    farmemfree(e);
  1901.    /* PB 910417 free all arrays if error */
  1902.    if (ErrPtr)
  1903.       free_workarea();
  1904.    return(ErrPtr);
  1905. }
  1906.  
  1907. int Formula(void) {
  1908.    if(FormName[0] == 0 || overflow) return(1);
  1909.  
  1910.    LodPtr = InitLodPtr;
  1911.    StoPtr = InitStoPtr;
  1912.    OpPtr = InitOpPtr;
  1913.  
  1914.    /* Set the random number, MCP 11-21-91 */
  1915.    if(SetRandom || Randomized)
  1916.    {
  1917.       switch(MathType)
  1918.       {
  1919.       case D_MATH:
  1920.          dRandom();
  1921.          break;
  1922. #ifndef XFRACT
  1923.       case L_MATH:
  1924.          lRandom();
  1925.          break;
  1926.       case M_MATH:
  1927.          mRandom();
  1928. #endif
  1929.       }
  1930.    }
  1931.  
  1932.    Arg1 = &s[0];
  1933.    Arg2 = Arg1-1;
  1934.    while(OpPtr < LastOp) {
  1935.       f[OpPtr++]();
  1936. #ifdef WATCH_MP
  1937.       x1 = *MP2d(Arg1->m.x);
  1938.       y1 = *MP2d(Arg1->m.y);
  1939.       x2 = *MP2d(Arg2->m.x);
  1940.       y2 = *MP2d(Arg2->m.y);
  1941. #endif
  1942.    }
  1943.  
  1944.    switch(MathType) {
  1945.    case D_MATH:
  1946.       old = new = v[3].a.d;
  1947.       return(Arg1->d.x == 0.0);
  1948. #ifndef XFRACT
  1949.    case M_MATH:
  1950.       old = new = MPC2cmplx(v[3].a.m);
  1951.       return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0);
  1952.    case L_MATH:
  1953.       lold = lnew = v[3].a.l;
  1954.       if(overflow)
  1955.          return(1);
  1956.       return(Arg1->l.x == 0L);
  1957. #endif
  1958.    }
  1959.    return(1);
  1960. }
  1961.  
  1962. int form_per_pixel(void) {
  1963.    if (FormName[0] == 0) return(1);
  1964.    overflow = LodPtr = StoPtr = OpPtr = 0;
  1965.    Arg1 = &s[0];
  1966.    Arg2 = Arg1;
  1967.    Arg2--;
  1968.    if(Transparent3D)
  1969.    {
  1970.       TranspPerPixel(MathType, &v[5].a, &v[6].a);
  1971.       v[0].a = v[5].a;
  1972.    }
  1973.    else
  1974.    {
  1975.       switch(MathType)
  1976.       {
  1977.       case D_MATH:
  1978.          v[5].a.d.x = (v[0].a.d.x = dx0[col]+dShiftx);
  1979.          v[5].a.d.x = (v[0].a.d.y = dy0[row]+dShifty);
  1980.          break;
  1981. #ifndef XFRACT
  1982.       case M_MATH:
  1983.          v[5].a.m.x = (v[0].a.m.x = *d2MP(dx0[col]+dShiftx));
  1984.          v[5].a.m.x = (v[0].a.m.y = *d2MP(dy0[row]+dShifty));
  1985.          break;
  1986.       case L_MATH:
  1987.          v[5].a.l.x = (v[0].a.l.x = lx0[col]+lShiftx);
  1988.          v[5].a.l.x = (v[0].a.l.y = ly0[row]+lShifty);
  1989.          break;
  1990. #endif
  1991.       }
  1992.    }
  1993.  
  1994.    if(LastInitOp)
  1995.       LastInitOp = LastOp;
  1996.    while(OpPtr < LastInitOp)
  1997.       f[OpPtr++]();
  1998.  
  1999.    InitLodPtr = LodPtr;
  2000.    InitStoPtr = StoPtr;
  2001.    InitOpPtr = OpPtr;
  2002.  
  2003.    if(overflow)
  2004.       return(0);
  2005.    else
  2006.       return(1);
  2007. }
  2008.  
  2009. char *FormStr;
  2010.  
  2011. extern char FormFileName[];   /* BDT file to find the formulas in */
  2012. extern char FormName[];    /* BDT Name of the Formula (if not null) */
  2013.  
  2014. char *FindFormula(char *Str) {
  2015.    char *FormulaStr = (char *)0;
  2016.    char StrBuff[201];      /* PB, to match a safety fix in parser */
  2017.    /* MCP, changed to an automatic variable */
  2018.    char fullfilename[100]; /* BDT Full file name */
  2019.    unsigned Done;
  2020.    int c;
  2021.    FILE *File;
  2022.  
  2023.    findpath(FormFileName, fullfilename);  /* BDT get full path name */
  2024.  
  2025.    symmetry = 0;
  2026.    if((File = fopen(fullfilename, "rt")) != NULL) { /* BDT use variable files */
  2027.       while(StrBuff[0]=0,/* TIW 04-22-91 */ fscanf(File, "%200[^ \n\t({]", StrBuff) != EOF) {
  2028.          if(!stricmp(StrBuff, Str) || !Str[0]) {
  2029.             while((c = getc(File)) != EOF) {
  2030.                if(c == '(') {
  2031.                   StrBuff[0]=0; /* TIW 04-22-91 */
  2032.                   fscanf(File, "%200[^)]", StrBuff);
  2033.                   for(n = 0; SymStr[n].s[0]; n++) {
  2034.                      if(!stricmp(SymStr[n].s, StrBuff)) {
  2035.                         symmetry = SymStr[n].n;
  2036.                         break;
  2037.                      }
  2038.                   }
  2039.                   if(!SymStr[n].s[0]) {
  2040.                      sprintf(fullfilename,"Undefined symmetry:\n  %.76s",
  2041.                         StrBuff);
  2042.                      stopmsg(0,fullfilename); /* PB printf -> stopmsg */
  2043.                      FormulaStr = (char *)0;  /* PB 910511 */
  2044. Exit:
  2045.                      fclose(File);
  2046.                      return(FormulaStr);
  2047.                   }
  2048.                }
  2049.                else if(c == '{')
  2050.                   break;
  2051.             }
  2052.  
  2053.             /* MCP 4-9-91, Strip the comments inside the formula.  Might
  2054.                            as well allow unlimited formula lengths while
  2055.                            we're at it.
  2056.             */
  2057.  
  2058.             FormulaStr = boxx;
  2059.             n = Done = 0;
  2060.             while(!Done) {
  2061.                switch(c = getc(File)) {
  2062.                   static char far msg[]={"Unexpected EOF:  missing a '}'"};
  2063.                case EOF:
  2064. UnexpectedEOF:
  2065.                   stopmsg(0, msg);
  2066.                   FormulaStr = (char *)0;
  2067.                   goto Exit;
  2068.                case '}':
  2069.                   FormulaStr[n++] = 0;
  2070.                   Done = 1;
  2071.                   break;
  2072.                case ';':
  2073.                   while((c = getc(File)) != '\n') {
  2074.                      if(c == EOF)
  2075.                         goto UnexpectedEOF;
  2076.                   }
  2077.                   FormulaStr[n++] = ',';
  2078.                   break;
  2079.                case ' ':                     /* Also strip out the
  2080.                                                    white spaces */
  2081.                                     
  2082.                case '\t':
  2083.                   break;
  2084.                case '\n':
  2085.                   FormulaStr[n++] = ',';
  2086.                   break;
  2087.                default:
  2088.                   FormulaStr[n++] = c;
  2089.                }
  2090.                if (n >= 8192) { /* PB 4-9-91, added safety test */
  2091.                   static char far msg[]={"Definition too large, missing a '}'?"};
  2092.                   stopmsg(0, msg);
  2093.                   FormulaStr = (char *)0;
  2094.                   goto Exit;
  2095.                }
  2096.             }
  2097.             goto Exit;
  2098.          }
  2099.  
  2100.          StrBuff[0]=0;  /* TIW 04-22-91 */
  2101.          fscanf(File, "%200[ \n\t({]", StrBuff);
  2102.          if(StrBuff[strcspn(StrBuff, "({")]) {
  2103. skipcomments:
  2104.             fscanf(File, "%200[^}]", StrBuff);
  2105.             if (getc(File)!= '}') goto skipcomments;
  2106.          }
  2107.       }
  2108.       sprintf(fullfilename, "Formula \"%s\" not found", Str);
  2109.       stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  2110.       FormulaStr = (char *)0;       /* PB 910511 */
  2111.       goto Exit;
  2112.    }
  2113.    sprintf(fullfilename, "Unable to open %s", FormFileName);
  2114.    stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
  2115.    return((char *)0);            /* PB 910511 */
  2116. }
  2117.  
  2118. int BadFormula() {
  2119.    /*  moved from Parsera.Asm by CAE  12 July 1993  */
  2120.  
  2121.    /*  this is called when a formula is bad, instead of calling  */
  2122.    /*     the normal functions which will produce undefined results  */
  2123.    return 1;
  2124. }
  2125.  
  2126. int RunForm(char *Name) {  /*  returns 1 if an error occurred  */
  2127.    /*  CAE changed fn 12 July 1993 to fix problem when formula not found  */
  2128.  
  2129.    /*  first set the pointers so they point to a fn which always returns 1  */
  2130.    curfractalspecific->per_pixel = BadFormula;
  2131.    curfractalspecific->orbitcalc = BadFormula;
  2132.  
  2133.    if (FormName[0] == 0 ){
  2134.       return 1;  /*  and don't reset the pointers  */
  2135.    }
  2136.  
  2137.    parser_allocate();  /*  ParseStr() will test if this alloc worked  */
  2138.  
  2139.    if((FormStr = FindFormula(Name)) != NULL ){
  2140.       /*  formula was found  */
  2141.       if (ParseStr(FormStr)){
  2142.          /*  parse failed, don't change fn pointers  */
  2143.          return 1;
  2144.       }
  2145.       else {
  2146.          /*  parse succeeded so set the pointers back to good functions  */
  2147.          curfractalspecific->per_pixel = form_per_pixel;
  2148.          curfractalspecific->orbitcalc = Formula;
  2149.          return 0;
  2150.       }
  2151.    }
  2152.    else {
  2153.       /*  formula not found, leave pointers set to BadFormula  */
  2154.       return 1;                    /* PB, msg moved to FindFormula */
  2155.    }
  2156. }
  2157.  
  2158. int fpFormulaSetup(void) {
  2159. #ifndef XFRACT
  2160.    int RunFormRes;        /* CAE fp */
  2161.  
  2162.    if (fpu > 0) {
  2163.       MathType = D_MATH;
  2164.       /* CAE changed below for fp */
  2165.       RunFormRes = !RunForm(FormName); /* RunForm() returns 1 for failure */
  2166.       if (RunFormRes && fpu >=387 && debugflag != 90 )
  2167.          return CvtStk(); /* run fast assembler code in parsera.asm */
  2168.       return RunFormRes;
  2169.    }
  2170.    else {
  2171.       MathType = M_MATH;
  2172.       return !RunForm(FormName);
  2173.    }
  2174. #else
  2175.    MathType = D_MATH;
  2176.    return(!RunForm(FormName));
  2177. #endif
  2178. }
  2179.  
  2180. int intFormulaSetup(void) {
  2181. #ifdef XFRACT
  2182.       printf("intFormulaSetup called!!!\n");
  2183.       exit(-1);
  2184. #endif
  2185.       MathType = L_MATH;
  2186.       fg = (double)(1L << bitshift);
  2187.       fgLimit = (double)0x7fffffffL / fg;
  2188.       ShiftBack = 32 - bitshift;
  2189.       return(!RunForm(FormName));
  2190.    }
  2191.  
  2192.  
  2193. /* TIW added 06-20-90 so functions can be called from fractals.c */
  2194. void init_misc()
  2195. {
  2196.    static struct ConstArg far vv[5];
  2197.    static union Arg argfirst,argsecond;
  2198.    if(!v) /* PB 901103 added this test to avoid clobbering the real thing */
  2199.       v = vv;  /* this is needed by lStkSqr and dStkSqr */
  2200.    Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */
  2201.    fg = (double)(1L << bitshift);
  2202.    fgLimit = (double)0x7fffffffL / fg;
  2203.    ShiftBack = 32 - bitshift;
  2204.    Delta16 = bitshift - 16;
  2205.    bitshiftless1 = bitshift-1;
  2206. }
  2207.  
  2208. /* PB 910417 here to end changed.
  2209.     Allocate sub-arrays from one main farmemalloc, using global variable
  2210.     typespecific_workarea; calcfrac.c releases this area when calculation
  2211.     ends or is terminated.
  2212.     Moved the "f" array to be allocated as part of this.
  2213.     */
  2214.  
  2215. static void parser_allocate(void)
  2216. {
  2217.    /* CAE fp changed below for v18 */
  2218.    /* Note that XFRACT will waste about 6k here for pfls */
  2219.    /* Somewhat more memory is now allocated than in v17 here */
  2220.    /* however Store and Load were reduced in size to help make up for it */
  2221.  
  2222.    unsigned int f_size,Store_size,Load_size,v_size, p_size;
  2223.    free_workarea();
  2224.    f_size = sizeof(void(far * far *)(void)) * MAX_OPS;
  2225.    Store_size = sizeof(union Arg far *) * MAX_STORES;
  2226.    Load_size = sizeof(union Arg far *) * MAX_LOADS;
  2227.    v_size = sizeof(struct ConstArg) * MAX_ARGS;
  2228.    p_size = sizeof(struct fls far *) * MAX_OPS;
  2229.    typespecific_workarea =
  2230.    farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size));
  2231.    f = (void(far * far *)(void))typespecific_workarea;
  2232.    Store = (union Arg far * far *)(f + MAX_OPS);
  2233.    Load = (union Arg far * far *)(Store + MAX_STORES);
  2234.    v = (struct ConstArg far *)(Load + MAX_LOADS);
  2235.    pfls = (struct fls far *)(v + MAX_ARGS);
  2236. }
  2237.  
  2238. void free_workarea()
  2239. {
  2240.    if(typespecific_workarea) {
  2241.       farmemfree(typespecific_workarea);
  2242.       typespecific_workarea = NULL;
  2243.    }
  2244.    Store = (union Arg far * far *)0;
  2245.    Load = (union Arg far * far *)0;
  2246.    v = (struct ConstArg far *)0;
  2247.    f = (void(far * far *)(void))0;    /* CAE fp */
  2248.    pfls = (struct fls far * )0;   /* CAE fp */
  2249.  
  2250. }
  2251.