File: common\parser.c

    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 <time.h>
   29 
   30   /* see Fractint.c for a description of the "include"  hierarchy */
   31 #include "port.h"
   32 #include "prototyp.h"
   33 
   34 
   35 #ifdef WATCH_MP
36 double x1, y1, x2, y2;
37 #endif 38 39 enum MATH_TYPE MathType = D_MATH; 40 /* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */ 41 42 #define MAX_OPS 250 43 #define MAX_ARGS 100 44 #define MAX_BOXX 8192 /* max size of boxx array */ 45 46 unsigned Max_Ops = MAX_OPS; 47 unsigned Max_Args = MAX_ARGS; 48 49 unsigned long number_of_ops, number_of_loads, number_of_stores, number_of_jumps; 50 51 struct PEND_OP { 52 void (far *f)(void); 53 int p; 54 }; 55 56 #ifndef XFRACT 57 /* reuse an array in the decoder */ 58 JUMP_CONTROL_ST far *jump_control = (JUMP_CONTROL_ST far *) sizeofstring;
59 #else 60 JUMP_CONTROL_ST jump_control[MAX_JUMPS];
61 #endif 62 63 int jump_index, InitJumpIndex; 64 65 static int frm_prescan (FILE * open_file); 66 67 #define CASE_TERMINATOR case',':\ 68 case '\n':\ 69 case '(':\ 70 case ')':\ 71 case '!':\ 72 case '=':\ 73 case '<':\ 74 case '>':\ 75 case '|':\ 76 case '&':\ 77 case '}':\ 78 case ':':\ 79 case '+':\ 80 case '-':\ 81 case '*':\ 82 case '/':\ 83 case '^' 84 85 #define CASE_ALPHA case 'a':\ 86 case 'b':\ 87 case 'c':\ 88 case 'd':\ 89 case 'e':\ 90 case 'f':\ 91 case 'g':\ 92 case 'h':\ 93 case 'i':\ 94 case 'j':\ 95 case 'k':\ 96 case 'l':\ 97 case 'm':\ 98 case 'n':\ 99 case 'o':\ 100 case 'p':\ 101 case 'q':\ 102 case 'r':\ 103 case 's':\ 104 case 't':\ 105 case 'u':\ 106 case 'v':\ 107 case 'w':\ 108 case 'x':\ 109 case 'y':\ 110 case 'z' 111 112 #define CASE_NUM case '0':\ 113 case '1':\ 114 case '2':\ 115 case '3':\ 116 case '4':\ 117 case '5':\ 118 case '6':\ 119 case '7':\ 120 case '8':\ 121 case '9' 122 123 /* token_type definitions */ 124 #define NOT_A_TOKEN 0 125 #define PARENS 1 126 #define PARAM_VARIABLE 2 127 #define USER_NAMED_VARIABLE 3 128 #define PREDEFINED_VARIABLE 4 129 #define REAL_CONSTANT 5 130 #define COMPLEX_CONSTANT 6 131 #define FUNCTION 7 132 #define PARAM_FUNCTION 8 133 #define FLOW_CONTROL 9 134 #define OPERATOR 10 135 #define END_OF_FORMULA 11 136 137 /* token IDs */ 138 #define END_OF_FILE 1 139 #define ILLEGAL_CHARACTER 2 140 #define ILLEGAL_VARIABLE_NAME 3 141 #define TOKEN_TOO_LONG 4 142 #define FUNC_USED_AS_VAR 5 143 #define JUMP_MISSING_BOOLEAN 6 144 #define JUMP_WITH_ILLEGAL_CHAR 7 145 #define UNDEFINED_FUNCTION 8 146 #define ILLEGAL_OPERATOR 9 147 #define ILL_FORMED_CONSTANT 10 148 #define OPEN_PARENS 1 149 #define CLOSE_PARENS -1 150 151 struct token_st { 152 char token_str[80]; 153 int token_type; 154 int token_id; 155 _CMPLX token_const; 156 }; 157 158 159 /* CAE fp added MAX_STORES and LOADS */ 160 /* MAX_STORES must be even to make Unix alignment work */ 161 /* TW made dependent on Max_Ops */ 162 163 #define MAX_STORES ((Max_Ops/4)*2) /* at most only half the ops can be stores */ 164 #define MAX_LOADS ((unsigned)(Max_Ops*.8)) /* and 80% can be loads */ 165 /* PB 901103 made some of the following static for safety */ 166 167 static struct PEND_OP far *o; 168 169 #if 0
170 static void ops_allocate(void); 171 static void vars_allocate(void);
172 #endif 173 174 struct var_list_st { 175 char name[34]; 176 struct var_list_st far * next_item; 177 } far * var_list; 178 179 struct const_list_st { 180 _CMPLX complex_const; 181 struct const_list_st far * next_item; 182 } far * complx_list, far * real_list; 183 184 static void parser_allocate(void); 185 186 union Arg *Arg1, *Arg2; 187 /* PB 910417 removed unused "a" array */ 188 189 /* CAE fp made some of the following non-static for PARSERA.ASM */ 190 /* Some of these variables should be renamed for safety */ 191 union Arg s[20], far * far *Store, far * far *Load; /* static CAE fp */ 192 int StoPtr, LodPtr, OpPtr; /* static CAE fp */ 193 int var_count; 194 int complx_count; 195 int real_count; 196 197 198 void (far * far *f)(void) = (void(far * far *)(void))0; /* static CAE fp */ 199 200 short int ismand = 1; 201 202 unsigned int posp, vsp, LastOp; /* CAE fp made non-static */ 203 static unsigned int n, NextOp, InitN; 204 static int paren, ExpectingArg; 205 struct ConstArg far *v = (struct ConstArg far *)0; /* was static CAE fp */ 206 int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp; /* was static CAE fp */ 207 static int Delta16; 208 double fgLimit; /* TIW 05-04-91 */ 209 static double fg; 210 static int ShiftBack; /* TIW 06-18-90 */ 211 static int SetRandom; /* MCP 11-21-91 */ 212 static int Randomized; 213 static unsigned long RandNum; 214 short uses_p1, uses_p2, uses_p3, uses_p4, uses_p5, uses_jump; 215 short uses_ismand; 216 unsigned int chars_in_formula; 217 218 #ifndef XFRACT 219 #define ChkLongDenom(denom)\ 220 if ((denom == 0 || overflow) && save_release > 1920) {\ 221 overflow = 1;\ 222 return;\ 223 }\ 224 else if (denom == 0)\ 225 return 226 #endif 227 228 #define ChkFloatDenom(denom)\ 229 if (fabs(denom) <= DBL_MIN) {\ 230 if (save_release > 1920) overflow = 1;\ 231 return;\ 232 } 233 234 #define LastSqr v[4].a 235 236 #if (_MSC_VER >= 700) 237 #pragma code_seg ("parser1_text") /* place following in an overlay */ 238 #endif 239 240 /* ParseErrs() defines; all calls to ParseErrs(), or any variable which will 241 be used as the argument in a call to ParseErrs(), should use one of these 242 defines. 243 */ 244 245 #define PE_NO_ERRORS_FOUND -1 246 #define PE_SHOULD_BE_ARGUMENT 0 247 #define PE_SHOULD_BE_OPERATOR 1 248 #define PE_NEED_A_MATCHING_OPEN_PARENS 2 249 #define PE_NEED_MORE_CLOSE_PARENS 3 250 #define PE_UNDEFINED_OPERATOR 4 251 #define PE_UNDEFINED_FUNCTION 5 252 #define PE_TABLE_OVERFLOW 6 253 #define PE_NO_MATCH_RIGHT_PAREN 7 254 #define PE_NO_LEFT_BRACKET_FIRST_LINE 8 255 #define PE_UNEXPECTED_EOF 9 256 #define PE_INVALID_SYM_USING_NOSYM 10 257 #define PE_FORMULA_TOO_LARGE 11 258 #define PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA 12 259 #define PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED 13 260 #define PE_JUMP_NOT_FIRST 14 261 #define PE_NO_CHAR_AFTER_THIS_JUMP 15 262 #define PE_JUMP_NEEDS_BOOLEAN 16 263 #define PE_ENDIF_REQUIRED_AFTER_ELSE 17 264 #define PE_ENDIF_WITH_NO_IF 18 265 #define PE_MISPLACED_ELSE_OR_ELSEIF 19 266 #define PE_UNMATCHED_IF_IN_INIT_SECTION 20 267 #define PE_IF_WITH_NO_ENDIF 21 268 #define PE_ERROR_IN_PARSING_JUMP_STATEMENTS 22 269 #define PE_TOO_MANY_JUMPS 23 270 #define PE_FORMULA_NAME_TOO_LARGE 24 271 #define PE_ILLEGAL_ASSIGNMENT 25 272 #define PE_ILLEGAL_VAR_NAME 26 273 #define PE_INVALID_CONST 27 274 #define PE_ILLEGAL_CHAR 28 275 #define PE_NESTING_TO_DEEP 29 276 #define PE_UNMATCHED_MODULUS 30 277 #define PE_FUNC_USED_AS_VAR 31 278 #define PE_NO_NEG_AFTER_EXPONENT 32 279 #define PE_TOKEN_TOO_LONG 33 280 #define PE_SECOND_COLON 34 281 #define PE_INVALID_CALL_TO_PARSEERRS 35 282 283 static char far *ParseErrs(int which) 284 { 285 int lasterr; 286 static FCODE e0[] = {"Should be an Argument"}; 287 static FCODE e1[] = {"Should be an Operator"}; 288 static FCODE e2[] = {"')' needs a matching '('"}; 289 static FCODE e3[] = {"Need more ')'"}; 290 static FCODE e4[] = {"Undefined Operator"}; 291 static FCODE e5[] = {"Undefined Function"}; 292 static FCODE e6[] = {"Table overflow"}; 293 static FCODE e7[] = {"Didn't find matching ')' in symmetry declaration"}; 294 static FCODE e8[] = {"No '{' found on first line"}; 295 static FCODE e9[] = {"Unexpected EOF!"}; 296 static FCODE e10[] = {"Symmetry below is invalid, will use NOSYM"}; 297 static FCODE e11[] = {"Formula is too large"}; 298 static FCODE e12[] = {"Insufficient memory to run fractal type 'formula'"}; 299 static FCODE e13[] = {"Could not open file where formula located"}; 300 static FCODE e14[] = {"No characters may precede jump instruction"}; 301 static FCODE e15[] = {"No characters may follow this jump instruction"}; 302 static FCODE e16[] = {"Jump instruction missing required (boolean argument)"}; 303 static FCODE e17[] = {"Next jump after \"else\" must be \"endif\""}; 304 static FCODE e18[] = {"\"endif\" has no matching \"if\""}; 305 static FCODE e19[] = {"Misplaced \"else\" or \"elseif()\""}; 306 static FCODE e20[] = {"\"if()\" in initialization has no matching \"endif\""}; 307 static FCODE e21[] = {"\"if()\" has no matching \"endif\""}; 308 static FCODE e22[] = {"Error in parsing jump statements"}; 309 static FCODE e23[] = {"Formula has too many jump commands"}; 310 static FCODE e24[] = {"Formula name has too many characters"}; 311 static FCODE e25[] = {"Only variables are allowed to left of assignment"}; 312 static FCODE e26[] = {"Illegal variable name"}; 313 static FCODE e27[] = {"Invalid constant expression"}; 314 static FCODE e28[] = {"This character not supported by parser"}; 315 static FCODE e29[] = {"Nesting of parentheses exceeds maximum depth"}; 316 static FCODE e30[] = {"Unmatched modulus operator \"|\" in this expression"}; /*last one */ 317 static FCODE e31[] = {"Can't use function name as variable"}; 318 static FCODE e32[] = {"Negative exponent must be enclosed in parens"}; 319 static FCODE e33[] = {"Variable or constant exceeds 32 character limit"}; 320 static FCODE e34[] = {"Only one \":\" permitted in a formula"}; 321 static FCODE e35[] = {"Invalid ParseErrs code"}; 322 static PFCODE ErrStrings[] = { e0,e1,e2,e3,e4,e5, 323 e6,e7,e8,e9,e10, 324 e11,e12,e13,e14,e15, 325 e16,e17,e18,e19,e20, 326 e21,e22,e23,e24,e25, 327 e26, e27, e28, e29, e30, 328 e31, e32, e33, e34, e35 329 }; 330 lasterr = sizeof(ErrStrings)/sizeof(ErrStrings[0]) - 1; 331 if(which > lasterr) 332 which = lasterr; 333 return((char far *)ErrStrings[which]); 334 } 335 336 #if (_MSC_VER >= 700) 337 #pragma code_seg () /* back to normal segment */ 338 #endif 339 340 /* use the following when only float functions are implemented to 341 get MP math and Integer math */ 342 343 #ifndef XFRACT 344 #define FUNCT 345 #ifdef FUNCT /* use function form save space - isn't really slower */ 346 347 #if (_MSC_VER >= 700) 348 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 349 #endif 350 static void mStkFunct(void (*fct)(void)) /* call lStk via dStk */ 351 { 352 Arg1->d = MPC2cmplx(Arg1->m); 353 (*fct)(); 354 Arg1->m = cmplx2MPC(Arg1->d); 355 } 356 #if (_MSC_VER >= 700) 357 #pragma code_seg () /* back to normal segment */ 358 #endif 359 360 static void lStkFunct(void (*fct)(void)) /* call lStk via dStk */ 361 { 362 double y; 363 /* 364 intermediate variable needed for safety because of 365 different size of double and long in Arg union 366 */ 367 y = (double)Arg1->l.y / fg; 368 Arg1->d.x = (double)Arg1->l.x / fg; 369 Arg1->d.y = y; 370 (*fct)(); 371 if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) { 372 Arg1->l.x = (long)(Arg1->d.x * fg); 373 Arg1->l.y = (long)(Arg1->d.y * fg); 374 } 375 else 376 overflow = 1; 377 }
378 #else /* use Macro form for (?) greater speed */ 379 /* call lStk via dStk */ 380 #define mStkFunct(fct) \ 381 Arg1->d = MPC2cmplx(Arg1->m);\ 382 (*fct)();\ 383 Arg1->m = cmplx2MPC(Arg1->d); 384 385 386 /* call lStk via dStk */ 387 #define lStkFunct(fct) {\ 388 double y;\ 389 y = (double)Arg1->l.y / fg;\ 390 Arg1->d.x = (double)Arg1->l.x / fg;\ 391 Arg1->d.y = y;\ 392 (*fct)();\ 393 if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {\ 394 Arg1->l.x = (long)(Arg1->d.x * fg);\ 395 Arg1->l.y = (long)(Arg1->d.y * fg);\ 396 }\ 397 else\ 398 overflow = 1;\ 399 } 400 401
402 #endif 403 404 #endif 405 406 /* Random number code, MCP 11-21-91 */ 407 408 unsigned long NewRandNum(void) 409 { 410 return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum); 411 } 412 413 void lRandom(void) 414 { 415 v[7].a.l.x = NewRandNum() >> (32 - bitshift); 416 v[7].a.l.y = NewRandNum() >> (32 - bitshift); 417 } 418 419 void dRandom(void) 420 { 421 long x, y; 422 423 /* Use the same algorithm as for fixed math so that they will generate 424 the same fractals when the srand() function is used. */ 425 x = NewRandNum() >> (32 - bitshift); 426 y = NewRandNum() >> (32 - bitshift); 427 v[7].a.d.x = ((double)x / (1L << bitshift)); 428 v[7].a.d.y = ((double)y / (1L << bitshift)); 429 430 } 431 432 #ifndef XFRACT 433 void mRandom(void) 434 { 435 long x, y; 436 437 /* Use the same algorithm as for fixed math so that they will generate 438 the same fractals when the srand() function is used. */ 439 x = NewRandNum() >> (32 - bitshift); 440 y = NewRandNum() >> (32 - bitshift); 441 v[7].a.m.x = *fg2MP(x, bitshift); 442 v[7].a.m.y = *fg2MP(y, bitshift); 443 } 444 #endif 445 446 void SetRandFnct(void) 447 { 448 unsigned Seed; 449 450 if(!SetRandom) 451 RandNum = Arg1->l.x ^ Arg1->l.y; 452 453 Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16); 454 srand(Seed); 455 SetRandom = 1; 456 457 /* Clear out the seed */ 458 NewRandNum(); 459 NewRandNum(); 460 NewRandNum(); 461 } 462 463 void RandomSeed(void) 464 { 465 time_t ltime; 466 467 /* Use the current time to randomize the random number sequence. */ 468 time(&ltime); 469 srand((unsigned int)ltime); 470 471 NewRandNum(); 472 NewRandNum(); 473 NewRandNum(); 474 Randomized = 1; 475 } 476 477 #ifndef XFRACT 478 void lStkSRand(void) 479 { 480 SetRandFnct(); 481 lRandom(); 482 Arg1->l = v[7].a.l; 483 } 484 #endif 485 486 #ifndef XFRACT 487 void mStkSRand(void) 488 { 489 Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp; 490 Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp; 491 SetRandFnct(); 492 mRandom(); 493 Arg1->m = v[7].a.m; 494 } 495 #endif 496 497 void dStkSRand(void) 498 { 499 Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift)); 500 Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift)); 501 SetRandFnct(); 502 dRandom(); 503 Arg1->d = v[7].a.d; 504 } 505 506 void (*StkSRand)(void) = dStkSRand; 507 508 509 void dStkLodDup() 510 { 511 Arg1+=2; 512 Arg2+=2; 513 *Arg2 = *Arg1 = *Load[LodPtr]; 514 LodPtr+=2; 515 } 516 517 void dStkLodSqr() 518 { 519 Arg1++; 520 Arg2++; 521 Arg1->d.y = Load[LodPtr]->d.x * Load[LodPtr]->d.y * 2.0; 522 Arg1->d.x = (Load[LodPtr]->d.x * Load[LodPtr]->d.x) - (Load[LodPtr]->d.y * Load[LodPtr]->d.y); 523 LodPtr++; 524 } 525 526 void dStkLodSqr2() 527 { 528 Arg1++; 529 Arg2++; 530 LastSqr.d.x = Load[LodPtr]->d.x * Load[LodPtr]->d.x; 531 LastSqr.d.y = Load[LodPtr]->d.y * Load[LodPtr]->d.y; 532 Arg1->d.y = Load[LodPtr]->d.x * Load[LodPtr]->d.y * 2.0; 533 Arg1->d.x = LastSqr.d.x - LastSqr.d.y; 534 LastSqr.d.x += LastSqr.d.y; 535 LastSqr.d.y = 0; 536 LodPtr++; 537 } 538 539 void dStkStoDup(){} 540 void dStkStoSqr(){} 541 void dStkStoSqr0(){} 542 543 void dStkLodDbl() 544 { 545 Arg1++; 546 Arg2++; 547 Arg1->d.x = Load[LodPtr]->d.x * 2.0; 548 Arg1->d.y = Load[LodPtr]->d.y * 2.0; 549 LodPtr++; 550 } 551 552 void dStkStoDbl(){} 553 void dStkReal2(){} 554 555 void dStkSqr0() 556 { 557 LastSqr.d.y = Arg1->d.y * Arg1->d.y; /* use LastSqr as temp storage */ 558 Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0; 559 Arg1->d.x = Arg1->d.x * Arg1->d.x - LastSqr.d.y; 560 } 561 562 563 void dStkSqr3() 564 { 565 Arg1->d.x = Arg1->d.x * Arg1->d.x; 566 } 567 568 569 570 void dStkAbs(void) { 571 Arg1->d.x = fabs(Arg1->d.x); 572 Arg1->d.y = fabs(Arg1->d.y); 573 } 574 575 #ifndef XFRACT 576 void mStkAbs(void) { 577 if(Arg1->m.x.Exp < 0) 578 Arg1->m.x.Exp = -Arg1->m.x.Exp; 579 if(Arg1->m.y.Exp < 0) 580 Arg1->m.y.Exp = -Arg1->m.y.Exp; 581 } 582 583 void lStkAbs(void) { 584 Arg1->l.x = labs(Arg1->l.x); 585 Arg1->l.y = labs(Arg1->l.y); 586 } 587 #endif 588 589 void (*StkAbs)(void) = dStkAbs; 590 591 void dStkSqr(void) { 592 LastSqr.d.x = Arg1->d.x * Arg1->d.x; 593 LastSqr.d.y = Arg1->d.y * Arg1->d.y; 594 Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0; 595 Arg1->d.x = LastSqr.d.x - LastSqr.d.y; 596 LastSqr.d.x += LastSqr.d.y; 597 LastSqr.d.y = 0; 598 } 599 600 #ifndef XFRACT 601 void mStkSqr(void) { 602 LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x); 603 LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y); 604 Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y); 605 Arg1->m.y.Exp++; 606 Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y); 607 LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y); 608 LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0); 609 } 610 611 void lStkSqr(void) { 612 LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift); 613 LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift); 614 Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1; 615 Arg1->l.x = LastSqr.l.x - LastSqr.l.y; 616 LastSqr.l.x += LastSqr.l.y; 617 LastSqr.l.y = 0L; 618 } 619 #endif 620 621 void (*StkSqr)(void) = dStkSqr; 622 623 void dStkAdd(void) { 624 Arg2->d.x += Arg1->d.x; 625 Arg2->d.y += Arg1->d.y; 626 Arg1--; 627 Arg2--; 628 } 629 630 #ifndef XFRACT 631 632 #if (_MSC_VER >= 700) 633 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 634 #endif 635 void mStkAdd(void) { 636 Arg2->m = MPCadd(Arg2->m, Arg1->m); 637 Arg1--; 638 Arg2--; 639 } 640 #if (_MSC_VER >= 700) 641 #pragma code_seg () /* back to normal segment */ 642 #endif 643 644 void lStkAdd(void) { 645 Arg2->l.x += Arg1->l.x; 646 Arg2->l.y += Arg1->l.y; 647 Arg1--; 648 Arg2--; 649 } 650 #endif 651 652 void (*StkAdd)(void) = dStkAdd; 653 654 void dStkSub(void) { 655 Arg2->d.x -= Arg1->d.x; 656 Arg2->d.y -= Arg1->d.y; 657 Arg1--; 658 Arg2--; 659 } 660 661 #ifndef XFRACT 662 #if (_MSC_VER >= 700) 663 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 664 #endif 665 void mStkSub(void) { 666 Arg2->m = MPCsub(Arg2->m, Arg1->m); 667 Arg1--; 668 Arg2--; 669 } 670 #if (_MSC_VER >= 700) 671 #pragma code_seg () /* back to normal segment */ 672 #endif 673 674 void lStkSub(void) { 675 Arg2->l.x -= Arg1->l.x; 676 Arg2->l.y -= Arg1->l.y; 677 Arg1--; 678 Arg2--; 679 } 680 #endif 681 682 void (*StkSub)(void) = dStkSub; 683 684 void dStkConj(void) { 685 Arg1->d.y = -Arg1->d.y; 686 } 687 688 #ifndef XFRACT 689 void mStkConj(void) { 690 Arg1->m.y.Exp ^= 0x8000; 691 } 692 693 void lStkConj(void) { 694 Arg1->l.y = -Arg1->l.y; 695 } 696 #endif 697 698 void (*StkConj)(void) = dStkConj; 699 700 void dStkFloor(void) { 701 Arg1->d.x = floor(Arg1->d.x); 702 Arg1->d.y = floor(Arg1->d.y); 703 } 704 705 #ifndef XFRACT 706 void mStkFloor(void) { 707 mStkFunct(dStkFloor); /* call lStk via dStk */ 708 } 709 710 void lStkFloor(void) { 711 /* 712 * Kill fractional part. This operation truncates negative numbers 713 * toward negative infinity as desired. 714 */ 715 Arg1->l.x = (Arg1->l.x) >> bitshift; 716 Arg1->l.y = (Arg1->l.y) >> bitshift; 717 Arg1->l.x = (Arg1->l.x) << bitshift; 718 Arg1->l.y = (Arg1->l.y) << bitshift; 719 } 720 #endif 721 722 void (*StkFloor)(void) = dStkFloor; 723 724 void dStkCeil(void) { 725 Arg1->d.x = ceil(Arg1->d.x); 726 Arg1->d.y = ceil(Arg1->d.y); 727 } 728 729 #ifndef XFRACT 730 void mStkCeil(void) { 731 mStkFunct(dStkCeil); /* call lStk via dStk */ 732 } 733 734 void lStkCeil(void) { 735 /* the shift operation does the "floor" operation, so we 736 negate everything before the operation */ 737 Arg1->l.x = (-Arg1->l.x) >> bitshift; 738 Arg1->l.y = (-Arg1->l.y) >> bitshift; 739 Arg1->l.x = -((Arg1->l.x) << bitshift); 740 Arg1->l.y = -((Arg1->l.y) << bitshift); 741 } 742 #endif 743 744 void (*StkCeil)(void) = dStkCeil; 745 746 void dStkTrunc(void) { 747 Arg1->d.x = (int)(Arg1->d.x); 748 Arg1->d.y = (int)(Arg1->d.y); 749 } 750 751 #ifndef XFRACT 752 void mStkTrunc(void) { 753 mStkFunct(dStkTrunc); /* call lStk via dStk */ 754 } 755 756 void lStkTrunc(void) { 757 /* shifting and shifting back truncates positive numbers, 758 so we make the numbers positive */ 759 int signx, signy; 760 signx = sign(Arg1->l.x); 761 signy = sign(Arg1->l.y); 762 Arg1->l.x = labs(Arg1->l.x); 763 Arg1->l.y = labs(Arg1->l.y); 764 Arg1->l.x = (Arg1->l.x) >> bitshift; 765 Arg1->l.y = (Arg1->l.y) >> bitshift; 766 Arg1->l.x = (Arg1->l.x) << bitshift; 767 Arg1->l.y = (Arg1->l.y) << bitshift; 768 Arg1->l.x = signx*Arg1->l.x; 769 Arg1->l.y = signy*Arg1->l.y; 770 } 771 #endif 772 773 void (*StkTrunc)(void) = dStkTrunc; 774 775 void dStkRound(void) { 776 Arg1->d.x = floor(Arg1->d.x+.5); 777 Arg1->d.y = floor(Arg1->d.y+.5); 778 } 779 780 #ifndef XFRACT 781 void mStkRound(void) { 782 mStkFunct(dStkRound); /* call lStk via dStk */ 783 } 784 785 void lStkRound(void) { 786 /* Add .5 then truncate */ 787 Arg1->l.x += (1L<<bitshiftless1); 788 Arg1->l.y += (1L<<bitshiftless1); 789 lStkFloor(); 790 } 791 #endif 792 793 void (*StkRound)(void) = dStkRound; 794 795 void dStkZero(void) { 796 Arg1->d.y = Arg1->d.x = 0.0; 797 } 798 799 #ifndef XFRACT 800 void mStkZero(void) { 801 Arg1->m.x.Mant = Arg1->m.x.Exp = 0; 802 Arg1->m.y.Mant = Arg1->m.y.Exp = 0; 803 } 804 805 void lStkZero(void) { 806 Arg1->l.y = Arg1->l.x = 0; 807 } 808 #endif 809 810 void (*StkZero)(void) = dStkZero; 811 812 void dStkOne(void) { 813 Arg1->d.x = 1.0; 814 Arg1->d.y = 0.0; 815 } 816 817 #ifndef XFRACT 818 void mStkOne(void) { 819 Arg1->m = MPCone; 820 } 821 822 void lStkOne(void) { 823 Arg1->l.x = (long) fg; 824 Arg1->l.y = 0L; 825 } 826 #endif 827 828 void (*StkOne)(void) = dStkOne; 829 830 831 void dStkReal(void) { 832 Arg1->d.y = 0.0; 833 } 834 835 #ifndef XFRACT 836 void mStkReal(void) { 837 Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); 838 } 839 840 void lStkReal(void) { 841 Arg1->l.y = 0l; 842 } 843 #endif 844 845 void (*StkReal)(void) = dStkReal; 846 847 void dStkImag(void) { 848 Arg1->d.x = Arg1->d.y; 849 Arg1->d.y = 0.0; 850 } 851 852 #ifndef XFRACT 853 void mStkImag(void) { 854 Arg1->m.x = Arg1->m.y; 855 Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); 856 } 857 858 void lStkImag(void) { 859 Arg1->l.x = Arg1->l.y; 860 Arg1->l.y = 0l; 861 } 862 #endif 863 864 void (*StkImag)(void) = dStkImag; 865 866 void dStkNeg(void) { 867 Arg1->d.x = -Arg1->d.x; 868 Arg1->d.y = -Arg1->d.y; 869 } 870 871 #ifndef XFRACT 872 void mStkNeg(void) { 873 Arg1->m.x.Exp ^= 0x8000; 874 Arg1->m.y.Exp ^= 0x8000; 875 } 876 877 void lStkNeg(void) { 878 Arg1->l.x = -Arg1->l.x; 879 Arg1->l.y = -Arg1->l.y; 880 } 881 #endif 882 883 void (*StkNeg)(void) = dStkNeg; 884 885 void dStkMul(void) { 886 FPUcplxmul(&Arg2->d, &Arg1->d, &Arg2->d); 887 Arg1--; 888 Arg2--; 889 } 890 891 #ifndef XFRACT 892 #if (_MSC_VER >= 700) 893 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 894 #endif 895 void mStkMul(void) { 896 Arg2->m = MPCmul(Arg2->m, Arg1->m); 897 Arg1--; 898 Arg2--; 899 } 900 #if (_MSC_VER >= 700) 901 #pragma code_seg () /* back to normal segment */ 902 #endif 903 904 void lStkMul(void) { 905 long x, y; 906 907 x = multiply(Arg2->l.x, Arg1->l.x, bitshift) - 908 multiply(Arg2->l.y, Arg1->l.y, bitshift); 909 y = multiply(Arg2->l.y, Arg1->l.x, bitshift) + 910 multiply(Arg2->l.x, Arg1->l.y, bitshift); 911 Arg2->l.x = x; 912 Arg2->l.y = y; 913 Arg1--; 914 Arg2--; 915 } 916 #endif 917 918 void (*StkMul)(void) = dStkMul; 919 920 void dStkDiv(void) { 921 FPUcplxdiv(&Arg2->d, &Arg1->d, &Arg2->d); 922 Arg1--; 923 Arg2--; 924 } 925 926 #ifndef XFRACT 927 #if (_MSC_VER >= 700) 928 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 929 #endif 930 void mStkDiv(void) { 931 Arg2->m = MPCdiv(Arg2->m, Arg1->m); 932 Arg1--; 933 Arg2--; 934 } 935 #if (_MSC_VER >= 700) 936 #pragma code_seg () /* back to normal segment */ 937 #endif 938 939 void lStkDiv(void) { 940 long x, y, mod, x2, y2; 941 942 mod = multiply(Arg1->l.x, Arg1->l.x, bitshift) + 943 multiply(Arg1->l.y, Arg1->l.y, bitshift); 944 x = divide(Arg1->l.x, mod, bitshift); 945 y = -divide(Arg1->l.y, mod, bitshift); 946 /* pb 900617 changed next 4 lines to use x2,y2 instead of x,y */ 947 x2 = multiply(Arg2->l.x, x, bitshift) - multiply(Arg2->l.y, y, bitshift); 948 y2 = multiply(Arg2->l.y, x, bitshift) + multiply(Arg2->l.x, y, bitshift); 949 Arg2->l.x = x2; 950 Arg2->l.y = y2; 951 Arg1--; 952 Arg2--; 953 } 954 #endif 955 956 void (*StkDiv)(void) = dStkDiv; 957 958 void dStkMod(void) { 959 Arg1->d.x = (Arg1->d.x * Arg1->d.x) + (Arg1->d.y * Arg1->d.y); 960 Arg1->d.y = 0.0; 961 } 962 963 #ifndef XFRACT 964 #if (_MSC_VER >= 700) 965 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 966 #endif 967 void mStkMod(void) { 968 Arg1->m.x = MPCmod(Arg1->m); 969 Arg1->m.y.Mant = (long)(Arg1->m.y.Exp = 0); 970 } 971 #if (_MSC_VER >= 700) 972 #pragma code_seg () /* back to normal segment */ 973 #endif 974 975 void lStkMod(void) { 976 /* Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) + */ 977 /* multiply(Arg2->l.y, Arg1->l.y, bitshift); */ 978 /*** I don't understand how this ever worked correctly! JCO 12/31/94 ***/ 979 Arg1->l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift) + 980 multiply(Arg1->l.y, Arg1->l.y, bitshift); 981 if(Arg1->l.x < 0) 982 overflow = 1; 983 Arg1->l.y = 0L; 984 } 985 986 void lStkModOld(void) { 987 Arg1->l.x = multiply(Arg2->l.x, Arg1->l.x, bitshift) + 988 multiply(Arg2->l.y, Arg1->l.y, bitshift); 989 if(Arg1->l.x < 0) 990 overflow = 1; 991 Arg1->l.y = 0L; 992 } 993 #endif 994 995 void (*StkMod)(void) = dStkMod; 996 997 void StkSto(void) { 998 *Store[StoPtr++] = *Arg1; 999 } 1000 1001 void (*PtrStkSto)(void) = StkSto; 1002 1003 void StkLod(void) { 1004 Arg1++; 1005 Arg2++; 1006 *Arg1 = *Load[LodPtr++]; 1007 } 1008 1009 void (*PtrStkLod)(void) = StkLod; 1010 1011 void StkClr(void) { 1012 s[0] = *Arg1; 1013 Arg1 = &s[0]; 1014 Arg2 = Arg1; 1015 Arg2--; 1016 } 1017 1018 void (*PtrStkClr)(void) = StkClr; 1019 1020 /* MCP 4-9-91, Added Flip() */ 1021 1022 void dStkFlip(void) { 1023 double t; 1024 1025 t = Arg1->d.x; 1026 Arg1->d.x = Arg1->d.y; 1027 Arg1->d.y = t; 1028 } 1029 1030 #ifndef XFRACT 1031 void mStkFlip(void) { 1032 struct MP t; 1033 1034 t = Arg1->m.x; 1035 Arg1->m.x = Arg1->m.y; 1036 Arg1->m.y = t; 1037 } 1038 1039 void lStkFlip(void) { 1040 long t; 1041 1042 t = Arg1->l.x; 1043 Arg1->l.x = Arg1->l.y; 1044 Arg1->l.y = t; 1045 } 1046 #endif 1047 1048 void (*StkFlip)(void) = dStkFlip; 1049 1050 void dStkSin(void) { 1051 double sinx, cosx, sinhy, coshy; 1052 1053 FPUsincos(&Arg1->d.x, &sinx, &cosx); 1054 FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); 1055 Arg1->d.x = sinx*coshy; 1056 Arg1->d.y = cosx*sinhy; 1057 } 1058 1059 #ifndef XFRACT 1060 void mStkSin(void) { 1061 mStkFunct(dStkSin); /* call lStk via dStk */ 1062 } 1063 1064 void lStkSin(void) { 1065 long x, y, sinx, cosx, sinhy, coshy; 1066 x = Arg1->l.x >> Delta16; 1067 y = Arg1->l.y >> Delta16; 1068 SinCos086(x, &sinx, &cosx); 1069 SinhCosh086(y, &sinhy, &coshy); 1070 Arg1->l.x = multiply(sinx, coshy, ShiftBack); /* TIW 06-18-90 */ 1071 Arg1->l.y = multiply(cosx, sinhy, ShiftBack); /* TIW 06-18-90 */ 1072 } 1073 #endif 1074 1075 void (*StkSin)(void) = dStkSin; 1076 1077 /* The following functions are supported by both the parser and for fn 1078 variable replacement. TIW 04-22-91 */ 1079 1080 void dStkTan(void) { 1081 double sinx, cosx, sinhy, coshy, denom; 1082 Arg1->d.x *= 2; 1083 Arg1->d.y *= 2; 1084 FPUsincos(&Arg1->d.x, &sinx, &cosx); 1085 FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); 1086 denom = cosx + coshy; 1087 ChkFloatDenom(denom); 1088 Arg1->d.x = sinx/denom; 1089 Arg1->d.y = sinhy/denom; 1090 } 1091 1092 #ifndef XFRACT 1093 void mStkTan(void) { 1094 mStkFunct(dStkTan); /* call lStk via dStk */ 1095 } 1096 1097 void lStkTan(void) { 1098 long x, y, sinx, cosx, sinhy, coshy, denom; 1099 x = Arg1->l.x >> Delta16; 1100 x = x << 1; 1101 y = Arg1->l.y >> Delta16; 1102 y = y << 1; 1103 SinCos086(x, &sinx, &cosx); 1104 SinhCosh086(y, &sinhy, &coshy); 1105 denom = cosx + coshy; 1106 ChkLongDenom(denom); 1107 Arg1->l.x = divide(sinx,denom,bitshift); 1108 Arg1->l.y = divide(sinhy,denom,bitshift); 1109 } 1110 #endif 1111 1112 void (*StkTan)(void) = dStkTan; 1113 1114 void dStkTanh(void) { 1115 double siny, cosy, sinhx, coshx, denom; 1116 Arg1->d.x *= 2; 1117 Arg1->d.y *= 2; 1118 FPUsincos(&Arg1->d.y, &siny, &cosy); 1119 FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); 1120 denom = coshx + cosy; 1121 ChkFloatDenom(denom); 1122 Arg1->d.x = sinhx/denom; 1123 Arg1->d.y = siny/denom; 1124 } 1125 1126 #ifndef XFRACT 1127 void mStkTanh(void) { 1128 mStkFunct(dStkTanh); /* call lStk via dStk */ 1129 } 1130 1131 void lStkTanh(void) { 1132 long x, y, siny, cosy, sinhx, coshx, denom; 1133 x = Arg1->l.x >> Delta16; 1134 x = x << 1; 1135 y = Arg1->l.y >> Delta16; 1136 y = y << 1; 1137 SinCos086(y, &siny, &cosy); 1138 SinhCosh086(x, &sinhx, &coshx); 1139 denom = coshx + cosy; 1140 ChkLongDenom(denom); 1141 Arg1->l.x = divide(sinhx,denom,bitshift); 1142 Arg1->l.y = divide(siny,denom,bitshift); 1143 } 1144 #endif 1145 1146 void (*StkTanh)(void) = dStkTanh; 1147 1148 void dStkCoTan(void) { 1149 double sinx, cosx, sinhy, coshy, denom; 1150 Arg1->d.x *= 2; 1151 Arg1->d.y *= 2; 1152 FPUsincos(&Arg1->d.x, &sinx, &cosx); 1153 FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); 1154 denom = coshy - cosx; 1155 ChkFloatDenom(denom); 1156 Arg1->d.x = sinx/denom; 1157 Arg1->d.y = -sinhy/denom; 1158 } 1159 1160 #ifndef XFRACT 1161 void mStkCoTan(void) { 1162 mStkFunct(dStkCoTan); /* call lStk via dStk */ 1163 } 1164 1165 void lStkCoTan(void) { 1166 long x, y, sinx, cosx, sinhy, coshy, denom; 1167 x = Arg1->l.x >> Delta16; 1168 x = x << 1; 1169 y = Arg1->l.y >> Delta16; 1170 y = y << 1; 1171 SinCos086(x, &sinx, &cosx); 1172 SinhCosh086(y, &sinhy, &coshy); 1173 denom = coshy - cosx; 1174 ChkLongDenom(denom); 1175 Arg1->l.x = divide(sinx,denom,bitshift); 1176 Arg1->l.y = -divide(sinhy,denom,bitshift); 1177 } 1178 #endif 1179 1180 void (*StkCoTan)(void) = dStkCoTan; 1181 1182 void dStkCoTanh(void) { 1183 double siny, cosy, sinhx, coshx, denom; 1184 Arg1->d.x *= 2; 1185 Arg1->d.y *= 2; 1186 FPUsincos(&Arg1->d.y, &siny, &cosy); 1187 FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); 1188 denom = coshx - cosy; 1189 ChkFloatDenom(denom); 1190 Arg1->d.x = sinhx/denom; 1191 Arg1->d.y = -siny/denom; 1192 } 1193 1194 #ifndef XFRACT 1195 void mStkCoTanh(void) { 1196 mStkFunct(dStkCoTanh); /* call lStk via dStk */ 1197 } 1198 1199 void lStkCoTanh(void) { 1200 long x, y, siny, cosy, sinhx, coshx, denom; 1201 x = Arg1->l.x >> Delta16; 1202 x = x << 1; 1203 y = Arg1->l.y >> Delta16; 1204 y = y << 1; 1205 SinCos086(y, &siny, &cosy); 1206 SinhCosh086(x, &sinhx, &coshx); 1207 denom = coshx - cosy; 1208 ChkLongDenom(denom); 1209 Arg1->l.x = divide(sinhx,denom,bitshift); 1210 Arg1->l.y = -divide(siny,denom,bitshift); 1211 } 1212 #endif 1213 1214 void (*StkCoTanh)(void) = dStkCoTanh; 1215 1216 /* The following functions are not directly used by the parser - support 1217 for the parser was not provided because the existing parser language 1218 represents these quite easily. They are used for fn variable support 1219 in miscres.c but are placed here because they follow the pattern of 1220 the other parser functions. TIW 04-22-91 */ 1221 1222 void dStkRecip(void) { 1223 double mod; 1224 mod =Arg1->d.x * Arg1->d.x + Arg1->d.y * Arg1->d.y; 1225 ChkFloatDenom(mod); 1226 Arg1->d.x = Arg1->d.x/mod; 1227 Arg1->d.y = -Arg1->d.y/mod; 1228 } 1229 1230 #ifndef XFRACT 1231 void mStkRecip(void) { 1232 struct MP mod; 1233 mod = *MPadd(*MPmul(Arg1->m.x, Arg1->m.x),*MPmul(Arg1->m.y, Arg1->m.y)); 1234 if(mod.Mant == 0L) { 1235 overflow = 1; 1236 return; 1237 } 1238 Arg1->m.x = *MPdiv(Arg1->m.x,mod); 1239 Arg1->m.y = *MPdiv(Arg1->m.y,mod); 1240 Arg1->m.y.Exp ^= 0x8000; 1241 } 1242 1243 void lStkRecip(void) { 1244 long mod; 1245 mod = multiply(Arg1->l.x,Arg1->l.x,bitshift) 1246 + multiply(Arg1->l.y,Arg1->l.y,bitshift); 1247 if(save_release > 1920) { 1248 ChkLongDenom(mod); 1249 } else if(mod<=0L) return; 1250 Arg1->l.x = divide(Arg1->l.x,mod,bitshift); 1251 Arg1->l.y = -divide(Arg1->l.y,mod,bitshift); 1252 } 1253 #endif 1254 1255 void StkIdent(void) { /* do nothing - the function Z */ 1256 } 1257 /* End TIW 04-22-91 */ 1258 1259 void dStkSinh(void) { 1260 double siny, cosy, sinhx, coshx; 1261 1262 FPUsincos(&Arg1->d.y, &siny, &cosy); 1263 FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); 1264 Arg1->d.x = sinhx*cosy; 1265 Arg1->d.y = coshx*siny; 1266 } 1267 1268 #ifndef XFRACT 1269 void mStkSinh(void) { 1270 mStkFunct(dStkSinh); /* call lStk via dStk */ 1271 } 1272 1273 void lStkSinh(void) { 1274 long x, y, sinhx, coshx, siny, cosy; 1275 1276 x = Arg1->l.x >> Delta16; 1277 y = Arg1->l.y >> Delta16; 1278 SinCos086(y, &siny, &cosy); 1279 SinhCosh086(x, &sinhx, &coshx); 1280 Arg1->l.x = multiply(cosy, sinhx, ShiftBack); /* TIW 06-18-90 */ 1281 Arg1->l.y = multiply(siny, coshx, ShiftBack); /* TIW 06-18-90 */ 1282 } 1283 #endif 1284 1285 void (*StkSinh)(void) = dStkSinh; 1286 1287 void dStkCos(void) { 1288 double sinx, cosx, sinhy, coshy; 1289 1290 FPUsincos(&Arg1->d.x, &sinx, &cosx); 1291 FPUsinhcosh(&Arg1->d.y, &sinhy, &coshy); 1292 Arg1->d.x = cosx*coshy; 1293 Arg1->d.y = -sinx*sinhy; /* TIW 04-25-91 sign */ 1294 } 1295 1296 #ifndef XFRACT 1297 void mStkCos(void) { 1298 mStkFunct(dStkCos); /* call lStk via dStk */ 1299 } 1300 1301 void lStkCos(void) { 1302 long x, y, sinx, cosx, sinhy, coshy; 1303 1304 x = Arg1->l.x >> Delta16; 1305 y = Arg1->l.y >> Delta16; 1306 SinCos086(x, &sinx, &cosx); 1307 SinhCosh086(y, &sinhy, &coshy); 1308 Arg1->l.x = multiply(cosx, coshy, ShiftBack); /* TIW 06-18-90 */ 1309 Arg1->l.y = -multiply(sinx, sinhy, ShiftBack); /* TIW 04-25-91 sign */ 1310 } 1311 #endif 1312 1313 void (*StkCos)(void) = dStkCos; 1314 1315 /* Bogus version of cos, to replicate bug which was in regular cos till v16: */ 1316 1317 void dStkCosXX(void) { 1318 dStkCos(); 1319 Arg1->d.y = -Arg1->d.y; 1320 } 1321 1322 #ifndef XFRACT 1323 void mStkCosXX(void) { 1324 mStkFunct(dStkCosXX); /* call lStk via dStk */ 1325 } 1326 1327 void lStkCosXX(void) { 1328 lStkCos(); 1329 Arg1->l.y = -Arg1->l.y; 1330 } 1331 #endif 1332 1333 void (*StkCosXX)(void) = dStkCosXX; 1334 1335 void dStkCosh(void) { 1336 double siny, cosy, sinhx, coshx; 1337 1338 FPUsincos(&Arg1->d.y, &siny, &cosy); 1339 FPUsinhcosh(&Arg1->d.x, &sinhx, &coshx); 1340 Arg1->d.x = coshx*cosy; 1341 Arg1->d.y = sinhx*siny; 1342 } 1343 1344 #ifndef XFRACT 1345 void mStkCosh(void) { 1346 mStkFunct(dStkCosh); /* call lStk via dStk */ 1347 } 1348 1349 void lStkCosh(void) { 1350 long x, y, sinhx, coshx, siny, cosy; 1351 1352 x = Arg1->l.x >> Delta16; 1353 y = Arg1->l.y >> Delta16; 1354 SinCos086(y, &siny, &cosy); 1355 SinhCosh086(x, &sinhx, &coshx); 1356 Arg1->l.x = multiply(cosy, coshx, ShiftBack); /* TIW 06-18-90 */ 1357 Arg1->l.y = multiply(siny, sinhx, ShiftBack); /* TIW 06-18-90 */ 1358 } 1359 #endif 1360 1361 void (*StkCosh)(void) = dStkCosh; 1362 1363 /* TIW added arc functions here 11-25-94 */ 1364 1365 void dStkASin(void) { 1366 Arcsinz(Arg1->d, &(Arg1->d)); 1367 } 1368 1369 #ifndef XFRACT 1370 void mStkASin(void) { 1371 mStkFunct(dStkASin); 1372 } 1373 1374 void lStkASin(void) { 1375 lStkFunct(dStkASin); 1376 } 1377 #endif 1378 1379 void (*StkASin)(void) = dStkASin; 1380 1381 void dStkASinh(void) { 1382 Arcsinhz(Arg1->d, &(Arg1->d)); 1383 } 1384 1385 #ifndef XFRACT 1386 void mStkASinh(void) { 1387 mStkFunct(dStkASinh); 1388 } 1389 1390 void lStkASinh(void) { 1391 lStkFunct(dStkASinh); 1392 } 1393 #endif 1394 1395 void (*StkASinh)(void) = dStkASinh; 1396 1397 void dStkACos(void) { 1398 Arccosz(Arg1->d, &(Arg1->d)); 1399 } 1400 1401 #ifndef XFRACT 1402 void mStkACos(void) { 1403 mStkFunct(dStkACos); 1404 } 1405 1406 void lStkACos(void) { 1407 lStkFunct(dStkACos); 1408 } 1409 #endif 1410 1411 void (*StkACos)(void) = dStkACos; 1412 1413 void dStkACosh(void) { 1414 Arccoshz(Arg1->d, &(Arg1->d)); 1415 } 1416 1417 #ifndef XFRACT 1418 void mStkACosh(void) { 1419 mStkFunct(dStkACosh); 1420 } 1421 1422 void lStkACosh(void) { 1423 lStkFunct(dStkACosh); 1424 } 1425 #endif 1426 1427 void (*StkACosh)(void) = dStkACosh; 1428 1429 void dStkATan(void) { 1430 Arctanz(Arg1->d, &(Arg1->d)); 1431 } 1432 1433 #ifndef XFRACT 1434 void mStkATan(void) { 1435 mStkFunct(dStkATan); 1436 } 1437 1438 void lStkATan(void) { 1439 lStkFunct(dStkATan); 1440 } 1441 #endif 1442 1443 void (*StkATan)(void) = dStkATan; 1444 1445 void dStkATanh(void) { 1446 Arctanhz(Arg1->d, &(Arg1->d)); 1447 } 1448 1449 #ifndef XFRACT 1450 void mStkATanh(void) { 1451 mStkFunct(dStkATanh); 1452 } 1453 1454 void lStkATanh(void) { 1455 lStkFunct(dStkATanh); 1456 } 1457 #endif 1458 1459 void (*StkATanh)(void) = dStkATanh; 1460 1461 void dStkSqrt(void) { 1462 Arg1->d = ComplexSqrtFloat(Arg1->d.x, Arg1->d.y); 1463 } 1464 1465 #ifndef XFRACT 1466 void mStkSqrt(void) { 1467 mStkFunct(dStkSqrt); 1468 } 1469 1470 void lStkSqrt(void) { 1471 /* lStkFunct(dStkSqrt); */ 1472 Arg1->l = ComplexSqrtLong(Arg1->l.x, Arg1->l.y); 1473 } 1474 #endif 1475 1476 void (*StkSqrt)(void) = dStkSqrt; 1477 1478 void dStkCAbs(void) { 1479 Arg1->d.x = sqrt(sqr(Arg1->d.x)+sqr(Arg1->d.y)); 1480 Arg1->d.y = 0.0; 1481 } 1482 1483 #ifndef XFRACT 1484 void mStkCAbs(void) { 1485 mStkFunct(dStkCAbs); 1486 } 1487 1488 void lStkCAbs(void) { 1489 lStkFunct(dStkCAbs); 1490 } 1491 #endif 1492 1493 void (*StkCAbs)(void) = dStkCAbs; 1494 1495 /* TIW end arc functions 11-25-94 */ 1496 1497 void dStkLT(void) { 1498 Arg2->d.x = (double)(Arg2->d.x < Arg1->d.x); 1499 Arg2->d.y = 0.0; 1500 Arg1--; 1501 Arg2--; 1502 } 1503 1504 #ifndef XFRACT 1505 void mStkLT(void) { 1506 Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == -1), 0); 1507 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1508 Arg1--; 1509 Arg2--; 1510 } 1511 1512 void lStkLT(void) { 1513 Arg2->l.x = (long)(Arg2->l.x < Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1514 Arg2->l.y = 0l; 1515 Arg1--; 1516 Arg2--; 1517 } 1518 #endif 1519 1520 void (*StkLT)(void) = dStkLT; 1521 1522 void dStkGT(void) { 1523 Arg2->d.x = (double)(Arg2->d.x > Arg1->d.x); 1524 Arg2->d.y = 0.0; 1525 Arg1--; 1526 Arg2--; 1527 } 1528 1529 #ifndef XFRACT 1530 void mStkGT(void) { 1531 Arg2->m.x = *fg2MP((long)(MPcmp(Arg2->m.x, Arg1->m.x) == 1), 0); 1532 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1533 Arg1--; 1534 Arg2--; 1535 } 1536 1537 void lStkGT(void) { 1538 Arg2->l.x = (long)(Arg2->l.x > Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1539 Arg2->l.y = 0l; 1540 Arg1--; 1541 Arg2--; 1542 } 1543 #endif 1544 1545 void (*StkGT)(void) = dStkGT; 1546 1547 void dStkLTE(void) { 1548 Arg2->d.x = (double)(Arg2->d.x <= Arg1->d.x); 1549 Arg2->d.y = 0.0; 1550 Arg1--; 1551 Arg2--; 1552 } 1553 1554 #ifndef XFRACT 1555 void mStkLTE(void) { 1556 int comp; 1557 1558 comp = MPcmp(Arg2->m.x, Arg1->m.x); 1559 Arg2->m.x = *fg2MP((long)(comp == -1 || comp == 0), 0); 1560 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1561 Arg1--; 1562 Arg2--; 1563 } 1564 1565 void lStkLTE(void) { 1566 Arg2->l.x = (long)(Arg2->l.x <= Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1567 Arg2->l.y = 0l; 1568 Arg1--; 1569 Arg2--; 1570 } 1571 #endif 1572 1573 void (*StkLTE)(void) = dStkLTE; 1574 1575 void dStkGTE(void) { 1576 Arg2->d.x = (double)(Arg2->d.x >= Arg1->d.x); 1577 Arg2->d.y = 0.0; 1578 Arg1--; 1579 Arg2--; 1580 } 1581 1582 #ifndef XFRACT 1583 void mStkGTE(void) { 1584 int comp; 1585 1586 comp = MPcmp(Arg2->m.x, Arg1->m.x); 1587 Arg2->m.x = *fg2MP((long)(comp == 1 || comp == 0), 0); 1588 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1589 Arg1--; 1590 Arg2--; 1591 } 1592 1593 void lStkGTE(void) { 1594 Arg2->l.x = (long)(Arg2->l.x >= Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1595 Arg2->l.y = 0l; 1596 Arg1--; 1597 Arg2--; 1598 } 1599 #endif 1600 1601 void (*StkGTE)(void) = dStkGTE; 1602 1603 void dStkEQ(void) { 1604 Arg2->d.x = (double)(Arg2->d.x == Arg1->d.x); 1605 Arg2->d.y = 0.0; 1606 Arg1--; 1607 Arg2--; 1608 } 1609 1610 #ifndef XFRACT 1611 void mStkEQ(void) { 1612 int comp; 1613 1614 comp = MPcmp(Arg2->m.x, Arg1->m.x); 1615 Arg2->m.x = *fg2MP((long)(comp == 0), 0); 1616 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1617 Arg1--; 1618 Arg2--; 1619 } 1620 1621 void lStkEQ(void) { 1622 Arg2->l.x = (long)(Arg2->l.x == Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1623 Arg2->l.y = 0l; 1624 Arg1--; 1625 Arg2--; 1626 } 1627 #endif 1628 1629 void (*StkEQ)(void) = dStkEQ; 1630 1631 void dStkNE(void) { 1632 Arg2->d.x = (double)(Arg2->d.x != Arg1->d.x); 1633 Arg2->d.y = 0.0; 1634 Arg1--; 1635 Arg2--; 1636 } 1637 1638 #ifndef XFRACT 1639 void mStkNE(void) { 1640 int comp; 1641 1642 comp = MPcmp(Arg2->m.x, Arg1->m.x); 1643 Arg2->m.x = *fg2MP((long)(comp != 0), 0); 1644 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1645 Arg1--; 1646 Arg2--; 1647 } 1648 1649 void lStkNE(void) { 1650 Arg2->l.x = (long)(Arg2->l.x != Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1651 Arg2->l.y = 0l; 1652 Arg1--; 1653 Arg2--; 1654 } 1655 #endif 1656 1657 void (*StkNE)(void) = dStkNE; 1658 1659 void dStkOR(void) { 1660 Arg2->d.x = (double)(Arg2->d.x || Arg1->d.x); 1661 Arg2->d.y = 0.0; 1662 Arg1--; 1663 Arg2--; 1664 } 1665 1666 #ifndef XFRACT 1667 void mStkOR(void) { 1668 Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant || Arg1->m.x.Mant), 0); 1669 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1670 Arg1--; 1671 Arg2--; 1672 } 1673 1674 void lStkOR(void) { 1675 Arg2->l.x = (long)(Arg2->l.x || Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1676 Arg2->l.y = 0l; 1677 Arg1--; 1678 Arg2--; 1679 } 1680 #endif 1681 1682 void (*StkOR)(void) = dStkOR; 1683 1684 void dStkAND(void) { 1685 Arg2->d.x = (double)(Arg2->d.x && Arg1->d.x); 1686 Arg2->d.y = 0.0; 1687 Arg1--; 1688 Arg2--; 1689 } 1690 1691 #ifndef XFRACT 1692 void mStkAND(void) { 1693 Arg2->m.x = *fg2MP((long)(Arg2->m.x.Mant && Arg1->m.x.Mant), 0); 1694 Arg2->m.y.Mant = (long)(Arg2->m.y.Exp = 0); 1695 Arg1--; 1696 Arg2--; 1697 } 1698 1699 void lStkAND(void) { 1700 Arg2->l.x = (long)(Arg2->l.x && Arg1->l.x) << bitshift; /* JCO 12/26/94 */ 1701 Arg2->l.y = 0l; 1702 Arg1--; 1703 Arg2--; 1704 } 1705 #endif 1706 1707 void (*StkAND)(void) = dStkAND; 1708 void dStkLog(void) { 1709 FPUcplxlog(&Arg1->d, &Arg1->d); 1710 } 1711 1712 #ifndef XFRACT 1713 void mStkLog(void) { 1714 mStkFunct(dStkLog); /* call lStk via dStk */ 1715 } 1716 1717 void lStkLog(void) { 1718 lStkFunct(dStkLog); 1719 } 1720 #endif 1721 1722 void (*StkLog)(void) = dStkLog; 1723 1724 void FPUcplxexp(_CMPLX *x, _CMPLX *z) { 1725 double e2x, siny, cosy; 1726 1727 if(fpu >= 387) 1728 FPUcplxexp387(x, z); 1729 else { 1730 e2x = exp(x->x); 1731 FPUsincos(&x->y, &siny, &cosy); 1732 z->x = e2x * cosy; 1733 z->y = e2x * siny; 1734 } 1735 } 1736 1737 void dStkExp(void) { 1738 FPUcplxexp(&Arg1->d, &Arg1->d); 1739 } 1740 1741 #ifndef XFRACT 1742 void mStkExp(void) { 1743 mStkFunct(dStkExp); /* call lStk via dStk */ 1744 } 1745 1746 void lStkExp(void) { 1747 lStkFunct(dStkExp); 1748 } 1749 #endif 1750 1751 void (*StkExp)(void) = dStkExp; 1752 1753 void dStkPwr(void) { 1754 Arg2->d = ComplexPower(Arg2->d, Arg1->d); 1755 Arg1--; 1756 Arg2--; 1757 } 1758 1759 #ifndef XFRACT 1760 #if (_MSC_VER >= 700) 1761 #pragma code_seg ("mpmath1_text") /* place following in an overlay */ 1762 #endif 1763 void mStkPwr(void) { 1764 _CMPLX x, y; 1765 1766 x = MPC2cmplx(Arg2->m); 1767 y = MPC2cmplx(Arg1->m); 1768 x = ComplexPower(x, y); 1769 Arg2->m = cmplx2MPC(x); 1770 Arg1--; 1771 Arg2--; 1772 } 1773 #if (_MSC_VER >= 700) 1774 #pragma code_seg () /* back to normal segment */ 1775 #endif 1776 1777 void lStkPwr(void) { 1778 _CMPLX x, y; 1779 1780 x.x = (double)Arg2->l.x / fg; 1781 x.y = (double)Arg2->l.y / fg; 1782 y.x = (double)Arg1->l.x / fg; 1783 y.y = (double)Arg1->l.y / fg; 1784 x = ComplexPower(x, y); 1785 if(fabs(x.x) < fgLimit && fabs(x.y) < fgLimit) { 1786 Arg2->l.x = (long)(x.x * fg); 1787 Arg2->l.y = (long)(x.y * fg); 1788 } 1789 else 1790 overflow = 1; 1791 Arg1--; 1792 Arg2--; 1793 } 1794 #endif 1795 1796 void (*StkPwr)(void) = dStkPwr; 1797 1798 void EndInit(void) { 1799 LastInitOp = OpPtr; 1800 InitJumpIndex = jump_index; 1801 } 1802 1803 void (*PtrEndInit)(void) = EndInit; 1804 1805 void StkJump (void) 1806 { 1807 OpPtr = jump_control[jump_index].ptrs.JumpOpPtr; 1808 LodPtr = jump_control[jump_index].ptrs.JumpLodPtr; 1809 StoPtr = jump_control[jump_index].ptrs.JumpStoPtr; 1810 jump_index = jump_control[jump_index].DestJumpIndex; 1811 } 1812 1813 void dStkJumpOnFalse (void) 1814 { 1815 if(Arg1->d.x == 0) 1816 StkJump(); 1817 else 1818 jump_index++; 1819 } 1820 1821 void mStkJumpOnFalse (void) 1822 { 1823 #ifndef XFRACT 1824 if(Arg1->m.x.Mant == 0) 1825 StkJump(); 1826 else 1827 jump_index++; 1828 #endif 1829 } 1830 1831 void lStkJumpOnFalse (void) 1832 { 1833 if(Arg1->l.x == 0) 1834 StkJump(); 1835 else 1836 jump_index++; 1837 } 1838 1839 void (*StkJumpOnFalse)(void) = dStkJumpOnFalse; 1840 1841 void dStkJumpOnTrue (void) 1842 { 1843 if(Arg1->d.x) 1844 StkJump(); 1845 else 1846 jump_index++; 1847 } 1848 1849 void mStkJumpOnTrue (void) 1850 { 1851 #ifndef XFRACT 1852 if(Arg1->m.x.Mant) 1853 StkJump(); 1854 else 1855 jump_index++; 1856 #endif 1857 } 1858 1859 void lStkJumpOnTrue (void) 1860 { 1861 if(Arg1->l.x) 1862 StkJump(); 1863 else 1864 jump_index++; 1865 } 1866 1867 void (*StkJumpOnTrue)(void) = dStkJumpOnTrue; 1868 1869 void StkJumpLabel (void) 1870 { 1871 jump_index++; 1872 } 1873 1874 1875 #if (_MSC_VER >= 700) 1876 #pragma code_seg ("parser1_text") /* place following in an overlay */ 1877 #endif 1878 1879 unsigned SkipWhiteSpace(char *Str) { 1880 unsigned n, Done; 1881 1882 for(Done = n = 0; !Done; n++) { 1883 switch(Str[n]) { 1884 case ' ': 1885 case '\t': 1886 case '\n': 1887 case '\r': 1888 break; 1889 default: 1890 Done = 1; 1891 } 1892 } 1893 return(n - 1); 1894 } 1895 1896 /* detect if constant is part of a (a,b) construct */ 1897 static int isconst_pair(char *Str) { 1898 int n,j; 1899 int answer = 0; 1900 /* skip past first number */ 1901 for(n = 0; isdigit(Str[n]) || Str[n] == '.'; n++); 1902 if(Str[n] == ',') { 1903 j = n + SkipWhiteSpace(&Str[n+1]) + 1; 1904 if(isdigit(Str[j]) 1905 || (Str[j] == '-' && (isdigit(Str[j+1]) || Str[j+1] == '.')) 1906 || Str[j] == '.') { 1907 answer = 1; 1908 } 1909 } 1910 return(answer); 1911 } 1912 1913 struct ConstArg far *isconst(char *Str, int Len) { 1914 _CMPLX z; 1915 unsigned n, j; 1916 /* next line enforces variable vs constant naming convention */ 1917 for(n = 0; n < vsp; n++) { 1918 if(v[n].len == Len) { 1919 if(!strnicmp(v[n].s, Str, Len)) 1920 { 1921 if(n == 1) /* The formula uses 'p1'. */ 1922 uses_p1 = 1; 1923 if(n == 2) /* The formula uses 'p2'. */ 1924 uses_p2 = 1; 1925 if(n == 7) /* The formula uses 'rand'. */ 1926 RandomSeed(); 1927 if(n == 8) /* The formula uses 'p3'. */ 1928 uses_p3 = 1; 1929 if(n == 13) /* The formula uses 'ismand'. */ 1930 uses_ismand = 1; 1931 if(n == 17) /* The formula uses 'p4'. */ 1932 uses_p4 = 1; 1933 if(n == 18) /* The formula uses 'p5'. */ 1934 uses_p5 = 1; 1935 #ifndef XFRACT 1936 if(n == 10 || n == 11 || n == 12) 1937 if(MathType == L_MATH) 1938 keybuffer = 'f'; 1939 #endif 1940 if(!isconst_pair(Str)) 1941 return(&v[n]); 1942 } 1943 } 1944 } 1945 v[vsp].s = Str; 1946 v[vsp].len = Len; 1947 v[vsp].a.d.x = v[vsp].a.d.y = 0.0; 1948 1949 #ifndef XFRACT 1950 /* v[vsp].a should already be zeroed out */ 1951 switch(MathType) { 1952 case M_MATH: 1953 v[vsp].a.m.x.Mant = v[vsp].a.m.x.Exp = 0; 1954 v[vsp].a.m.y.Mant = v[vsp].a.m.y.Exp = 0; 1955 break; 1956 case L_MATH: 1957 v[vsp].a.l.x = v[vsp].a.l.y = 0; 1958 break; 1959 } 1960 #endif 1961 1962 if(isdigit(Str[0]) 1963 || (Str[0] == '-' && (isdigit(Str[1]) || Str[1] == '.')) 1964 || Str[0] == '.') { 1965 if(o[posp-1].f == StkNeg) { 1966 posp--; 1967 Str = Str - 1; 1968 InitN--; 1969 v[vsp].len++; 1970 } 1971 for(n = 1; isdigit(Str[n]) || Str[n] == '.'; n++); 1972 if(Str[n] == ',') { 1973 j = n + SkipWhiteSpace(&Str[n+1]) + 1; 1974 if(isdigit(Str[j]) 1975 || (Str[j] == '-' && (isdigit(Str[j+1]) || Str[j+1] == '.')) 1976 || Str[j] == '.') { 1977 z.y = atof(&Str[j]); 1978 for(; isdigit(Str[j]) || Str[j] == '.' || Str[j] == '-'; j++); 1979 v[vsp].len = j; 1980 } 1981 else 1982 z.y = 0.0; 1983 } 1984 else 1985 z.y = 0.0; 1986 z.x = atof(Str); 1987 switch(MathType) { 1988 case D_MATH: 1989 v[vsp].a.d = z; 1990 break; 1991 #ifndef XFRACT 1992 case M_MATH: 1993 v[vsp].a.m = cmplx2MPC(z); 1994 break; 1995 case L_MATH: 1996 v[vsp].a.l.x = (long)(z.x * fg); 1997 v[vsp].a.l.y = (long)(z.y * fg); 1998 break; 1999 #endif 2000 } 2001 v[vsp].s = Str; 2002 } 2003 return(&v[vsp++]); 2004 } 2005 2006 2007 struct FNCT_LIST { 2008 char far *s; /* TIW 03-31-91 added far */ 2009 void (**ptr)(void); 2010 }; 2011 2012 /* TIW 03-30-91 START */ 2013 void (*StkTrig0)(void) = dStkSin; 2014 void (*StkTrig1)(void) = dStkSqr; 2015 void (*StkTrig2)(void) = dStkSinh; 2016 void (*StkTrig3)(void) = dStkCosh; 2017 2018 char far * JumpList[] = { 2019 "if", 2020 "elseif", 2021 "else", 2022 "endif", 2023 "" 2024 }; 2025 2026 2027 2028 int isjump(char *Str, int Len) 2029 { 2030 /* return values 2031 0 - Not a jump 2032 1 - if 2033 2 - elseif 2034 3 - else 2035 4 - endif 2036 */ 2037 2038 int i; 2039 2040 for(i = 0; *JumpList[i]; i++) 2041 if(far_strlen(JumpList[i]) == Len) 2042 if(!far_strnicmp(JumpList[i], Str, Len)) 2043 return i + 1; 2044 return 0; 2045 } 2046 2047 2048 char maxfn = 0; 2049 /* TIW 03-30-91 STOP */ 2050 2051 struct FNCT_LIST far FnctList[] = { /* TIW 03-31-91 added far */ 2052 {s_sin, &StkSin}, 2053 {s_sinh, &StkSinh}, 2054 {s_cos, &StkCos}, 2055 {s_cosh, &StkCosh}, 2056 {s_sqr, &StkSqr}, 2057 {s_log, &StkLog}, 2058 {s_exp, &StkExp}, 2059 {s_abs, &StkAbs}, 2060 {s_conj, &StkConj}, 2061 {s_real, &StkReal}, 2062 {s_imag, &StkImag}, 2063 {s_fn1, &StkTrig0}, /* TIW 03-30-91 */ 2064 {s_fn2, &StkTrig1}, /* TIW 03-30-91 */ 2065 {s_fn3, &StkTrig2}, /* TIW 03-30-91 */ 2066 {s_fn4, &StkTrig3}, /* TIW 03-30-91 */ 2067 {s_flip, &StkFlip}, /* MCP 4-9-91 */ 2068 {s_tan, &StkTan}, /* TIW 04-22-91 */ 2069 {s_tanh, &StkTanh}, /* TIW 04-22-91 */ 2070 {s_cotan, &StkCoTan}, /* TIW 04-24-91 */ 2071 {s_cotanh,&StkCoTanh}, /* TIW 04-24-91 */ 2072 {s_cosxx, &StkCosXX}, /* PB 04-28-91 */ 2073 {s_srand, &StkSRand}, /* MCP 11-21-91 */ 2074 {s_asin, &StkASin}, /* TIW 11-26-94 */ 2075 {s_asinh, &StkASinh}, /* TIW 11-26-94 */ 2076 {s_acos, &StkACos}, /* TIW 11-26-94 */ 2077 {s_acosh, &StkACosh}, /* TIW 11-26-94 */ 2078 {s_atan, &StkATan}, /* TIW 11-26-94 */ 2079 {s_atanh, &StkATanh}, /* TIW 11-26-94 */ 2080 {s_sqrt, &StkSqrt}, /* TIW 11-26-94 */ 2081 {s_cabs, &StkCAbs}, /* TIW 11-26-94 */ 2082 {s_floor, &StkFloor}, /* TIW 06-30-96 */ 2083 {s_ceil, &StkCeil}, /* TIW 06-30-96 */ 2084 {s_trunc, &StkTrunc}, /* TIW 06-30-96 */ 2085 {s_round, &StkRound}, /* TIW 06-30-96 */ 2086 }; 2087 2088 struct OP_LIST { 2089 char *s; 2090 void (**ptr)(void); 2091 }; 2092 2093 struct OP_LIST far OPList[] = { 2094 {"," , &PtrStkClr }, /* 0 */ 2095 {"!=" , &StkNE }, /* 1 */ 2096 {"=" , &PtrStkSto }, /* 2 */ 2097 {"==" , &StkEQ }, /* 3 */ 2098 {"<" , &StkLT }, /* 4 */ 2099 {"<=" , &StkLTE }, /* 5 */ 2100 {">" , &StkGT }, /* 6 */ 2101 {">=" , &StkGTE }, /* 7 */ 2102 {"|" , &StkMod }, /* 8 */ 2103 {"||" , &StkOR }, /* 9 */ 2104 {"&&" , &StkAND }, /* 10 */ 2105 {":" , &PtrEndInit }, /* 11 */ 2106 {"+" , &StkAdd }, /* 12 */ 2107 {"-" , &StkSub }, /* 13 */ 2108 {"*" , &StkMul }, /* 14 */ 2109 {"/" , &StkDiv }, /* 15 */ 2110 {"^" , &StkPwr }, /* 16 */ 2111 }; 2112 2113 2114 void NotAFnct(void) { } 2115 void FnctNotFound(void) { } 2116 2117 /* determine if s names a function and if so which one */ 2118 /* TIW 04-22-91 */ 2119 int whichfn(char *s, int len) 2120 { 2121 int out; 2122 if(len != 3) 2123 out = 0; 2124 else if(strnicmp(s,"fn",2)) 2125 out = 0; 2126 else 2127 out = atoi(s+2); 2128 if(out < 1 || out > 4) 2129 out = 0; 2130 return(out); 2131 } 2132 2133 #ifndef XFRACT 2134 void (far *isfunct(char *Str, int Len))(void)
2135 #else 2136 void (*isfunct(Str, Len))() 2137 char *Str; 2138 int Len;
2139 #endif 2140 { 2141 unsigned n; 2142 int functnum; /* TIW 04-22-91 */ 2143 2144 n = SkipWhiteSpace(&Str[Len]); 2145 if(Str[Len+n] == '(') { 2146 for(n = 0; n < sizeof(FnctList) / sizeof(struct FNCT_LIST); n++) { 2147 if(far_strlen(FnctList[n].s) == Len) { /* TIW 03-31-91 added far */ 2148 if(!far_strnicmp(FnctList[n].s, Str, Len)) { /* TIW 03-31-91 added far */ 2149 /* count function variables */ 2150 if((functnum = whichfn(Str, Len)) != 0) /* TIW 04-22-91 */ 2151 if(functnum > maxfn) /* TIW 04-22-91 */ 2152 maxfn = (char)functnum; /* TIW 04-22-91 */ 2153 return(*FnctList[n].ptr); 2154 } 2155 } 2156 } 2157 return(FnctNotFound); 2158 } 2159 return(NotAFnct); 2160 } 2161 2162 void RecSortPrec(void) { 2163 int ThisOp = NextOp++; 2164 while(o[ThisOp].p > o[NextOp].p && NextOp < posp) 2165 RecSortPrec(); 2166 f[OpPtr++] = o[ThisOp].f; 2167 } 2168 2169 static char *Constants[] = { 2170 "pixel", /* v[0] */ 2171 "p1", /* v[1] */ 2172 "p2", /* v[2] */ 2173 "z", /* v[3] */ 2174 "LastSqr", /* v[4] */ 2175 "pi", /* v[5] */ 2176 "e", /* v[6] */ 2177 "rand", /* v[7] */ 2178 "p3", /* v[8] */ 2179 "whitesq", /* v[9] */ 2180 "scrnpix", /* v[10] */ 2181 "scrnmax", /* v[11] */ 2182 "maxit", /* v[12] */ 2183 s_ismand, /* v[13] */ 2184 "center", /* v[14] */ 2185 "magxmag", /* v[15] */ 2186 "rotskew", /* v[16] */ 2187 "p4", /* v[17] */ 2188 "p5" /* v[18] */ 2189 }; 2190 2191 struct SYMETRY { 2192 char *s; 2193 int n; 2194 } SymStr[] = { 2195 {"NOSYM", 0}, 2196 {"XAXIS_NOPARM", -1}, 2197 {"XAXIS", 1}, 2198 {"YAXIS_NOPARM", -2}, 2199 {"YAXIS", 2}, 2200 {"XYAXIS_NOPARM",-3}, 2201 {"XYAXIS", 3}, 2202 {"ORIGIN_NOPARM",-4}, 2203 {"ORIGIN", 4}, 2204 {"PI_SYM_NOPARM",-5}, 2205 {"PI_SYM", 5}, 2206 {"XAXIS_NOIMAG", -6}, 2207 {"XAXIS_NOREAL", 6}, 2208 {"NOPLOT", 99}, 2209 {"", 0} 2210 }; 2211 2212 static int ParseStr(char *Str, int pass) { 2213 struct ConstArg far *c; 2214 int ModFlag = 999, Len, Equals = 0, Mod[20], mdstk = 0; 2215 int jumptype; 2216 double const_pi, const_e; 2217 double Xctr, Yctr, Xmagfactor, Rotation, Skew; 2218 LDBL Magnification; 2219 SetRandom = Randomized = 0; 2220 uses_jump = 0; 2221 jump_index = 0; 2222 if(pass == 0) 2223 o = (struct PEND_OP far *) 2224 ((char far *)typespecific_workarea + total_formula_mem-sizeof(struct PEND_OP) * Max_Ops); 2225 else if(used_extra == 1) 2226 o = (struct PEND_OP far *) 2227 ((char far *)typespecific_workarea + total_formula_mem-sizeof(struct PEND_OP) * Max_Ops); 2228 else 2229 o = (struct PEND_OP far *)farmemalloc(sizeof(struct PEND_OP) * (long)Max_Ops); 2230 if( !o || !typespecific_workarea) { 2231 stopmsg(0,ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); 2232 return(1); 2233 } 2234 switch(MathType) { 2235 case D_MATH: 2236 StkAdd = dStkAdd; 2237 StkSub = dStkSub; 2238 StkNeg = dStkNeg; 2239 StkMul = dStkMul; 2240 StkSin = dStkSin; 2241 StkSinh = dStkSinh; 2242 StkLT = dStkLT; 2243 StkLTE = dStkLTE; 2244 StkMod = dStkMod; 2245 StkSqr = dStkSqr; 2246 StkCos = dStkCos; 2247 StkCosh = dStkCosh; 2248 StkLog = dStkLog; 2249 StkExp = dStkExp; 2250 StkPwr = dStkPwr; 2251 StkDiv = dStkDiv; 2252 StkAbs = dStkAbs; 2253 StkReal = dStkReal; 2254 StkImag = dStkImag; 2255 StkConj = dStkConj; 2256 StkTrig0 = dtrig0; /* TIW 03-30-91 */ 2257 StkTrig1 = dtrig1; /* TIW 03-30-91 */ 2258 StkTrig2 = dtrig2; /* TIW 03-30-91 */ 2259 StkTrig3 = dtrig3; /* TIW 03-30-91 */ 2260 StkFlip = dStkFlip; 2261 StkTan = dStkTan; /* TIW 04-22-91 */ 2262 StkTanh = dStkTanh; /* TIW 04-22-91 */ 2263 StkCoTan = dStkCoTan; /* TIW 04-24-91 */ 2264 StkCoTanh = dStkCoTanh; /* TIW 04-24-91 */ 2265 StkCosXX = dStkCosXX; /* PB 04-28-91 */ 2266 StkGT = dStkGT; /* MCP 11-3-91 */ 2267 StkGTE = dStkGTE; /* MCP 11-3-91 */ 2268 StkEQ = dStkEQ; /* MCP 11-3-91 */ 2269 StkNE = dStkNE; /* MCP 11-3-91 */ 2270 StkAND = dStkAND; /* MCP 11-3-91 */ 2271 StkOR = dStkOR ; /* MCP 11-3-91 */ 2272 StkSRand = dStkSRand; /* MCP 11-21-91 */ 2273 StkASin = dStkASin; /* TIW 11-25-94 */ 2274 StkASinh = dStkASinh; /* TIW 11-25-94 */ 2275 StkACos = dStkACos; /* TIW 11-25-94 */ 2276 StkACosh = dStkACosh; /* TIW 11-25-94 */ 2277 StkATan = dStkATan; /* TIW 11-25-94 */ 2278 StkATanh = dStkATanh; /* TIW 11-25-94 */ 2279 StkCAbs = dStkCAbs; /* TIW 11-25-94 */ 2280 StkSqrt = dStkSqrt; /* TIW 11-25-94 */ 2281 StkZero = dStkZero; /* JCO 12-31-94 */ 2282 StkFloor = dStkFloor; /* TIW 06-30-96 */ 2283 StkCeil = dStkCeil; /* TIW 06-30-96 */ 2284 StkTrunc = dStkTrunc; /* TIW 06-30-96 */ 2285 StkRound = dStkRound; /* TIW 06-30-96 */ 2286 StkJumpOnTrue = dStkJumpOnTrue; /* GGM 02-10-97 */ 2287 StkJumpOnFalse = dStkJumpOnFalse; /* GGM 02-10-97 */ 2288 StkOne = dStkOne; /* GGM 10-08-97 */ 2289 break; 2290 #ifndef XFRACT 2291 case M_MATH: 2292 StkAdd = mStkAdd; 2293 StkSub = mStkSub; 2294 StkNeg = mStkNeg; 2295 StkMul = mStkMul; 2296 StkSin = mStkSin; 2297 StkSinh = mStkSinh; 2298 StkLT = mStkLT; 2299 StkLTE = mStkLTE; 2300 StkMod = mStkMod; 2301 StkSqr = mStkSqr; 2302 StkCos = mStkCos; 2303 StkCosh = mStkCosh; 2304 StkLog = mStkLog; 2305 StkExp = mStkExp; 2306 StkPwr = mStkPwr; 2307 StkDiv = mStkDiv; 2308 StkAbs = mStkAbs; 2309 StkReal = mStkReal; 2310 StkImag = mStkImag; 2311 StkConj = mStkConj; 2312 StkTrig0 = mtrig0; /* TIW 03-30-91 */ 2313 StkTrig1 = mtrig1; /* TIW 03-30-91 */ 2314 StkTrig2 = mtrig2; /* TIW 03-30-91 */ 2315 StkTrig3 = mtrig3; /* TIW 03-30-91 */ 2316 StkFlip = mStkFlip; 2317 StkTan = mStkTan; /* TIW 04-22-91 */ 2318 StkTanh = mStkTanh;/* TIW 04-22-91 */ 2319 StkCoTan = mStkCoTan; /* TIW 04-24-91 */ 2320 StkCoTanh = mStkCoTanh;/* TIW 04-24-91 */ 2321 StkCosXX = mStkCosXX; /* PB 04-28-91 */ 2322 StkGT = mStkGT; /* MCP 11-3-91 */ 2323 StkGTE = mStkGTE; /* MCP 11-3-91 */ 2324 StkEQ = mStkEQ; /* MCP 11-3-91 */ 2325 StkNE = mStkNE; /* MCP 11-3-91 */ 2326 StkAND = mStkAND; /* MCP 11-3-91 */ 2327 StkOR = mStkOR ; /* MCP 11-3-91 */ 2328 StkSRand = mStkSRand; /* MCP 11-21-91 */ 2329 StkASin = mStkASin; /* TIW 11-25-94 */ 2330 StkACos = mStkACos; /* TIW 11-25-94 */ 2331 StkACosh = mStkACosh; /* TIW 11-25-94 */ 2332 StkATan = mStkATan; /* TIW 11-25-94 */ 2333 StkATanh = mStkATanh; /* TIW 11-25-94 */ 2334 StkCAbs = mStkCAbs; /* TIW 11-25-94 */ 2335 StkSqrt = mStkSqrt; /* TIW 11-25-94 */ 2336 StkZero = mStkZero; /* JCO 12-31-94 */ 2337 StkFloor = mStkFloor; /* TIW 06-30-96 */ 2338 StkCeil = mStkCeil; /* TIW 06-30-96 */ 2339 StkTrunc = mStkTrunc; /* TIW 06-30-96 */ 2340 StkRound = mStkRound; /* TIW 06-30-96 */ 2341 StkJumpOnTrue = mStkJumpOnTrue; /* GGM 02-10-97 */ 2342 StkJumpOnFalse = mStkJumpOnFalse; /* GGM 02-10-97 */ 2343 StkOne = mStkOne; /* GGM 10-08-97 */ 2344 break; 2345 case L_MATH: 2346 Delta16 = bitshift - 16; 2347 ShiftBack = 32 - bitshift; /* TW 06-18-90 */ 2348 StkAdd = lStkAdd; 2349 StkSub = lStkSub; 2350 StkNeg = lStkNeg; 2351 StkMul = lStkMul; 2352 StkSin = lStkSin; 2353 StkSinh = lStkSinh; 2354 StkLT = lStkLT; 2355 StkLTE = lStkLTE; 2356 if (save_release > 1826) 2357 StkMod = lStkMod; 2358 else 2359 StkMod = lStkModOld; 2360 StkSqr = lStkSqr; 2361 StkCos = lStkCos; 2362 StkCosh = lStkCosh; 2363 StkLog = lStkLog; 2364 StkExp = lStkExp; 2365 StkPwr = lStkPwr; 2366 StkDiv = lStkDiv; 2367 StkAbs = lStkAbs; 2368 StkReal = lStkReal; 2369 StkImag = lStkImag; 2370 StkConj = lStkConj; 2371 StkTrig0 = ltrig0; /* TIW 03-30-91 */ 2372 StkTrig1 = ltrig1; /* TIW 03-30-91 */ 2373 StkTrig2 = ltrig2; /* TIW 03-30-91 */ 2374 StkTrig3 = ltrig3; /* TIW 03-30-91 */ 2375 StkFlip = lStkFlip; 2376 StkTan = lStkTan; /* TIW 04-22-91 */ 2377 StkTanh = lStkTanh; /* TIW 04-22-91 */ 2378 StkCoTan = lStkCoTan; /* TIW 04-24-91 */ 2379 StkCoTanh = lStkCoTanh; /* TIW 04-24-91 */ 2380 StkCosXX = lStkCosXX; /* PB 04-28-91 */ 2381 StkGT = lStkGT; /* MCP 11-3-91 */ 2382 StkGTE = lStkGTE; /* MCP 11-3-91 */ 2383 StkEQ = lStkEQ; /* MCP 11-3-91 */ 2384 StkNE = lStkNE; /* MCP 11-3-91 */ 2385 StkAND = lStkAND; /* MCP 11-3-91 */ 2386 StkOR = lStkOR ; /* MCP 11-3-91 */ 2387 StkSRand = lStkSRand; /* MCP 11-21-91 */ 2388 StkASin = lStkASin; /* TIW 11-25-94 */ 2389 StkACos = lStkACos; /* TIW 11-25-94 */ 2390 StkACosh = lStkACosh; /* TIW 11-25-94 */ 2391 StkATan = lStkATan; /* TIW 11-25-94 */ 2392 StkATanh = lStkATanh; /* TIW 11-25-94 */ 2393 StkCAbs = lStkCAbs; /* TIW 11-25-94 */ 2394 StkSqrt = lStkSqrt; /* TIW 11-25-94 */ 2395 StkZero = lStkZero; /* JCO 12-31-94 */ 2396 StkFloor = lStkFloor; /* TIW 06-30-96 */ 2397 StkCeil = lStkCeil; /* TIW 06-30-96 */ 2398 StkTrunc = lStkTrunc; /* TIW 06-30-96 */ 2399 StkRound = lStkRound; /* TIW 06-30-96 */ 2400 StkJumpOnTrue = lStkJumpOnTrue; /* GGM 02-10-97 */ 2401 StkJumpOnFalse = lStkJumpOnFalse; /* GGM 02-10-97 */ 2402 StkOne = lStkOne; /* GGM 10-08-97 */ 2403 break; 2404 #endif 2405 } 2406 maxfn = 0; /* TIW 03-30-91 */ 2407 for(vsp = 0; vsp < sizeof(Constants) / sizeof(char*); vsp++) { 2408 v[vsp].s = Constants[vsp]; 2409 v[vsp].len = strlen(Constants[vsp]); 2410 } 2411 cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew); 2412 const_pi = atan(1.0) * 4; 2413 const_e = exp(1.0); 2414 v[7].a.d.x = v[7].a.d.y = 0.0; 2415 v[11].a.d.x = (double)xdots; 2416 v[11].a.d.y = (double)ydots; 2417 v[12].a.d.x = (double)maxit; 2418 v[12].a.d.y = 0; 2419 v[13].a.d.x = (double)ismand; 2420 v[13].a.d.y = 0; 2421 v[14].a.d.x = Xctr; 2422 v[14].a.d.y = Yctr; 2423 v[15].a.d.x = (double)Magnification; 2424 v[15].a.d.y = Xmagfactor; 2425 v[16].a.d.x = Rotation; 2426 v[16].a.d.y = Skew; 2427 2428 switch(MathType) { 2429 case D_MATH: 2430 v[1].a.d.x = param[0]; 2431 v[1].a.d.y = param[1]; 2432 v[2].a.d.x = param[2]; 2433 v[2].a.d.y = param[3]; 2434 v[5].a.d.x = const_pi; 2435 v[5].a.d.y = 0.0; 2436 v[6].a.d.x = const_e; 2437 v[6].a.d.y = 0.0; 2438 v[8].a.d.x = param[4]; 2439 v[8].a.d.y = param[5]; 2440 v[17].a.d.x = param[6]; 2441 v[17].a.d.y = param[7]; 2442 v[18].a.d.x = param[8]; 2443 v[18].a.d.y = param[9]; 2444 break; 2445 #ifndef XFRACT 2446 case M_MATH: 2447 v[1].a.m.x = *d2MP(param[0]); 2448 v[1].a.m.y = *d2MP(param[1]); 2449 v[2].a.m.x = *d2MP(param[2]); 2450 v[2].a.m.y = *d2MP(param[3]); 2451 v[5].a.m.x = *d2MP(const_pi); 2452 v[5].a.m.y = *d2MP(0.0); 2453 v[6].a.m.x = *d2MP(const_e); 2454 v[6].a.m.y = *d2MP(0.0); 2455 v[8].a.m.x = *d2MP(param[4]); 2456 v[8].a.m.y = *d2MP(param[5]); 2457 v[11].a.m = cmplx2MPC(v[11].a.d); 2458 v[12].a.m = cmplx2MPC(v[12].a.d); 2459 v[13].a.m = cmplx2MPC(v[13].a.d); 2460 v[14].a.m = cmplx2MPC(v[14].a.d); 2461 v[15].a.m = cmplx2MPC(v[15].a.d); 2462 v[16].a.m = cmplx2MPC(v[16].a.d); 2463 v[17].a.m.x = *d2MP(param[6]); 2464 v[17].a.m.y = *d2MP(param[7]); 2465 v[18].a.m.x = *d2MP(param[8]); 2466 v[18].a.m.y = *d2MP(param[9]); 2467 break; 2468 case L_MATH: 2469 v[1].a.l.x = (long)(param[0] * fg); 2470 v[1].a.l.y = (long)(param[1] * fg); 2471 v[2].a.l.x = (long)(param[2] * fg); 2472 v[2].a.l.y = (long)(param[3] * fg); 2473 v[5].a.l.x = (long)(const_pi * fg); 2474 v[5].a.l.y = 0L; 2475 v[6].a.l.x = (long)(const_e * fg); 2476 v[6].a.l.y = 0L; 2477 v[8].a.l.x = (long)(param[4] * fg); 2478 v[8].a.l.y = (long)(param[5] * fg); 2479 v[11].a.l.x = xdots; v[11].a.l.x <<= bitshift; 2480 v[11].a.l.y = ydots; v[11].a.l.y <<= bitshift; 2481 v[12].a.l.x = maxit; v[12].a.l.x <<= bitshift; 2482 v[12].a.l.y = 0L; 2483 v[13].a.l.x = ismand; v[13].a.l.x <<= bitshift; 2484 v[13].a.l.y = 0L; 2485 v[14].a.l.x = (long)(v[14].a.d.x * fg); 2486 v[14].a.l.y = (long)(v[14].a.d.y * fg); 2487 v[15].a.l.x = (long)(v[15].a.d.x * fg); 2488 v[15].a.l.y = (long)(v[15].a.d.y * fg); 2489 v[16].a.l.x = (long)(v[16].a.d.x * fg); 2490 v[16].a.l.y = (long)(v[16].a.d.y * fg); 2491 v[17].a.l.x = (long)(param[6] * fg); 2492 v[17].a.l.y = (long)(param[7] * fg); 2493 v[18].a.l.x = (long)(param[8] * fg); 2494 v[18].a.l.y = (long)(param[9] * fg); 2495 break; 2496 #endif 2497 } 2498 2499 LastInitOp = paren = OpPtr = LodPtr = StoPtr = posp = 0; 2500 ExpectingArg = 1; 2501 for(n = 0; Str[n]; n++) { 2502 if(!Str[n]) 2503 break; 2504 InitN = n; 2505 switch(Str[n]) { 2506 case ' ': 2507 case '\t': 2508 case '\r': 2509 case '\n': 2510 break; 2511 case '(': 2512 paren++; 2513 break; 2514 case ')': 2515 paren--; 2516 break; 2517 case '|': 2518 if(Str[n+1] == '|') { 2519 ExpectingArg = 1; 2520 n++; 2521 o[posp].f = StkOR; 2522 o[posp++].p = 7 - (paren + Equals)*15; 2523 } 2524 else if(ModFlag == paren-1) { 2525 paren--; 2526 ModFlag = Mod[--mdstk]; 2527 } 2528 else { 2529 Mod[mdstk++] = ModFlag; 2530 o[posp].f = StkMod; 2531 o[posp++].p = 2 - (paren + Equals)*15; 2532 ModFlag = paren++; 2533 } 2534 break; 2535 case ',': 2536 case ';': 2537 if(!ExpectingArg) { 2538 ExpectingArg = 1; 2539 o[posp].f = (void(far*)(void))0; 2540 o[posp++].p = 15; 2541 o[posp].f = StkClr; 2542 o[posp++].p = -30000; 2543 Equals = paren = 0; 2544 } 2545 break; 2546 case ':': 2547 ExpectingArg = 1; 2548 o[posp].f = (void(far*)(void))0; 2549 o[posp++].p = 15; 2550 o[posp].f = EndInit; 2551 o[posp++].p = -30000; 2552 Equals = paren = 0; 2553 LastInitOp = 10000; 2554 break; 2555 case '+': 2556 ExpectingArg = 1; 2557 o[posp].f = StkAdd; 2558 o[posp++].p = 4 - (paren + Equals)*15; 2559 break; 2560 case '-': 2561 if(ExpectingArg) { 2562 o[posp].f = StkNeg; 2563 o[posp++].p = 2 - (paren + Equals)*15; 2564 } 2565 else { 2566 o[posp].f = StkSub; 2567 o[posp++].p = 4 - (paren + Equals)*15; 2568 ExpectingArg = 1; 2569 } 2570 break; 2571 case '&': 2572 ExpectingArg = 1; 2573 n++; 2574 o[posp].f = StkAND; 2575 o[posp++].p = 7 - (paren + Equals)*15; 2576 break; 2577 case '!': 2578 ExpectingArg = 1; 2579 n++; 2580 o[posp].f = StkNE; 2581 o[posp++].p = 6 - (paren + Equals)*15; 2582 break; 2583 case '<': 2584 ExpectingArg = 1; 2585 if(Str[n+1] == '=') { 2586 n++; 2587 o[posp].f = StkLTE; 2588 } 2589 else 2590 o[posp].f = StkLT; 2591 o[posp++].p = 6 - (paren + Equals)*15; 2592 break; 2593 case '>': 2594 ExpectingArg = 1; 2595 if(Str[n+1] == '=') { 2596 n++; 2597 o[posp].f = StkGTE; 2598 } 2599 else 2600 o[posp].f = StkGT; 2601 o[posp++].p = 6 - (paren + Equals)*15; 2602 break; 2603 case '*': 2604 ExpectingArg = 1; 2605 o[posp].f = StkMul; 2606 o[posp++].p = 3 - (paren + Equals)*15; 2607 break; 2608 case '/': 2609 ExpectingArg = 1; 2610 o[posp].f = StkDiv; 2611 o[posp++].p = 3 - (paren + Equals)*15; 2612 break; 2613 case '^': 2614 ExpectingArg = 1; 2615 o[posp].f = StkPwr; 2616 o[posp++].p = 2 - (paren + Equals)*15; 2617 break; 2618 case '=': 2619 ExpectingArg = 1; 2620 if(Str[n+1] == '=') { 2621 n++; 2622 o[posp].f = StkEQ; 2623 o[posp++].p = 6 - (paren + Equals)*15; 2624 } 2625 else { 2626 o[posp-1].f = StkSto; 2627 o[posp-1].p = 5 - (paren + Equals)*15; 2628 Store[StoPtr++] = Load[--LodPtr]; 2629 Equals++; 2630 } 2631 break; 2632 default: 2633 while(isalnum(Str[n+1]) || Str[n+1] == '.' || Str[n+1] == '_') 2634 n++; 2635 Len = (n+1)-InitN; 2636 ExpectingArg = 0; 2637 if((jumptype = isjump(&Str[InitN], Len)) != 0) { 2638 uses_jump = 1; 2639 switch (jumptype) { 2640 case 1: /* if */ 2641 ExpectingArg = 1; 2642 jump_control[jump_index++].type = 1; 2643 o[posp].f = StkJumpOnFalse; 2644 o[posp++].p = 1; 2645 break; 2646 case 2: /* elseif */ 2647 ExpectingArg = 1; 2648 jump_control[jump_index++].type = 2; 2649 jump_control[jump_index++].type = 2; 2650 o[posp].f = StkJump; 2651 o[posp++].p = 1; 2652 o[posp].f = (void(far*)(void))0; 2653 o[posp++].p = 15; 2654 o[posp].f = StkClr; 2655 o[posp++].p = -30000; 2656 o[posp].f = StkJumpOnFalse; 2657 o[posp++].p = 1; 2658 break; 2659 case 3: /* else */ 2660 jump_control[jump_index++].type = 3; 2661 o[posp].f = StkJump; 2662 o[posp++].p = 1; 2663 break; 2664 case 4: /* endif */ 2665 jump_control[jump_index++].type = 4; 2666 o[posp].f = StkJumpLabel; 2667 o[posp++].p = 1; 2668 break; 2669 default: 2670 break; 2671 } 2672 } 2673 else { 2674 o[posp].f = isfunct(&Str[InitN], Len); 2675 if(o[posp].f != NotAFnct) { 2676 o[posp++].p = 1 - (paren + Equals)*15; 2677 ExpectingArg = 1; 2678 } 2679 else { 2680 c = isconst(&Str[InitN], Len); 2681 Load[LodPtr++] = &(c->a); 2682 o[posp].f = StkLod; 2683 o[posp++].p = 1 - (paren + Equals)*15; 2684 n = InitN + c->len - 1; 2685 } 2686 } 2687 break; 2688 } 2689 } 2690 o[posp].f = (void(far*)(void))0; 2691 o[posp++].p = 16; 2692 NextOp = 0; 2693 LastOp = posp; 2694 while(NextOp < posp) { 2695 if(o[NextOp].f) 2696 RecSortPrec(); 2697 else { 2698 NextOp++; 2699 LastOp--; 2700 } 2701 } 2702 if(pass > 0 && used_extra == 0) 2703 farmemfree(o); 2704 return(0); 2705 } 2706 2707 2708 #if (_MSC_VER >= 700) 2709 #pragma code_seg () /* back to normal segment */ 2710 #endif 2711 2712 int Formula(void) { 2713 if(FormName[0] == 0 || overflow) return(1); 2714 2715 LodPtr = InitLodPtr; 2716 StoPtr = InitStoPtr; 2717 OpPtr = InitOpPtr; 2718 jump_index=InitJumpIndex; 2719 /* Set the random number, MCP 11-21-91 */ 2720 if(SetRandom || Randomized) 2721 { 2722 switch(MathType) 2723 { 2724 case D_MATH: 2725 dRandom(); 2726 break; 2727 #ifndef XFRACT 2728 case L_MATH: 2729 lRandom(); 2730 break; 2731 case M_MATH: 2732 mRandom(); 2733 #endif 2734 } 2735 } 2736 2737 Arg1 = &s[0]; 2738 Arg2 = Arg1-1; 2739 while(OpPtr < (int)LastOp) { 2740 f[OpPtr](); 2741 OpPtr++; 2742 #ifdef WATCH_MP
2743 x1 = *MP2d(Arg1->m.x); 2744 y1 = *MP2d(Arg1->m.y); 2745 x2 = *MP2d(Arg2->m.x); 2746 y2 = *MP2d(Arg2->m.y);
2747 #endif 2748 } 2749 2750 switch(MathType) { 2751 case D_MATH: 2752 old = new = v[3].a.d; 2753 return(Arg1->d.x == 0.0); 2754 #ifndef XFRACT 2755 case M_MATH: 2756 old = new = MPC2cmplx(v[3].a.m); 2757 return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0); 2758 case L_MATH: 2759 lold = lnew = v[3].a.l; 2760 if(overflow) 2761 return(1); 2762 return(Arg1->l.x == 0L); 2763 #endif 2764 } 2765 return(1); 2766 } 2767 2768 int form_per_pixel(void) { 2769 if (FormName[0] == 0) return(1); 2770 overflow = LodPtr = StoPtr = OpPtr = jump_index = 0; 2771 Arg1 = &s[0]; 2772 Arg2 = Arg1; 2773 Arg2--; 2774 2775 2776 v[10].a.d.x = (double)col; 2777 v[10].a.d.y = (double)row; 2778 2779 switch(MathType) { 2780 case D_MATH: 2781 if((row+col)&1) 2782 v[9].a.d.x = 1.0; 2783 else 2784 v[9].a.d.x = 0.0; 2785 v[9].a.d.y = 0.0; 2786 break; 2787 2788 2789 #ifndef XFRACT 2790 case M_MATH: 2791 if((row+col)&1) 2792 v[9].a.m = MPCone; 2793 else { 2794 v[9].a.m.x.Mant = v[9].a.m.x.Exp = 0; 2795 v[9].a.m.y.Mant = v[9].a.m.y.Exp = 0; 2796 } 2797 v[10].a.m = cmplx2MPC(v[10].a.d); 2798 break; 2799 case L_MATH: 2800 v[9].a.l.x = (long) (((row+col)&1) * fg); 2801 v[9].a.l.y = 0L; 2802 v[10].a.l.x = col; v[10].a.l.x <<= bitshift; 2803 v[10].a.l.y = row; v[10].a.l.y <<= bitshift; 2804 break; 2805 #endif 2806 } 2807 2808 /* TW started additions for inversion support here 4/17/94 */ 2809 { 2810 if(invert) 2811 { 2812 invertz2(&old); 2813 switch(MathType) 2814 { 2815 case D_MATH: 2816 v[0].a.d.x = old.x; 2817 v[0].a.d.y = old.y; 2818 break; 2819 #ifndef XFRACT 2820 case M_MATH: 2821 v[0].a.m.x = *d2MP(old.x); 2822 v[0].a.m.y = *d2MP(old.y); 2823 break; 2824 case L_MATH: 2825 /* watch out for overflow */ 2826 if(sqr(old.x)+sqr(old.y) >= 127) 2827 { 2828 old.x = 8; /* value to bail out in one iteration */ 2829 old.y = 8; 2830 } 2831 /* convert to fudged longs */ 2832 v[0].a.l.x = (long)(old.x*fg); 2833 v[0].a.l.y = (long)(old.y*fg); 2834 break; 2835 #endif 2836 } 2837 } 2838 else 2839 /* TW end of inversion support changes here 4/17/94 */ 2840 switch(MathType) 2841 { 2842 case D_MATH: 2843 v[0].a.d.x = dxpixel(); 2844 v[0].a.d.y = dypixel(); 2845 break; 2846 #ifndef XFRACT 2847 case M_MATH: 2848 v[0].a.m.x = *d2MP(dxpixel()); 2849 v[0].a.m.y = *d2MP(dypixel()); 2850 break; 2851 case L_MATH: 2852 v[0].a.l.x = lxpixel(); 2853 v[0].a.l.y = lypixel(); 2854 break; 2855 #endif 2856 } 2857 } 2858 2859 if(LastInitOp) 2860 LastInitOp = LastOp; 2861 while(OpPtr < LastInitOp) { 2862 f[OpPtr](); 2863 OpPtr++; 2864 } 2865 InitLodPtr = LodPtr; 2866 InitStoPtr = StoPtr; 2867 InitOpPtr = OpPtr; 2868 /* Set old variable for orbits TIW 12-18-93 */ 2869 switch(MathType) { 2870 case D_MATH: 2871 old = v[3].a.d; 2872 break; 2873 #ifndef XFRACT 2874 case M_MATH: 2875 old = MPC2cmplx(v[3].a.m); 2876 break; 2877 case L_MATH: 2878 lold = v[3].a.l; 2879 break; 2880 #endif 2881 } 2882 2883 if(overflow) 2884 return(0); 2885 else 2886 return(1); 2887 } 2888 2889 int fill_if_group(int endif_index, JUMP_PTRS_ST* jump_data) 2890 { 2891 int i = endif_index; 2892 int ljp = endif_index; /* ljp means "last jump processed" */ 2893 while(i > 0) { 2894 i--; 2895 switch (jump_control[i].type) { 2896 case 1: /*if(); this concludes processing of this group*/ 2897 jump_control[i].ptrs = jump_data[ljp]; 2898 jump_control[i].DestJumpIndex = ljp + 1; 2899 return i; 2900 case 2: /*elseif* ( 2 jumps, the else and the if*/ 2901 /* first, the "if" part */ 2902 jump_control[i].ptrs = jump_data[ljp]; 2903 jump_control[i].DestJumpIndex = ljp + 1; 2904 2905 /* then, the else part */ 2906 i--; /*fall through to "else" is intentional*/ 2907 case 3: 2908 jump_control[i].ptrs = jump_data[endif_index]; 2909 jump_control[i].DestJumpIndex = endif_index + 1; 2910 ljp = i; 2911 break; 2912 case 4: /*endif*/ 2913 i = fill_if_group(i, jump_data); 2914 break; 2915 default: 2916 break; 2917 } 2918 } 2919 return -1; /* should never get here */ 2920 } 2921 2922 int fill_jump_struct(void) 2923 { /* Completes all entries in jump structure. Returns 1 on error) */ 2924 /* On entry, jump_index is the number of jump functions in the formula*/ 2925 int i = 0; 2926 int loadcount = 0; 2927 int storecount = 0; 2928 int checkforelse = 0; 2929 void (*JumpFunc)(void) = NULL; 2930 int find_new_func = 1; 2931 2932 JUMP_PTRS_ST jump_data[MAX_JUMPS]; 2933 2934 for (OpPtr = 0; OpPtr < (int) LastOp; OpPtr++) { 2935 if(find_new_func) { 2936 switch (jump_control[i].type) { 2937 case 1: 2938 JumpFunc = StkJumpOnFalse; 2939 break; 2940 case 2: 2941 checkforelse = !checkforelse; 2942 if(checkforelse) 2943 JumpFunc = StkJump; 2944 else 2945 JumpFunc = StkJumpOnFalse; 2946 break; 2947 case 3: 2948 JumpFunc = StkJump; 2949 break; 2950 case 4: 2951 JumpFunc = StkJumpLabel; 2952 break; 2953 default: 2954 break; 2955 } 2956 find_new_func = 0; 2957 } 2958 if(*(f[OpPtr]) == StkLod) 2959 loadcount++; 2960 else if(*(f[OpPtr]) == StkSto) 2961 storecount++; 2962 else if(*(f[OpPtr]) == JumpFunc) { 2963 jump_data[i].JumpOpPtr = OpPtr; 2964 jump_data[i].JumpLodPtr = loadcount; 2965 jump_data[i].JumpStoPtr = storecount; 2966 i++; 2967 find_new_func = 1; 2968 } 2969 } 2970 2971 /* Following for safety only; all should always be false */ 2972 if(i != jump_index || jump_control[i - 1].type != 4 2973 || jump_control[0].type != 1) { 2974 return 1; 2975 } 2976 2977 while(i > 0) { 2978 i--; 2979 i = fill_if_group(i, jump_data); 2980 } 2981 return i < 0 ? 1 : 0; 2982 } 2983 2984 static char *FormStr; 2985 2986 #if (_MSC_VER >= 700) 2987 #pragma code_seg ("parser1_text") /* place following in an overlay */ 2988 #endif 2989 2990 int frmgetchar (FILE * openfile) 2991 { 2992 int c; 2993 int done = 0; 2994 int linewrap = 0; 2995 while (!done) { 2996 c = getc(openfile); 2997 switch (c) { 2998 case '\r': case ' ' : case '\t' : 2999 break; 3000 case '\\': 3001 linewrap = 1; 3002 break; 3003 case ';' : 3004 while ((c = getc(openfile)) != '\n' && c != EOF && c != '\032') 3005 {} 3006 if(c == EOF || c == '\032') 3007 done = 1; 3008 case '\n' : 3009 if(!linewrap) 3010 done = 1; 3011 linewrap = 0; 3012 break; 3013 default: 3014 done = 1; 3015 break; 3016 } 3017 } 3018 return tolower(c); 3019 } 3020 3021 /* This function also gets flow control info */ 3022 3023 void getfuncinfo(struct token_st * tok) 3024 { 3025 int i; 3026 for(i=0; i < sizeof(FnctList)/ sizeof(struct FNCT_LIST); i++) { 3027 if(!far_strcmp(FnctList[i].s, tok->token_str)) { 3028 tok->token_id = i; 3029 if(i >= 11 && i <= 14) 3030 tok->token_type = PARAM_FUNCTION; 3031 else 3032 tok->token_type = FUNCTION; 3033 return; 3034 } 3035 } 3036 3037 for (i=0; i < 4; i++) { /*pick up flow control*/ 3038 if(!far_strcmp(JumpList[i], tok->token_str)) { 3039 tok->token_type = FLOW_CONTROL; 3040 tok->token_id = i + 1; 3041 return; 3042 } 3043 } 3044 tok->token_type = NOT_A_TOKEN; 3045 tok->token_id = UNDEFINED_FUNCTION; 3046 return; 3047 } 3048 3049 void getvarinfo(struct token_st * tok) 3050 { 3051 int i; 3052 3053 for(i=0; i < sizeof(Constants) / sizeof(char*); i++) { 3054 if(!far_strcmp(Constants[i], tok->token_str)) { 3055 tok->token_id = i; 3056 switch(i) { 3057 case 1: case 2: case 8: case 13: case 17: case 18: 3058 tok->token_type = PARAM_VARIABLE; 3059 break; 3060 default: 3061 tok->token_type = PREDEFINED_VARIABLE; 3062 break; 3063 } 3064 return; 3065 } 3066 } 3067 tok->token_type = USER_NAMED_VARIABLE; 3068 tok->token_id = 0; 3069 } 3070 3071 /* fills in token structure where numeric constant is indicated */ 3072 /* Note - this function will be called twice to fill in the components 3073 of a complex constant. See is_complex_constant() below. */ 3074 3075 /* returns 1 on success, 0 on NOT_A_TOKEN */ 3076 3077 int frmgetconstant(FILE * openfile, struct token_st * tok) 3078 { 3079 int c; 3080 int i = 1; 3081 int getting_base = 1; 3082 long filepos = ftell(openfile); 3083 int got_decimal_already = 0; 3084 int done = 0; 3085 tok->token_const.x = 0.0; /*initialize values to 0*/ 3086 tok->token_const.y = 0.0; 3087 if(tok->token_str[0] == '.') 3088 got_decimal_already = 1; 3089 while (!done) { 3090 switch (c=frmgetchar(openfile)) { 3091 case EOF: case '\032': 3092 tok->token_str[i] = (char) 0; 3093 tok->token_type = NOT_A_TOKEN; 3094 tok->token_id = END_OF_FILE; 3095 return 0; 3096 CASE_NUM: 3097 tok->token_str[i++] = (char) c; 3098 filepos=ftell(openfile); 3099 break; 3100 case '.': 3101 if (got_decimal_already || !getting_base) { 3102 tok->token_str[i++] = (char) c; 3103 tok->token_str[i++] = (char) 0; 3104 tok->token_type = NOT_A_TOKEN; 3105 tok->token_id = ILL_FORMED_CONSTANT; 3106 return 0; 3107 } 3108 else { 3109 tok->token_str[i++] = (char) c; 3110 got_decimal_already = 1; 3111 filepos=ftell(openfile); 3112 } 3113 break; 3114 default : 3115 if(c == 'e' && getting_base && (isdigit(tok->token_str[i-1]) || (tok->token_str[i-1] == '.' && i > 1))) { 3116 tok->token_str[i++] = (char) c; 3117 getting_base = 0; 3118 got_decimal_already = 0; 3119 filepos=ftell(openfile); 3120 if((c = frmgetchar(openfile)) == '-' || c == '+') { 3121 tok->token_str[i++] = (char) c; 3122 filepos = ftell(openfile); 3123 } 3124 else { 3125 fseek(openfile, filepos, SEEK_SET); 3126 } 3127 } 3128 else if(isalpha(c) || c == '_') { 3129 tok->token_str[i++] = (char) c; 3130 tok->token_str[i++] = (char) 0; 3131 tok->token_type = NOT_A_TOKEN; 3132 tok->token_id = ILL_FORMED_CONSTANT; 3133 return 0; 3134 } 3135 else if (tok->token_str[i-1] == 'e' || (tok->token_str[i-1] == '.' && i == 1)) { 3136 tok->token_str[i++] = (char) c; 3137 tok->token_str[i++] = (char) 0; 3138 tok->token_type = NOT_A_TOKEN; 3139 tok->token_id = ILL_FORMED_CONSTANT; 3140 return 0; 3141 } 3142 else { 3143 fseek(openfile, filepos, SEEK_SET); 3144 tok->token_str[i++] = (char) 0; 3145 done = 1; 3146 } 3147 break; 3148 } 3149 if (i == 33 && tok->token_str[32]) { 3150 tok->token_str[33] = (char) 0; 3151 tok->token_type = NOT_A_TOKEN; 3152 tok->token_id = TOKEN_TOO_LONG; 3153 return 0; 3154 } 3155 } /* end of while loop. Now fill in the value */ 3156 tok->token_const.x = atof(tok->token_str); 3157 tok->token_type = REAL_CONSTANT; 3158 tok->token_id = 0; 3159 return 1; 3160 } 3161 3162 void is_complex_constant(FILE * openfile, struct token_st * tok) 3163 { 3164 /* should test to make sure tok->token_str[0] == '(' */ 3165 struct token_st temp_tok; 3166 long filepos; 3167 int c; 3168 int sign_value = 1; 3169 int done = 0; 3170 int getting_real = 1; 3171 FILE * debug_token = NULL; 3172 tok->token_str[1] = (char) 0; /* so we can concatenate later */ 3173 3174 filepos = ftell(openfile); 3175 if (debugflag == 96) { 3176 debug_token = fopen("frmconst.txt","at"); 3177 } 3178 3179 while (!done) { 3180 switch (c = frmgetchar(openfile)) { 3181 CASE_NUM : case '.': 3182 if (debug_token != NULL) { 3183 fprintf(debug_token, "Set temp_tok.token_str[0] to %c\n", c); 3184 } 3185 temp_tok.token_str[0] = (char) c; 3186 break; 3187 case '-' : 3188 if (debug_token != NULL) { 3189 fprintf(debug_token, "First char is a minus\n"); 3190 } 3191 sign_value = -1; 3192 if ((c = frmgetchar(openfile)) == '.' || isdigit(c)) { 3193 if (debug_token != NULL) { 3194 fprintf(debug_token, "Set temp_tok.token_str[0] to %c\n", c); 3195 } 3196 temp_tok.token_str[0] = (char) c; 3197 } 3198 else { 3199 if (debug_token != NULL) { 3200 fprintf(debug_token, "First char not a . or NUM\n"); 3201 } 3202 done = 1; 3203 } 3204 break; 3205 default: 3206 if (debug_token != NULL) { 3207 fprintf(debug_token, "First char not a . or NUM\n"); 3208 } 3209 done = 1; 3210 break; 3211 } 3212 if (debug_token != NULL) { 3213 fprintf(debug_token, "Calling frmgetconstant unless done is 1; done is %d\n", done); 3214 } 3215 if (!done && frmgetconstant (openfile, &temp_tok)) { 3216 c = frmgetchar(openfile); 3217 if (debug_token != NULL) { 3218 fprintf(debug_token, "frmgetconstant returned 1; next token is %c\n", c); 3219 } 3220 if (getting_real && c == ',') { /*we have the real part now*/ 3221 if (sign_value == -1) { 3222 strcat(tok->token_str, "-"); 3223 } 3224 strcat(tok->token_str, temp_tok.token_str); 3225 strcat(tok->token_str, ","); 3226 tok->token_const.x = temp_tok.token_const.x * sign_value; 3227 getting_real = 0; 3228 sign_value = 1; 3229 } 3230 else if (!getting_real && c == ')') { /* we have the complex part */ 3231 if (sign_value == -1) { 3232 strcat(tok->token_str, "-"); 3233 } 3234 strcat(tok->token_str, temp_tok.token_str); 3235 strcat(tok->token_str, ")"); 3236 tok->token_const.y = temp_tok.token_const.x * sign_value; 3237 tok->token_type = tok->token_const.y ? COMPLEX_CONSTANT : REAL_CONSTANT; 3238 tok->token_id = 0; 3239 if (debug_token != NULL) { 3240 fprintf(debug_token, "Exiting with type set to %d\n", tok->token_const.y ? COMPLEX_CONSTANT : REAL_CONSTANT); 3241 fclose (debug_token); 3242 } 3243 return; 3244 } 3245 else 3246 done = 1; 3247 } 3248 else 3249 done = 1; 3250 } 3251 fseek (openfile, filepos, SEEK_SET); 3252 tok->token_str[1] = (char) 0; 3253 tok->token_const.y = tok->token_const.x = 0.0; 3254 tok->token_type = PARENS; 3255 tok->token_id = OPEN_PARENS; 3256 if (debug_token != NULL) { 3257 fprintf(debug_token, "Exiting with ID set to OPEN_PARENS\n"); 3258 fclose (debug_token); 3259 } 3260 return; 3261 } 3262 3263 int frmgetalpha(FILE * openfile, struct token_st * tok) 3264 { 3265 int c; 3266 int i = 1; 3267 int var_name_too_long = 0; 3268 long filepos; 3269 long last_filepos = ftell(openfile); 3270 while ((c=frmgetchar(openfile)) != EOF && c != '\032') { 3271 filepos = ftell(openfile); 3272 switch (c) { 3273 CASE_ALPHA: CASE_NUM: case '_': 3274 if (i<79) 3275 tok->token_str[i++] = (char) c; 3276 else { 3277 tok->token_str[i] = (char) 0; 3278 } 3279 if(i == 33) { 3280 var_name_too_long=1; 3281 } 3282 last_filepos = filepos; 3283 break; 3284 default: 3285 if (c == '.') { /*illegal character in variable or func name*/ 3286 tok->token_type = NOT_A_TOKEN; 3287 tok->token_id = ILLEGAL_VARIABLE_NAME; 3288 tok->token_str[i++] = '.'; 3289 tok->token_str[i] = (char) 0; 3290 return 0; 3291 } 3292 else if (var_name_too_long) { 3293 tok->token_type = NOT_A_TOKEN; 3294 tok->token_id = TOKEN_TOO_LONG; 3295 tok->token_str[i] = (char) 0; 3296 fseek(openfile, last_filepos, SEEK_SET); 3297 return 0; 3298 } 3299 tok->token_str[i] = (char) 0; 3300 fseek(openfile, last_filepos, SEEK_SET); 3301 getfuncinfo(tok); 3302 if(c=='(') { /*getfuncinfo() correctly filled structure*/ 3303 if (tok->token_type == NOT_A_TOKEN) 3304 return 0; 3305 else if (tok->token_type == FLOW_CONTROL && (tok->token_id == 3 || tok->token_id == 4)) { 3306 tok->token_type = NOT_A_TOKEN; 3307 tok->token_id = JUMP_WITH_ILLEGAL_CHAR; 3308 return 0; 3309 } 3310 else 3311 return 1; 3312 } 3313 /*can't use function names as variables*/ 3314 else if(tok->token_type == FUNCTION || tok->token_type == PARAM_FUNCTION) { 3315 tok->token_type = NOT_A_TOKEN; 3316 tok->token_id = FUNC_USED_AS_VAR; 3317 return 0; 3318 } 3319 else if(tok->token_type == FLOW_CONTROL && (tok->token_id == 1 || tok->token_id == 2)) { 3320 tok->token_type = NOT_A_TOKEN; 3321 tok->token_id = JUMP_MISSING_BOOLEAN; 3322 return 0; 3323 } 3324 else if (tok->token_type == FLOW_CONTROL && (tok->token_id == 3 || tok->token_id == 4)) { 3325 if (c == ',' || c == '\n' || c == ':') 3326 return 1; 3327 else { 3328 tok->token_type = NOT_A_TOKEN; 3329 tok->token_id = JUMP_WITH_ILLEGAL_CHAR; 3330 return 0; 3331 } 3332 } 3333 else { 3334 getvarinfo(tok); 3335 return 1; 3336 } 3337 } 3338 } 3339 tok->token_str[0] = (char) 0; 3340 tok->token_type = NOT_A_TOKEN; 3341 tok->token_id = END_OF_FILE; 3342 return 0; 3343 } 3344 3345 void frm_get_eos (FILE * openfile, struct token_st * this_token) 3346 { 3347 long last_filepos = ftell(openfile); 3348 int c; 3349 while ((c = frmgetchar(openfile)) == '\n' || c == ',' || c == ':') { 3350 if (c == ':') { 3351 this_token->token_str[0] = ':'; 3352 } 3353 last_filepos = ftell(openfile); 3354 } 3355 if (c == '}') { 3356 this_token->token_str[0] = '}'; 3357 this_token->token_type = END_OF_FORMULA; 3358 this_token->token_id = 0; 3359 } 3360 else { 3361 fseek (openfile, last_filepos, SEEK_SET); 3362 if (this_token->token_str[0] == '\n') { 3363 this_token->token_str[0] = ','; 3364 } 3365 } 3366 } 3367 3368 /*frmgettoken fills token structure; returns 1 on success and 0 on 3369 NOT_A_TOKEN and END_OF_FORMULA 3370 */ 3371 3372 int frmgettoken(FILE * openfile, struct token_st * this_token) 3373 { 3374 int c; 3375 int i=1; 3376 long filepos; 3377 3378 switch (c = frmgetchar(openfile)) { 3379 CASE_NUM: case '.': 3380 this_token->token_str[0] = (char) c; 3381 return frmgetconstant(openfile, this_token); 3382 CASE_ALPHA: case '_': 3383 this_token->token_str[0] = (char) c; 3384 return frmgetalpha(openfile, this_token); 3385 CASE_TERMINATOR: 3386 this_token->token_type = OPERATOR; /* this may be changed below */ 3387 this_token->token_str[0] = (char) c; 3388 filepos = ftell(openfile); 3389 if(c=='<' || c=='>' || c=='=') { 3390 if((c=frmgetchar(openfile)) == '=') 3391 this_token->token_str[i++] = (char) c; 3392 else { 3393 fseek(openfile, filepos, SEEK_SET); 3394 } 3395 } 3396 else if(c=='!') { 3397 if((c=frmgetchar(openfile)) == '=') 3398 this_token->token_str[i++] = (char) c; 3399 else { 3400 fseek(openfile, filepos, SEEK_SET); 3401 this_token->token_str[1] = (char) 0; 3402 this_token->token_type = NOT_A_TOKEN; 3403 this_token->token_id = ILLEGAL_OPERATOR; 3404 return 0; 3405 } 3406 } 3407 else if(c=='|') { 3408 if((c=frmgetchar(openfile)) == '|') 3409 this_token->token_str[i++] = (char) c; 3410 else 3411 fseek(openfile, filepos, SEEK_SET); 3412 } 3413 else if (c=='&') { 3414 if((c=frmgetchar(openfile)) == '&') 3415 this_token->token_str[i++] = (char) c; 3416 else { 3417 fseek(openfile, filepos, SEEK_SET); 3418 this_token->token_str[1] = (char) 0; 3419 this_token->token_type = NOT_A_TOKEN; 3420 this_token->token_id = ILLEGAL_OPERATOR; 3421 return 0; 3422 } 3423 } 3424 else if(this_token->token_str[0] == '}') { 3425 this_token->token_type = END_OF_FORMULA; 3426 this_token->token_id = 0; 3427 } 3428 else if (this_token->token_str[0] == '\n' 3429 || this_token->token_str[0] == ',' 3430 || this_token->token_str[0] == ':' ) { 3431 frm_get_eos(openfile, this_token); 3432 } 3433 else if (this_token->token_str[0] == ')') { 3434 this_token->token_type = PARENS; 3435 this_token->token_id = CLOSE_PARENS; 3436 } 3437 else if (this_token->token_str[0] == '(') { 3438 /* the following function will set token_type to PARENS and 3439 token_id to OPEN_PARENS if this is not the start of a 3440 complex constant */ 3441 is_complex_constant(openfile, this_token); 3442 return 1; 3443 } 3444 this_token->token_str[i] = (char) 0; 3445 if(this_token->token_type == OPERATOR) { 3446 for(i=0; i < sizeof(OPList)/sizeof(struct OP_LIST); i++) { 3447 if(!far_strcmp(OPList[i].s, this_token->token_str)) { 3448 this_token->token_id = i; 3449 } 3450 } 3451 } 3452 return this_token->token_str[0] == '}' ? 0 : 1; 3453 case EOF: case '\032': 3454 this_token->token_str[0] = (char) 0; 3455 this_token->token_type = NOT_A_TOKEN; 3456 this_token->token_id = END_OF_FILE; 3457 return 0; 3458 default: 3459 this_token->token_str[0] = (char) c; 3460 this_token->token_str[1] = (char) 0; 3461 this_token->token_type = NOT_A_TOKEN; 3462 this_token->token_id = ILLEGAL_CHARACTER; 3463 return 0; 3464 } 3465 } 3466 3467 int frm_get_param_stuff (char * Name) 3468 { 3469 FILE *debug_token = NULL; 3470 int c; 3471 struct token_st current_token; 3472 FILE * entry_file = NULL; 3473 uses_p1 = uses_p2 = uses_p3 = uses_ismand = maxfn = 0; 3474 uses_p4 = uses_p5 = 0; 3475 3476 if (FormName[0] == 0 ) { 3477 return 0; /* and don't reset the pointers */ 3478 } 3479 if (find_file_item(FormFileName,Name,&entry_file, 1)) { 3480 stopmsg(0, ParseErrs(PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED)); 3481 return 0; 3482 } 3483 while((c=frmgetchar(entry_file)) != '{' && c != EOF && c != '\032') 3484 {} 3485 if (c != '{') { 3486 stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); 3487 fclose(entry_file); 3488 return 0; 3489 } 3490 3491 if(debugflag == 96) { 3492 if((debug_token = fopen("frmtokens.txt","at")) != NULL) 3493 fprintf(debug_token,"%s\n", Name); 3494 } 3495 while(frmgettoken(entry_file, &current_token)) { 3496 if (debug_token != NULL) { 3497 fprintf(debug_token,"%s\n", current_token.token_str); 3498 fprintf(debug_token,"token_type is %d\n", current_token.token_type); 3499 fprintf(debug_token,"token_id is %d\n", current_token.token_id); 3500 if (current_token.token_type == REAL_CONSTANT || current_token.token_type == COMPLEX_CONSTANT) { 3501 fprintf(debug_token,"Real value is %f\n", current_token.token_const.x); 3502 fprintf(debug_token,"Imag value is %f\n", current_token.token_const.y); 3503 } 3504 fprintf(debug_token,"\n"); 3505 } 3506 switch (current_token.token_type) { 3507 case PARAM_VARIABLE: 3508 if(current_token.token_id == 1) 3509 uses_p1 = 1; 3510 else if(current_token.token_id == 2) 3511 uses_p2 = 1; 3512 else if(current_token.token_id == 8) 3513 uses_p3 = 1; 3514 else if(current_token.token_id == 13) 3515 uses_ismand = 1; 3516 else if(current_token.token_id == 17) 3517 uses_p4 = 1; 3518 else if(current_token.token_id == 18) 3519 uses_p5 = 1; 3520 break; 3521 case PARAM_FUNCTION: 3522 if((current_token.token_id - 10) > maxfn) 3523 maxfn = (char) (current_token.token_id - 10); 3524 break; 3525 } 3526 } 3527 fclose(entry_file); 3528 if(debug_token) 3529 fclose(debug_token); 3530 if (current_token.token_type != END_OF_FORMULA) { 3531 uses_p1 = uses_p2 = uses_p3 = uses_ismand = maxfn = 0; 3532 uses_p4 = uses_p5 = 0; 3533 return 0; 3534 } 3535 return 1; 3536 } 3537 3538 /* frm_check_name_and_sym(): 3539 error checking to the open brace on the first line; return 1 3540 on success, 2 if an invalid symmetry is found, and 0 if errors 3541 are found which should cause the formula not to be executed 3542 */ 3543 3544 int frm_check_name_and_sym (FILE * open_file, int report_bad_sym) 3545 { 3546 long filepos = ftell(open_file); 3547 int c, i, done, at_end_of_name; 3548 3549 /* first, test name */ 3550 done = at_end_of_name = i = 0; 3551 while(!done) { 3552 switch (c = getc(open_file)) { 3553 case EOF: case '\032': 3554 stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); 3555 return 0; 3556 case '\r': case '\n': 3557 stopmsg(0,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); 3558 return 0; 3559 case ' ': case '\t': 3560 at_end_of_name = 1; 3561 break; 3562 case '(': case '{': 3563 done = 1; 3564 break; 3565 default : 3566 if (!at_end_of_name) 3567 i++; 3568 break; 3569 } 3570 } 3571 3572 if(i > ITEMNAMELEN) { 3573 int j; 3574 int k = far_strlen(ParseErrs(PE_FORMULA_NAME_TOO_LARGE)); 3575 char msgbuf[100]; 3576 far_strcpy(msgbuf, ParseErrs(PE_FORMULA_NAME_TOO_LARGE)); 3577 strcat(msgbuf, ":\n "); 3578 fseek(open_file, filepos, SEEK_SET); 3579 for(j = 0; j < i && j < 25; j++) 3580 msgbuf[j+k+2] = (char) getc(open_file); 3581 msgbuf[j+k+2] = (char) 0; 3582 stopmsg(8, msgbuf); 3583 return 0; 3584 } 3585 /* get symmetry */ 3586 symmetry = 0; 3587 if (c == '(') { 3588 char sym_buf[20]; 3589 done = i = 0; 3590 while(!done) { 3591 switch (c = getc(open_file)) { 3592 case EOF: case '\032': 3593 stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); 3594 return 0; 3595 case '\r': case '\n': 3596 stopmsg(8,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); 3597 return 0; 3598 case '{': 3599 stopmsg(8,ParseErrs(PE_NO_MATCH_RIGHT_PAREN)); 3600 return 0; 3601 case ' ': case '\t': 3602 break; 3603 case ')': 3604 done = 1; 3605 break; 3606 default : 3607 if(i < 19) 3608 sym_buf[i++] = (char) toupper(c); 3609 break; 3610 } 3611 } 3612 sym_buf[i] = (char) 0; 3613 for(i = 0; SymStr[i].s[0]; i++) { 3614 if(!stricmp(SymStr[i].s, sym_buf)) { 3615 symmetry = SymStr[i].n; 3616 break; 3617 } 3618 } 3619 if(SymStr[i].s[0] == (char) 0 && report_bad_sym) { 3620 char far * msgbuf = (char far*) farmemalloc(far_strlen(ParseErrs(PE_INVALID_SYM_USING_NOSYM)) 3621 + strlen(sym_buf) + 6); 3622 far_strcpy(msgbuf, ParseErrs(PE_INVALID_SYM_USING_NOSYM)); 3623 far_strcat(msgbuf, ":\n "); 3624 far_strcat(msgbuf, sym_buf); 3625 stopmsg(8, msgbuf); 3626 farmemfree(msgbuf); 3627 } 3628 } 3629 if (c != '{') { 3630 done = 0; 3631 while(!done) { 3632 switch (c = getc(open_file)) { 3633 case EOF: case '\032': 3634 stopmsg(8,ParseErrs(PE_UNEXPECTED_EOF)); 3635 return 0; 3636 case '\r': case '\n': 3637 stopmsg(8,ParseErrs(PE_NO_LEFT_BRACKET_FIRST_LINE)); 3638 return 0; 3639 case '{': 3640 done = 1; 3641 break; 3642 default : 3643 break; 3644 } 3645 } 3646 } 3647 return 1; 3648 } 3649 3650 3651 static char *PrepareFormula(FILE * File, int from_prompts1c) { 3652 3653 /* GGM 5-23-96: replaces FindFormula(). This function sets the 3654 symmetry and converts a formula into a string with no spaces, 3655 and one comma after each expression except where the ':' is placed 3656 and except the final expression in the formula. The open file passed 3657 as an argument is open in "rb" mode and is positioned at the first 3658 letter of the name of the formula to be prepared. This function 3659 is called from RunForm() below. 3660 */ 3661 3662 FILE *debug_fp = NULL; 3663 char *FormulaStr; 3664 struct token_st temp_tok; 3665 int Done; 3666 long filepos = ftell(File); 3667 3668 /* char debugmsg[500]; 3669 */ 3670 3671 /*Test for a repeat*/ 3672 3673 if (frm_check_name_and_sym(File, from_prompts1c) == 0) { 3674 fseek(File, filepos, SEEK_SET); 3675 return NULL; 3676 } 3677 if(!frm_prescan(File)) { 3678 fseek(File, filepos, SEEK_SET); 3679 return NULL; 3680 } 3681 3682 if(chars_in_formula > 8190) { 3683 fseek(File, filepos, SEEK_SET); 3684 return NULL; 3685 } 3686 3687 if(debugflag == 96) 3688 { 3689 if((debug_fp = fopen("debugfrm.txt","at")) != NULL) { 3690 fprintf(debug_fp,"%s\n",FormName); 3691 if(symmetry != 0) 3692 fprintf(debug_fp,"%s\n", SymStr[symmetry].s); 3693 } 3694 } 3695 3696 FormulaStr = (char *)boxx; 3697 FormulaStr[0] = (char) 0; /* To permit concantenation later */ 3698 3699 Done = 0; 3700 3701 /*skip opening end-of-lines */ 3702 while(!Done) { 3703 frmgettoken(File, &temp_tok); 3704 if (temp_tok.token_type == NOT_A_TOKEN) { 3705 stopmsg(8, "Unexpected token error in PrepareFormula\n"); 3706 fseek(File, filepos, SEEK_SET); 3707 return NULL; 3708 } 3709 else if (temp_tok.token_type == END_OF_FORMULA) { 3710 stopmsg(8, "Formula has no executable instructions\n"); 3711 fseek(File, filepos, SEEK_SET); 3712 return NULL; 3713 } 3714 if (temp_tok.token_str[0] == ',') 3715 ; 3716 else { 3717 strcat(FormulaStr, temp_tok.token_str); 3718 Done = 1; 3719 } 3720 } 3721 3722 Done = 0; 3723 while(!Done) { 3724 frmgettoken(File, &temp_tok); 3725 switch (temp_tok.token_type) { 3726 case NOT_A_TOKEN: 3727 stopmsg(8, "Unexpected token error in PrepareFormula\n"); 3728 fseek(File, filepos, SEEK_SET); 3729 return NULL; 3730 case END_OF_FORMULA: 3731 Done = 1; 3732 fseek(File, filepos, SEEK_SET); 3733 break; 3734 default: 3735 strcat(FormulaStr, temp_tok.token_str); 3736 break; 3737 } 3738 } 3739 3740 if(debug_fp != NULL && FormulaStr != NULL) 3741 fprintf(debug_fp," %s\n",FormulaStr); 3742 if(debug_fp != NULL) 3743 fclose(debug_fp); 3744 3745 3746 /* sprintf(debugmsg, "Chars in formula per boxx is %u.\n", strlen(FormulaStr)); 3747 stopmsg(0, debugmsg); 3748 */ 3749 return FormulaStr; 3750 } 3751 3752 int BadFormula(void) { 3753 /* moved from Parsera.Asm by CAE 12 July 1993 */ 3754 3755 /* this is called when a formula is bad, instead of calling */ 3756 /* the normal functions which will produce undefined results */ 3757 return 1; 3758 } 3759 3760 int RunForm(char *Name, int from_prompts1c) { /* returns 1 if an error occurred */ 3761 3762 FILE * entry_file = NULL; 3763 3764 /* CAE changed fn 12 July 1993 to fix problem when formula not found */ 3765 3766 /* first set the pointers so they point to a fn which always returns 1 */ 3767 curfractalspecific->per_pixel = BadFormula; 3768 curfractalspecific->orbitcalc = BadFormula; 3769 3770 if (FormName[0] == 0 ){ 3771 return 1; /* and don't reset the pointers */ 3772 } 3773 3774 /* TW 5-31-94 add search for FRM files in directory */ 3775 if (find_file_item(FormFileName,Name,&entry_file, 1)) { 3776 stopmsg(0, ParseErrs(PE_COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED)); 3777 return 1; 3778 } 3779 3780 FormStr = PrepareFormula(entry_file, from_prompts1c ); 3781 fclose(entry_file); 3782 3783 if(FormStr) /* No errors while making string */ 3784 { 3785 parser_allocate(); /* ParseStr() will test if this alloc worked */ 3786 if (ParseStr(FormStr,1)) 3787 return 1; /* parse failed, don't change fn pointers */ 3788 else 3789 { 3790 if(uses_jump == 1 && fill_jump_struct() == 1) { 3791 stopmsg(0, ParseErrs(PE_ERROR_IN_PARSING_JUMP_STATEMENTS)); 3792 return 1; 3793 } 3794 3795 /* all parses succeeded so set the pointers back to good functions*/ 3796 curfractalspecific->per_pixel = form_per_pixel; 3797 curfractalspecific->orbitcalc = Formula; 3798 return 0; 3799 } 3800 } 3801 else 3802 return 1; /* error in making string*/ 3803 } 3804 3805 3806 int fpFormulaSetup(void) { 3807 3808 int RunFormRes; /* CAE fp */ 3809 #ifndef XFRACT 3810 if (fpu > 0) { 3811 MathType = D_MATH; 3812 /* CAE changed below for fp */ 3813 RunFormRes = !RunForm(FormName, 0); /* RunForm() returns 1 for failure */ 3814 if (RunFormRes && fpu >=387 && debugflag != 90 && (orbitsave&2) == 0 3815 && !Randomized) 3816 return CvtStk(); /* run fast assembler code in parsera.asm */ 3817 return RunFormRes; 3818 } 3819 else { 3820 MathType = M_MATH; 3821 return !RunForm(FormName, 0); 3822 }
3823 #else 3824 MathType = D_MATH; 3825 RunFormRes = !RunForm(FormName, 0); /* RunForm() returns 1 for failure */ 3826 #if 0 3827 if (RunFormRes && fpu == -1 && debugflag != 90 && (orbitsave&2) == 0 3828 && !Randomized) 3829 return CvtStk(); /* run fast assembler code in parsera.asm */ 3830 #endif 3831 return RunFormRes;
3832 #endif 3833 } 3834 3835 int intFormulaSetup(void) { 3836 #ifdef XFRACT
3837 printf("intFormulaSetup called!!!\n"); 3838 exit(-1);
3839 #else 3840 MathType = L_MATH; 3841 fg = (double)(1L << bitshift); 3842 fgLimit = (double)0x7fffffffL / fg; 3843 ShiftBack = 32 - bitshift; 3844 #endif 3845 return(!RunForm(FormName, 0)); 3846 } 3847 3848 3849 /* TIW added 06-20-90 so functions can be called from fractals.c */ 3850 void init_misc() 3851 { 3852 static struct ConstArg far vv[5]; 3853 static union Arg argfirst,argsecond; 3854 if(!v) 3855 v = vv; 3856 Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */ 3857 fg = (double)(1L << bitshift); 3858 fgLimit = (double)0x7fffffffL / fg; 3859 ShiftBack = 32 - bitshift; 3860 Delta16 = bitshift - 16; 3861 bitshiftless1 = bitshift-1; 3862 uses_p1 = uses_p2 = uses_p3 = uses_jump = uses_ismand = 0; 3863 uses_p4 = uses_p5 = 0; 3864 } 3865 3866 3867 /* PB 910417 here to end changed. 3868 Allocate sub-arrays from one main farmemalloc, using global variable 3869 typespecific_workarea; calcfrac.c releases this area when calculation 3870 ends or is terminated. 3871 Moved the "f" array to be allocated as part of this. 3872 */ 3873 3874 long total_formula_mem; 3875 BYTE used_extra = 0; 3876 static void parser_allocate(void) 3877 { 3878 /* CAE fp changed below for v18 */ 3879 /* Note that XFRACT will waste about 6k here for pfls */ 3880 /* Somewhat more memory is now allocated than in v17 here */ 3881 /* however Store and Load were reduced in size to help make up for it */ 3882 3883 long f_size,Store_size,Load_size,v_size, p_size; 3884 int pass, is_bad_form=0; 3885 long end_dx_array; 3886 /* TW Jan 1 1996 Made two passes to determine actual values of 3887 Max_Ops and Max_Args. Now use the end of extraseg if possible, so 3888 if less than 2048x2048 resolution is used, usually no farmemalloc 3889 calls are needed */ 3890 for(pass = 0; pass < 2; pass++) 3891 { 3892 free_workarea(); 3893 if(pass == 0) { 3894 Max_Ops = 2300; /* this value uses up about 64K memory */ 3895 Max_Args = (unsigned)(Max_Ops/2.5); 3896 } 3897 f_size = sizeof(void(far * far *)(void)) * Max_Ops; 3898 Store_size = sizeof(union Arg far *) * MAX_STORES; 3899 Load_size = sizeof(union Arg far *) * MAX_LOADS; 3900 v_size = sizeof(struct ConstArg) * Max_Args; 3901 p_size = sizeof(struct fls far *) * Max_Ops; 3902 total_formula_mem = f_size+Load_size+Store_size+v_size+p_size /*+ jump_size*/ 3903 + sizeof(struct PEND_OP) * Max_Ops; 3904 used_extra = 0; 3905 3906 if(use_grid) 3907 end_dx_array = 2L*(long)(xdots+ydots)*sizeof(double); 3908 else 3909 end_dx_array = 0; 3910 3911 if(pass == 0 || is_bad_form) 3912 { 3913 typespecific_workarea = (char far *)MK_FP(extraseg,0); 3914 used_extra = 1; 3915 } 3916 else if(1L<<16 > end_dx_array + total_formula_mem) 3917 { 3918 typespecific_workarea = (char far *)MK_FP(extraseg,0) + end_dx_array; 3919 used_extra = 1; 3920 } 3921 else if(is_bad_form == 0) 3922 { 3923 typespecific_workarea = 3924 (char far *)farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size)); 3925 used_extra = 0; 3926 } 3927 f = (void(far * far *)(void))typespecific_workarea; 3928 Store = (union Arg far * far *)(f + Max_Ops); 3929 Load = (union Arg far * far *)(Store + MAX_STORES); 3930 v = (struct ConstArg far *)(Load + MAX_LOADS); 3931 pfls = (struct fls far *)(v + Max_Args); 3932 3933 if(pass == 0) 3934 { 3935 if((is_bad_form = ParseStr(FormStr,pass)) == 0) 3936 { 3937 /* per Chuck Ebbert, fudge these up a little */ 3938 Max_Ops = posp+4; 3939 Max_Args = vsp+4; 3940 } 3941 typespecific_workarea = NULL; 3942 } 3943 } 3944 uses_p1 = uses_p2 = uses_p3 = uses_p4 = uses_p5 = 0; 3945 } 3946 3947 void free_workarea() 3948 { 3949 if(typespecific_workarea && used_extra == 0) { 3950 farmemfree(typespecific_workarea); 3951 } 3952 typespecific_workarea = NULL; 3953 Store = (union Arg far * far *)0; 3954 Load = (union Arg far * far *)0; 3955 v = (struct ConstArg far *)0; 3956 f = (void(far * far *)(void))0; /* CAE fp */ 3957 pfls = (struct fls far * )0; /* CAE fp */ 3958 total_formula_mem = 0; 3959 3960 /* restore extraseg */ 3961 if(integerfractal && !invert) 3962 fill_lx_array(); 3963 else 3964 fill_dx_array(); 3965 } 3966 3967 3968 struct error_data_st { 3969 long start_pos; 3970 long error_pos; 3971 int error_number; 3972 } errors[3]; 3973 3974 3975 void frm_error(FILE * open_file, long begin_frm) 3976 { 3977 struct token_st tok; 3978 /* char debugmsg[500]; 3979 */ int i, chars_to_error=0, chars_in_error=0, token_count; 3980 int statement_len, line_number; 3981 int done; 3982 char msgbuf[900]; 3983 long filepos; 3984 int j; 3985 int initialization_error; 3986 strcpy (msgbuf, "\n"); 3987 3988 for(j=0; j < 3 && errors[j].start_pos; j++) { 3989 initialization_error = errors[j].error_number == PE_SECOND_COLON ? 1 : 0; 3990 fseek(open_file, begin_frm, SEEK_SET); 3991 line_number = 1; 3992 while (ftell(open_file) != errors[j].error_pos) { 3993 if((i = fgetc(open_file)) == '\n') { 3994 line_number++; 3995 } 3996 else if (i == EOF || i == '}') { 3997 stopmsg(0, "Unexpected EOF or end-of-formula in error function.\n"); 3998 fseek (open_file, errors[j].error_pos, SEEK_SET); 3999 frmgettoken(open_file, &tok); /*reset file to end of error token */ 4000 return; 4001 } 4002 } 4003 #ifndef XFRACT 4004 sprintf(&msgbuf[strlen(msgbuf)], "Error(%d) at line %d: %Fs\n ", errors[j].error_number, line_number, ParseErrs(errors[j].error_number));
4005 #else 4006 sprintf(&msgbuf[strlen(msgbuf)], "Error(%d) at line %d: %s\n ", errors[j].error_number, line_number, ParseErrs(errors[j].error_number));
4007 #endif 4008 i = strlen(msgbuf); 4009 /* sprintf(debugmsg, "msgbuf is: %s\n and i is %d\n", msgbuf, i); 4010 stopmsg (0, debugmsg); 4011 */ fseek(open_file, errors[j].start_pos, SEEK_SET); 4012 statement_len = token_count = 0; 4013 done = 0; 4014 while(!done) { 4015 filepos = ftell (open_file); 4016 if(filepos == errors[j].error_pos) { 4017 /* stopmsg(0, "About to get error token\n"); 4018 */ chars_to_error = statement_len; 4019 frmgettoken(open_file, &tok); 4020 chars_in_error = strlen(tok.token_str); 4021 statement_len += chars_in_error; 4022 token_count++; 4023 /* sprintf(debugmsg, "Error is %s\nChars in error is %d\nChars to error is %d\n", tok.token_str, chars_in_error, chars_to_error); 4024 stopmsg (0, debugmsg); 4025 */ } 4026 else { 4027 frmgettoken(open_file, &tok); 4028 /* sprintf(debugmsg, "Just got %s\n", tok.token_str); 4029 stopmsg (0, debugmsg); 4030 */ statement_len += strlen(tok.token_str); 4031 token_count++; 4032 } 4033 if ((tok.token_type == END_OF_FORMULA) 4034 || (tok.token_type == OPERATOR 4035 && (tok.token_id == 0 || tok.token_id == 11)) 4036 || (tok.token_type == NOT_A_TOKEN && tok.token_id == END_OF_FILE)){ 4037 done = 1; 4038 if (token_count > 1 && !initialization_error) { 4039 token_count--; 4040 } 4041 } 4042 } 4043 fseek(open_file, errors[j].start_pos, SEEK_SET); 4044 if(chars_in_error < 74) { 4045 while (chars_to_error + chars_in_error > 74) { 4046 /* stopmsg(0, "chars in error less than 74, but late in line"); 4047 */ frmgettoken(open_file, &tok); 4048 chars_to_error -= strlen(tok.token_str); 4049 token_count--; 4050 } 4051 } 4052 else { 4053 fseek(open_file, errors[j].error_pos, SEEK_SET); 4054 chars_to_error = 0; 4055 token_count = 1; 4056 } 4057 /* stopmsg(0, "Back to beginning of statement to build msgbuf"); 4058 */ while (strlen(&msgbuf[i]) <=74 && token_count--) { 4059 frmgettoken (open_file, &tok); 4060 strcat (msgbuf, tok.token_str); 4061 /* stopmsg(0, &msgbuf[i]); 4062 */ } 4063 fseek (open_file, errors[j].error_pos, SEEK_SET); 4064 frmgettoken (open_file, &tok); 4065 if (strlen(&msgbuf[i]) > 74) 4066 msgbuf[i + 74] = (char) 0; 4067 strcat(msgbuf, "\n"); 4068 i = strlen(msgbuf); 4069 while (chars_to_error-- > -2) 4070 strcat (msgbuf, " "); 4071 /* sprintf(debugmsg, "Going into final line, chars in error is %d", chars_in_error); 4072 stopmsg(0, debugmsg); 4073 */ 4074 if(errors[j].error_number == PE_TOKEN_TOO_LONG) { 4075 chars_in_error = 33; 4076 } 4077 while (chars_in_error-- && strlen(&msgbuf[i]) <=74) 4078 strcat (msgbuf, "^"); 4079 strcat (msgbuf, "\n"); 4080 } 4081 stopmsg (8, msgbuf); 4082 return; 4083 } 4084 4085 void display_var_list() 4086 { 4087 struct var_list_st far * p; 4088 stopmsg(0, "List of user defined variables:\n"); 4089 for (p = var_list; p; p=p->next_item) { 4090 stopmsg(0, p->name); 4091 } 4092 4093 } 4094 4095 void display_const_lists() 4096 { 4097 struct const_list_st far * p; 4098 char msgbuf[800]; 4099 stopmsg (0, "Complex constants are:"); 4100 for (p = complx_list; p; p=p->next_item) { 4101 sprintf(msgbuf, "%f, %f\n", p->complex_const.x, p->complex_const.y); 4102 stopmsg(0, msgbuf); 4103 } 4104 stopmsg (0, "Real constants are:"); 4105 for (p = real_list; p; p=p->next_item) { 4106 sprintf(msgbuf, "%f, %f\n", p->complex_const.x, p->complex_const.y); 4107 stopmsg(0, msgbuf); 4108 } 4109 } 4110 4111 4112 struct var_list_st far *var_list_alloc() { 4113 return (struct var_list_st far*) farmemalloc(sizeof(struct var_list_st)); 4114 } 4115 4116 4117 struct const_list_st far *const_list_alloc() { 4118 return (struct const_list_st far *) farmemalloc(sizeof(struct const_list_st)); 4119 } 4120 4121 void init_var_list() 4122 { 4123 struct var_list_st far * temp, far * p; 4124 for (p = var_list; p; p=temp) { 4125 temp = p->next_item; 4126 farmemfree(p); 4127 } 4128 var_list = NULL; 4129 } 4130 4131 4132 void init_const_lists() 4133 { 4134 struct const_list_st far * temp, far * p; 4135 for (p = complx_list; p; p=temp) { 4136 temp = p->next_item; 4137 farmemfree(p); 4138 } 4139 complx_list = NULL; 4140 for (p = real_list; p; p=temp) { 4141 temp = p->next_item; 4142 farmemfree(p); 4143 } 4144 real_list = NULL; 4145 } 4146 4147 struct var_list_st far * add_var_to_list (struct var_list_st far * p, struct token_st tok) { 4148 if (p == NULL) { 4149 if ((p = var_list_alloc()) == NULL) 4150 return NULL; 4151 far_strcpy(p->name, tok.token_str); 4152 p->next_item = NULL; 4153 } 4154 else if (far_strcmp(p->name, tok.token_str) == 0) { 4155 } 4156 else { 4157 if ((p->next_item = add_var_to_list(p->next_item, tok)) == NULL) 4158 return NULL; 4159 } 4160 return p; 4161 } 4162 4163 struct const_list_st far * add_const_to_list (struct const_list_st far * p, struct token_st tok) { 4164 if (p == NULL) { 4165 if ((p = const_list_alloc()) == NULL) 4166 return NULL; 4167 p->complex_const.x = tok.token_const.x; 4168 p->complex_const.y = tok.token_const.y; 4169 p->next_item = NULL; 4170 } 4171 else if (p->complex_const.x == tok.token_const.x && p->complex_const.y == tok.token_const.y) { 4172 } 4173 else 4174 if ((p->next_item = add_const_to_list(p->next_item, tok)) == NULL) 4175 return NULL; 4176 return p; 4177 } 4178 4179 void count_lists() 4180 { 4181 /* char msgbuf[800]; 4182 */ struct var_list_st far * p; 4183 struct const_list_st far * q; 4184 4185 var_count = 0; 4186 complx_count = 0; 4187 real_count = 0; 4188 4189 for (p = var_list; p; p=p->next_item) { 4190 var_count++; 4191 } 4192 for (q = complx_list; q; q=q->next_item) { 4193 complx_count++; 4194 } 4195 for (q = real_list; q; q=q->next_item) { 4196 real_count++; 4197 } 4198 /* sprintf(msgbuf, "Number of vars is %d\nNumber of complx is %d\nNumber of real is %d\n", var_count, complx_count, real_count); 4199 stopmsg(0, msgbuf); 4200 */ 4201 } 4202 4203 4204 4205 /*frm_prescan() takes an open file with the file pointer positioned at 4206 the beginning of the relevant formula, and parses the formula, token 4207 by token, for syntax errors. The function also accumulates data for 4208 memory allocation to be done later. 4209 4210 The function returns 1 if success, and 0 if errors are found. 4211 */ 4212 4213 int disable_fastparser; 4214 int must_use_float; 4215 4216 4217 int frm_prescan (FILE * open_file) 4218 { 4219 long filepos; 4220 int i; 4221 long statement_pos, orig_pos; 4222 int done = 0; 4223 struct token_st this_token; 4224 int errors_found = 0; 4225 int ExpectingArg = 1; 4226 int NewStatement = 1; 4227 int assignment_ok = 1; 4228 int already_got_colon = 0; 4229 unsigned long else_has_been_used = 0; 4230 unsigned long waiting_for_mod = 0; 4231 int waiting_for_endif = 0; 4232 int max_parens = sizeof(long) * 8; 4233 /* char debugmsg[800]; 4234 stopmsg (0, "Entering prescan"); 4235 */ 4236 4237 disable_fastparser = 0; 4238 must_use_float = 0; 4239 4240 number_of_ops = number_of_loads = number_of_stores = number_of_jumps = (unsigned) 0L; 4241 chars_in_formula = (unsigned) 0; 4242 uses_jump = (short) 0; 4243 paren = 0; 4244 4245 init_var_list(); 4246 init_const_lists(); 4247 4248 orig_pos = statement_pos = ftell(open_file); 4249 for (i = 0; i < 3; i++) { 4250 errors[i].start_pos = 0L; 4251 errors[i].error_pos = 0L; 4252 errors[i].error_number = 0; 4253 } 4254 4255 while (!done) { 4256 /* char msgbuf[80] = "Just got "; 4257 */ filepos = ftell (open_file); 4258 frmgettoken (open_file, &this_token); 4259 /* strcat(msgbuf, this_token.token_str); 4260 stopmsg (0, msgbuf); 4261 sprintf (debugmsg, "Errors structure\n0: %ld, %ld, %d\n1: %ld, %ld, %d\n2: %ld, %ld, %d\n\n", 4262 errors[0].start_pos, errors[0].error_pos, errors[0].error_number, 4263 errors[1].start_pos, errors[1].error_pos, errors[1].error_number, 4264 errors[2].start_pos, errors[2].error_pos, errors[2].error_number); 4265 stopmsg (0, debugmsg); 4266 */ 4267 chars_in_formula += strlen(this_token.token_str); 4268 switch (this_token.token_type) { 4269 case NOT_A_TOKEN: 4270 assignment_ok = 0; 4271 switch (this_token.token_id) { 4272 case END_OF_FILE: 4273 stopmsg(0,ParseErrs(PE_UNEXPECTED_EOF)); 4274 fseek(open_file, orig_pos, SEEK_SET); 4275 return 0; 4276 case ILLEGAL_CHARACTER: 4277 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4278 errors[errors_found].start_pos = statement_pos; 4279 errors[errors_found].error_pos = filepos; 4280 errors[errors_found++].error_number = PE_ILLEGAL_CHAR; 4281 } 4282 break; 4283 case ILLEGAL_VARIABLE_NAME: 4284 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4285 errors[errors_found].start_pos = statement_pos; 4286 errors[errors_found].error_pos = filepos; 4287 errors[errors_found++].error_number = PE_ILLEGAL_VAR_NAME; 4288 } 4289 break; 4290 case TOKEN_TOO_LONG: 4291 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4292 errors[errors_found].start_pos = statement_pos; 4293 errors[errors_found].error_pos = filepos; 4294 errors[errors_found++].error_number = PE_TOKEN_TOO_LONG; 4295 } 4296 break; 4297 case FUNC_USED_AS_VAR: 4298 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4299 errors[errors_found].start_pos = statement_pos; 4300 errors[errors_found].error_pos = filepos; 4301 errors[errors_found++].error_number = PE_FUNC_USED_AS_VAR; 4302 } 4303 break; 4304 case JUMP_MISSING_BOOLEAN: 4305 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4306 errors[errors_found].start_pos = statement_pos; 4307 errors[errors_found].error_pos = filepos; 4308 errors[errors_found++].error_number = PE_JUMP_NEEDS_BOOLEAN; 4309 } 4310 break; 4311 case JUMP_WITH_ILLEGAL_CHAR: 4312 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4313 errors[errors_found].start_pos = statement_pos; 4314 errors[errors_found].error_pos = filepos; 4315 errors[errors_found++].error_number = PE_NO_CHAR_AFTER_THIS_JUMP; 4316 } 4317 break; 4318 case UNDEFINED_FUNCTION: 4319 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4320 errors[errors_found].start_pos = statement_pos; 4321 errors[errors_found].error_pos = filepos; 4322 errors[errors_found++].error_number = PE_UNDEFINED_FUNCTION; 4323 } 4324 break; 4325 case ILLEGAL_OPERATOR: 4326 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4327 errors[errors_found].start_pos = statement_pos; 4328 errors[errors_found].error_pos = filepos; 4329 errors[errors_found++].error_number = PE_UNDEFINED_OPERATOR; 4330 } 4331 break; 4332 case ILL_FORMED_CONSTANT: 4333 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4334 errors[errors_found].start_pos = statement_pos; 4335 errors[errors_found].error_pos = filepos; 4336 errors[errors_found++].error_number = PE_INVALID_CONST; 4337 } 4338 break; 4339 default: 4340 stopmsg(0, "Unexpected arrival at default case in prescan()"); 4341 fseek(open_file, orig_pos, SEEK_SET); 4342 return 0; 4343 } 4344 break; 4345 case PARENS: 4346 assignment_ok = 0; 4347 NewStatement = 0; 4348 switch (this_token.token_id) { 4349 case OPEN_PARENS: 4350 if(++paren > max_parens) { 4351 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4352 errors[errors_found].start_pos = statement_pos; 4353 errors[errors_found].error_pos = filepos; 4354 errors[errors_found++].error_number = PE_NESTING_TO_DEEP; 4355 } 4356 } 4357 else if(!ExpectingArg) { 4358 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4359 errors[errors_found].start_pos = statement_pos; 4360 errors[errors_found].error_pos = filepos; 4361 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4362 } 4363 } 4364 waiting_for_mod = waiting_for_mod << 1; 4365 break; 4366 case CLOSE_PARENS: 4367 if(paren) { 4368 paren--; 4369 } 4370 else { 4371 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4372 errors[errors_found].start_pos = statement_pos; 4373 errors[errors_found].error_pos = filepos; 4374 errors[errors_found++].error_number = PE_NEED_A_MATCHING_OPEN_PARENS; 4375 } 4376 paren = 0; 4377 } 4378 if (waiting_for_mod & 1L) { 4379 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4380 errors[errors_found].start_pos = statement_pos; 4381 errors[errors_found].error_pos = filepos; 4382 errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; 4383 } 4384 } 4385 else { 4386 waiting_for_mod = waiting_for_mod >> 1; 4387 } 4388 if (ExpectingArg) { 4389 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4390 errors[errors_found].start_pos = statement_pos; 4391 errors[errors_found].error_pos = filepos; 4392 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4393 } 4394 } 4395 break; 4396 default: 4397 break; 4398 } 4399 break; 4400 case PARAM_VARIABLE: /*i.e. p1, p2, p3, p4 or p5*/ 4401 number_of_ops++; 4402 number_of_loads++; 4403 NewStatement = 0; 4404 if(!ExpectingArg) { 4405 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4406 errors[errors_found].start_pos = statement_pos; 4407 errors[errors_found].error_pos = filepos; 4408 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4409 } 4410 } 4411 switch (this_token.token_id) { 4412 case 1: 4413 break; 4414 case 2: 4415 break; 4416 case 8: 4417 break; 4418 case 17: 4419 break; 4420 case 18: 4421 break; 4422 default: 4423 break; 4424 } 4425 ExpectingArg = 0; 4426 break; 4427 case USER_NAMED_VARIABLE: /* i.e. c, iter, etc. */ 4428 number_of_ops++; 4429 number_of_loads++; 4430 NewStatement = 0; 4431 if(!ExpectingArg) { 4432 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4433 errors[errors_found].start_pos = statement_pos; 4434 errors[errors_found].error_pos = filepos; 4435 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4436 } 4437 } 4438 ExpectingArg = 0; 4439 /* if ((var_list = add_var_to_list (var_list, this_token)) == NULL) { 4440 stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); 4441 fseek(open_file, orig_pos, SEEK_SET); 4442 init_var_list(); 4443 init_const_lists(); 4444 return 0; 4445 } 4446 */ break; 4447 case PREDEFINED_VARIABLE: /* i.e. z, pixel, whitesq, etc. */ 4448 number_of_ops++; 4449 number_of_loads++; 4450 NewStatement = 0; 4451 if(!ExpectingArg) { 4452 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4453 errors[errors_found].start_pos = statement_pos; 4454 errors[errors_found].error_pos = filepos; 4455 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4456 } 4457 } 4458 switch (this_token.token_id) { 4459 case 0: /* pixel */ 4460 break; 4461 case 3: /* z */ 4462 break; 4463 case 4: /* LastSqr */ 4464 break; 4465 case 5: /* pi */ 4466 break; 4467 case 6: /* e */ 4468 break; 4469 case 7: /* rand */ 4470 break; 4471 case 9: /* whitesq */ 4472 break; 4473 case 10: /* scrnpix */ 4474 break; 4475 case 11: /* scrnmax */ 4476 break; 4477 case 12: /* maxit */ 4478 break; 4479 case 13: /* ismand */ 4480 break; 4481 default: 4482 break; 4483 } 4484 ExpectingArg = 0; 4485 break; 4486 case REAL_CONSTANT: /* i.e. 4, (4,0), etc.) */ 4487 assignment_ok = 0; 4488 number_of_ops++; 4489 number_of_loads++; 4490 NewStatement = 0; 4491 if(!ExpectingArg) { 4492 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4493 errors[errors_found].start_pos = statement_pos; 4494 errors[errors_found].error_pos = filepos; 4495 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4496 } 4497 } 4498 ExpectingArg = 0; 4499 /* if ((real_list = add_const_to_list (real_list, this_token)) == NULL) { 4500 stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); 4501 fseek(open_file, orig_pos, SEEK_SET); 4502 init_var_list(); 4503 init_const_lists(); 4504 return 0; 4505 } 4506 */ break; 4507 case COMPLEX_CONSTANT: /* i.e. (1,2) etc. */ 4508 assignment_ok = 0; 4509 number_of_ops++; 4510 number_of_loads++; 4511 NewStatement = 0; 4512 if(!ExpectingArg) { 4513 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4514 errors[errors_found].start_pos = statement_pos; 4515 errors[errors_found].error_pos = filepos; 4516 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4517 } 4518 } 4519 ExpectingArg = 0; 4520 /* if ((complx_list = add_const_to_list (complx_list, this_token)) == NULL) { 4521 stopmsg(0, ParseErrs(PE_INSUFFICIENT_MEM_FOR_TYPE_FORMULA)); 4522 fseek(open_file, orig_pos, SEEK_SET); 4523 init_var_list(); 4524 init_const_lists(); 4525 return 0; 4526 } 4527 */ break; 4528 case FUNCTION: 4529 assignment_ok = 0; 4530 NewStatement = 0; 4531 number_of_ops++; 4532 if(!ExpectingArg) { 4533 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4534 errors[errors_found].start_pos = statement_pos; 4535 errors[errors_found].error_pos = filepos; 4536 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4537 } 4538 } 4539 switch (this_token.token_id) { 4540 case 0: 4541 break; 4542 case 1: 4543 break; 4544 case 2: 4545 break; 4546 case 3: 4547 break; 4548 case 4: 4549 break; 4550 case 5: 4551 break; 4552 case 6: 4553 break; 4554 case 7: 4555 break; 4556 case 8: 4557 break; 4558 case 9: 4559 break; 4560 case 10: 4561 break; 4562 case 15: 4563 break; 4564 case 16: 4565 break; 4566 case 17: 4567 break; 4568 case 18: 4569 break; 4570 case 19: 4571 break; 4572 case 20: 4573 break; 4574 case 21: 4575 break; 4576 case 22: 4577 break; 4578 case 23: 4579 break; 4580 case 24: 4581 break; 4582 case 25: 4583 break; 4584 case 26: 4585 break; 4586 case 27: 4587 break; 4588 case 28: 4589 break; 4590 case 29: 4591 break; 4592 case 30: 4593 break; 4594 case 31: 4595 break; 4596 case 32: 4597 break; 4598 case 33: 4599 break; 4600 case 34: 4601 break; 4602 default: 4603 break; 4604 } 4605 break; 4606 case PARAM_FUNCTION: 4607 assignment_ok = 0; 4608 NewStatement = 0; 4609 number_of_ops++; 4610 if(!ExpectingArg) { 4611 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4612 errors[errors_found].start_pos = statement_pos; 4613 errors[errors_found].error_pos = filepos; 4614 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4615 } 4616 } 4617 switch (this_token.token_id) { 4618 case 11: 4619 break; 4620 case 12: 4621 break; 4622 case 13: 4623 break; 4624 case 14: 4625 break; 4626 default: 4627 break; 4628 } 4629 NewStatement = 0; 4630 break; 4631 case FLOW_CONTROL: 4632 assignment_ok = 0; 4633 number_of_ops++; 4634 number_of_jumps++; 4635 if(!NewStatement) { 4636 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4637 errors[errors_found].start_pos = statement_pos; 4638 errors[errors_found].error_pos = filepos; 4639 errors[errors_found++].error_number = PE_JUMP_NOT_FIRST; 4640 } 4641 } 4642 else { 4643 uses_jump = 1; 4644 switch (this_token.token_id) { 4645 case 1: /* if */ 4646 else_has_been_used = else_has_been_used << 1; 4647 waiting_for_endif++; 4648 break; 4649 case 2: /*ELSEIF*/ 4650 number_of_ops += 3; /*else + two clear statements*/ 4651 number_of_jumps++; /* this involves two jumps */ 4652 if (else_has_been_used % 2) { 4653 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4654 errors[errors_found].start_pos = statement_pos; 4655 errors[errors_found].error_pos = filepos; 4656 errors[errors_found++].error_number = PE_ENDIF_REQUIRED_AFTER_ELSE; 4657 } 4658 } 4659 else if (!waiting_for_endif) { 4660 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4661 errors[errors_found].start_pos = statement_pos; 4662 errors[errors_found].error_pos = filepos; 4663 errors[errors_found++].error_number = PE_MISPLACED_ELSE_OR_ELSEIF; 4664 } 4665 } 4666 break; 4667 case 3: /*ELSE*/ 4668 if (else_has_been_used % 2) { 4669 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4670 errors[errors_found].start_pos = statement_pos; 4671 errors[errors_found].error_pos = filepos; 4672 errors[errors_found++].error_number = PE_ENDIF_REQUIRED_AFTER_ELSE; 4673 } 4674 } 4675 else if (!waiting_for_endif) { 4676 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4677 errors[errors_found].start_pos = statement_pos; 4678 errors[errors_found].error_pos = filepos; 4679 errors[errors_found++].error_number = PE_MISPLACED_ELSE_OR_ELSEIF; 4680 } 4681 } 4682 else_has_been_used = else_has_been_used | 1; 4683 break; 4684 case 4: /*ENDIF*/ 4685 else_has_been_used = else_has_been_used >> 1; 4686 waiting_for_endif--; 4687 if(waiting_for_endif < 0) { 4688 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4689 errors[errors_found].start_pos = statement_pos; 4690 errors[errors_found].error_pos = filepos; 4691 errors[errors_found++].error_number = PE_ENDIF_WITH_NO_IF; 4692 } 4693 waiting_for_endif = 0; 4694 } 4695 break; 4696 default: 4697 break; 4698 } 4699 } 4700 break; 4701 case OPERATOR: 4702 number_of_ops++; /*This will be corrected below in certain cases*/ 4703 switch (this_token.token_id) { 4704 case 0: case 11: /* end of statement and : */ 4705 number_of_ops++; /* ParseStr inserts a dummy op*/ 4706 if (paren) { 4707 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4708 errors[errors_found].start_pos = statement_pos; 4709 errors[errors_found].error_pos = filepos; 4710 errors[errors_found++].error_number = PE_NEED_MORE_CLOSE_PARENS; 4711 } 4712 paren = 0; 4713 } 4714 if (waiting_for_mod) { 4715 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4716 errors[errors_found].start_pos = statement_pos; 4717 errors[errors_found].error_pos = filepos; 4718 errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; 4719 } 4720 waiting_for_mod = 0; 4721 } 4722 if (!ExpectingArg) { 4723 if (this_token.token_id == 11) 4724 number_of_ops += 2; 4725 else 4726 number_of_ops++; 4727 } 4728 else if (!NewStatement) { 4729 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4730 errors[errors_found].start_pos = statement_pos; 4731 errors[errors_found].error_pos = filepos; 4732 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4733 } 4734 } 4735 if (this_token.token_id == 11 && waiting_for_endif) { 4736 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4737 errors[errors_found].start_pos = statement_pos; 4738 errors[errors_found].error_pos = filepos; 4739 errors[errors_found++].error_number = PE_UNMATCHED_IF_IN_INIT_SECTION; 4740 } 4741 waiting_for_endif = 0; 4742 } 4743 if (this_token.token_id == 11 && already_got_colon) { 4744 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4745 errors[errors_found].start_pos = statement_pos; 4746 errors[errors_found].error_pos = filepos; 4747 errors[errors_found++].error_number = PE_SECOND_COLON; 4748 } 4749 } 4750 if (this_token.token_id == 11) 4751 already_got_colon = 1; 4752 NewStatement = ExpectingArg = assignment_ok = 1; 4753 statement_pos = ftell(open_file); 4754 break; 4755 case 1: /* != */ 4756 assignment_ok = 0; 4757 if(ExpectingArg) { 4758 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4759 errors[errors_found].start_pos = statement_pos; 4760 errors[errors_found].error_pos = filepos; 4761 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4762 } 4763 } 4764 ExpectingArg = 1; 4765 break; 4766 case 2: /* = */ 4767 number_of_ops--; /*this just converts a load to a store*/ 4768 number_of_loads--; 4769 number_of_stores++; 4770 if(!assignment_ok) { 4771 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4772 errors[errors_found].start_pos = statement_pos; 4773 errors[errors_found].error_pos = filepos; 4774 errors[errors_found++].error_number = PE_ILLEGAL_ASSIGNMENT; 4775 } 4776 } 4777 ExpectingArg = 1; 4778 break; 4779 case 3: /* == */ 4780 assignment_ok = 0; 4781 if(ExpectingArg) { 4782 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4783 errors[errors_found].start_pos = statement_pos; 4784 errors[errors_found].error_pos = filepos; 4785 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4786 } 4787 } 4788 ExpectingArg = 1; 4789 break; 4790 case 4: /* < */ 4791 assignment_ok = 0; 4792 if(ExpectingArg) { 4793 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4794 errors[errors_found].start_pos = statement_pos; 4795 errors[errors_found].error_pos = filepos; 4796 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4797 } 4798 } 4799 ExpectingArg = 1; 4800 break; 4801 case 5: /* <= */ 4802 assignment_ok = 0; 4803 if(ExpectingArg) { 4804 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4805 errors[errors_found].start_pos = statement_pos; 4806 errors[errors_found].error_pos = filepos; 4807 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4808 } 4809 } 4810 ExpectingArg = 1; 4811 break; 4812 case 6: /* > */ 4813 assignment_ok = 0; 4814 if(ExpectingArg) { 4815 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4816 errors[errors_found].start_pos = statement_pos; 4817 errors[errors_found].error_pos = filepos; 4818 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4819 } 4820 } 4821 ExpectingArg = 1; 4822 break; 4823 case 7: /* >= */ 4824 assignment_ok = 0; 4825 if(ExpectingArg) { 4826 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4827 errors[errors_found].start_pos = statement_pos; 4828 errors[errors_found].error_pos = filepos; 4829 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4830 } 4831 } 4832 ExpectingArg = 1; 4833 break; 4834 case 8: /* | */ /* (half of the modulus operator */ 4835 assignment_ok = 0; 4836 if(!waiting_for_mod & 1L) { 4837 number_of_ops--; 4838 } 4839 if(!(waiting_for_mod & 1L) && !ExpectingArg) { 4840 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4841 errors[errors_found].start_pos = statement_pos; 4842 errors[errors_found].error_pos = filepos; 4843 errors[errors_found++].error_number = PE_SHOULD_BE_OPERATOR; 4844 } 4845 } 4846 else if ((waiting_for_mod & 1L) && ExpectingArg) { 4847 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4848 errors[errors_found].start_pos = statement_pos; 4849 errors[errors_found].error_pos = filepos; 4850 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4851 } 4852 } 4853 waiting_for_mod = waiting_for_mod ^ 1L; /*switch right bit*/ 4854 break; 4855 case 9: /* || */ 4856 assignment_ok = 0; 4857 if(ExpectingArg) { 4858 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4859 errors[errors_found].start_pos = statement_pos; 4860 errors[errors_found].error_pos = filepos; 4861 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4862 } 4863 } 4864 ExpectingArg = 1; 4865 break; 4866 case 10: /* && */ 4867 assignment_ok = 0; 4868 if(ExpectingArg) { 4869 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4870 errors[errors_found].start_pos = statement_pos; 4871 errors[errors_found].error_pos = filepos; 4872 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4873 } 4874 } 4875 ExpectingArg = 1; 4876 break; 4877 case 12: /* + */ /* case 11 (":") is up with case 0 */ 4878 assignment_ok = 0; 4879 if(ExpectingArg) { 4880 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4881 errors[errors_found].start_pos = statement_pos; 4882 errors[errors_found].error_pos = filepos; 4883 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4884 } 4885 } 4886 ExpectingArg = 1; 4887 break; 4888 case 13: /* - */ 4889 assignment_ok = 0; 4890 ExpectingArg = 1; 4891 break; 4892 case 14: /* * */ 4893 assignment_ok = 0; 4894 if(ExpectingArg) { 4895 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4896 errors[errors_found].start_pos = statement_pos; 4897 errors[errors_found].error_pos = filepos; 4898 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4899 } 4900 } 4901 ExpectingArg = 1; 4902 break; 4903 case 15: /* / */ 4904 assignment_ok = 0; 4905 if(ExpectingArg) { 4906 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4907 errors[errors_found].start_pos = statement_pos; 4908 errors[errors_found].error_pos = filepos; 4909 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4910 } 4911 } 4912 ExpectingArg = 1; 4913 break; 4914 case 16: /* ^ */ 4915 assignment_ok = 0; 4916 if(ExpectingArg) { 4917 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4918 errors[errors_found].start_pos = statement_pos; 4919 errors[errors_found].error_pos = filepos; 4920 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4921 } 4922 } 4923 filepos = ftell(open_file); 4924 frmgettoken (open_file, &this_token); 4925 if (this_token.token_str[0] == '-') { 4926 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4927 errors[errors_found].start_pos = statement_pos; 4928 errors[errors_found].error_pos = filepos; 4929 errors[errors_found++].error_number = PE_NO_NEG_AFTER_EXPONENT; 4930 } 4931 } 4932 else 4933 fseek(open_file, filepos, SEEK_SET); 4934 ExpectingArg = 1; 4935 break; 4936 default: 4937 break; 4938 } 4939 break; 4940 case END_OF_FORMULA: 4941 number_of_ops+= 3; /* Just need one, but a couple of extra just for the heck of it */ 4942 if (paren) { 4943 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4944 errors[errors_found].start_pos = statement_pos; 4945 errors[errors_found].error_pos = filepos; 4946 errors[errors_found++].error_number = PE_NEED_MORE_CLOSE_PARENS; 4947 } 4948 paren = 0; 4949 } 4950 if (waiting_for_mod) { 4951 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4952 errors[errors_found].start_pos = statement_pos; 4953 errors[errors_found].error_pos = filepos; 4954 errors[errors_found++].error_number = PE_UNMATCHED_MODULUS; 4955 } 4956 waiting_for_mod = 0; 4957 } 4958 if (waiting_for_endif) { 4959 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4960 errors[errors_found].start_pos = statement_pos; 4961 errors[errors_found].error_pos = filepos; 4962 errors[errors_found++].error_number = PE_IF_WITH_NO_ENDIF; 4963 } 4964 waiting_for_endif = 0; 4965 } 4966 if (ExpectingArg && !NewStatement) { 4967 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4968 errors[errors_found].start_pos = statement_pos; 4969 errors[errors_found].error_pos = filepos; 4970 errors[errors_found++].error_number = PE_SHOULD_BE_ARGUMENT; 4971 } 4972 statement_pos = ftell(open_file); 4973 } 4974 4975 if (number_of_jumps >= MAX_JUMPS) { 4976 if(!errors_found || errors[errors_found-1].start_pos != statement_pos) { 4977 errors[errors_found].start_pos = statement_pos; 4978 errors[errors_found].error_pos = filepos; 4979 errors[errors_found++].error_number = PE_TOO_MANY_JUMPS; 4980 } 4981 } 4982 4983 4984 4985 done = 1; 4986 break; 4987 default: 4988 break; 4989 } 4990 if (errors_found == 3) 4991 done = 1; 4992 } 4993 if(errors[0].start_pos) { 4994 /* sprintf (debugmsg, "Errors structure on entering frm_error\n 0: %ld, %ld, %d\n1: %ld, %ld, %d\n2: %ld, %ld, %d\n\n", 4995 errors[0].start_pos, errors[0].error_pos, errors[0].error_number, 4996 errors[1].start_pos, errors[1].error_pos, errors[1].error_number, 4997 errors[2].start_pos, errors[2].error_pos, errors[2].error_number); 4998 stopmsg (0, debugmsg); 4999 */ frm_error(open_file, orig_pos); 5000 fseek(open_file, orig_pos, SEEK_SET); 5001 return 0; 5002 } 5003 fseek(open_file, orig_pos, SEEK_SET); 5004 5005 /* display_var_list(); 5006 display_const_lists(); 5007 */ count_lists(); 5008 5009 /* sprintf(debugmsg, "Chars in formula per prescan() is %u.\n", chars_in_formula); 5010 stopmsg(0, debugmsg); 5011 */ return 1; 5012 } 5013 5014