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