Annotation of OpenXM_contrib/gnuplot/internal.c, Revision 1.1
1.1 ! maekawa 1: #ifndef lint
! 2: static char *RCSid = "$Id: internal.c,v 1.23 1998/04/14 00:15:44 drd Exp $";
! 3: #endif
! 4:
! 5: /* GNUPLOT - internal.c */
! 6:
! 7: /*[
! 8: * Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
! 9: *
! 10: * Permission to use, copy, and distribute this software and its
! 11: * documentation for any purpose with or without fee is hereby granted,
! 12: * provided that the above copyright notice appear in all copies and
! 13: * that both that copyright notice and this permission notice appear
! 14: * in supporting documentation.
! 15: *
! 16: * Permission to modify the software is granted, but not the right to
! 17: * distribute the complete modified source code. Modifications are to
! 18: * be distributed as patches to the released version. Permission to
! 19: * distribute binaries produced by compiling modified sources is granted,
! 20: * provided you
! 21: * 1. distribute the corresponding source modifications from the
! 22: * released version in the form of a patch file along with the binaries,
! 23: * 2. add special version identification to distinguish your version
! 24: * in addition to the base release version number,
! 25: * 3. provide your name and address as the primary contact for the
! 26: * support of your modified version, and
! 27: * 4. retain our contact information in regard to use of the base
! 28: * software.
! 29: * Permission to distribute the released version of the source code along
! 30: * with corresponding source modifications in the form of a patch file is
! 31: * granted with same provisions 2 through 4 for binary distributions.
! 32: *
! 33: * This software is provided "as is" without express or implied warranty
! 34: * to the extent permitted by applicable law.
! 35: ]*/
! 36:
! 37:
! 38: #include "plot.h"
! 39: #include "fnproto.h"
! 40:
! 41: /* some machines have trouble with exp(-x) for large x
! 42: * if MINEXP is defined at compile time, use gp_exp(x) instead,
! 43: * which returns 0 for exp(x) with x < MINEXP
! 44: * exp(x) will already have been defined as gp_exp(x) in plot.h
! 45: */
! 46:
! 47: #ifdef MINEXP
! 48: double gp_exp(x)
! 49: double x;
! 50: {
! 51: return (x < (MINEXP)) ? 0.0 : exp(x);
! 52: }
! 53: #endif
! 54:
! 55: TBOOLEAN undefined;
! 56:
! 57: static void int_check __PROTO((struct value * v));
! 58:
! 59: struct value stack[STACK_DEPTH];
! 60:
! 61: int s_p = -1; /* stack pointer */
! 62:
! 63:
! 64: /*
! 65: * System V and MSC 4.0 call this when they wants to print an error message.
! 66: * Don't!
! 67: */
! 68: #ifndef _CRAY
! 69: # ifdef AMIGA_SC_6_1
! 70: # define matherr __matherr
! 71: # define exception __exception
! 72: # endif /* AMIGA_SC_6_1 */
! 73: # if defined(__BORLANDC__) && __BORLANDC__ >= 0x450
! 74: # define matherr _matherr
! 75: # endif /* __BORLANDC__ >= 0x450 */
! 76: # if (defined(MSDOS) || defined(DOS386)) && defined(__TURBOC__) || defined(VMS)
! 77: int matherr()
! 78: #else
! 79: int matherr(x)
! 80: struct exception *x;
! 81: # endif /* (MSDOS || DOS386) && __TURBOC__ */
! 82: {
! 83: return (undefined = TRUE); /* don't print error message */
! 84: }
! 85: #endif /* not _CRAY */
! 86:
! 87:
! 88: void reset_stack()
! 89: {
! 90: s_p = -1;
! 91: }
! 92:
! 93:
! 94: void check_stack()
! 95: { /* make sure stack's empty */
! 96: if (s_p != -1)
! 97: fprintf(stderr, "\n\
! 98: warning: internal error--stack not empty!\n\
! 99: (function called with too many parameters?)\n");
! 100: }
! 101:
! 102: #define BAD_DEFAULT default: int_error("interal error : type neither INT or CMPLX", NO_CARET); return;
! 103:
! 104: struct value *pop(x)
! 105: struct value *x;
! 106: {
! 107: if (s_p < 0)
! 108: int_error("stack underflow (function call with missing parameters?)", NO_CARET);
! 109: *x = stack[s_p--];
! 110: return (x);
! 111: }
! 112:
! 113:
! 114: void push(x)
! 115: struct value *x;
! 116: {
! 117: if (s_p == STACK_DEPTH - 1)
! 118: int_error("stack overflow", NO_CARET);
! 119: stack[++s_p] = *x;
! 120: }
! 121:
! 122:
! 123: #define ERR_VAR "undefined variable: "
! 124:
! 125: void f_push(x)
! 126: union argument *x; /* contains pointer to value to push; */
! 127: {
! 128: static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
! 129: struct udvt_entry *udv;
! 130:
! 131: udv = x->udv_arg;
! 132: if (udv->udv_undef) { /* undefined */
! 133: (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
! 134: int_error(err_str, NO_CARET);
! 135: }
! 136: push(&(udv->udv_value));
! 137: }
! 138:
! 139:
! 140: void f_pushc(x)
! 141: union argument *x;
! 142: {
! 143: push(&(x->v_arg));
! 144: }
! 145:
! 146:
! 147: void f_pushd1(x)
! 148: union argument *x;
! 149: {
! 150: push(&(x->udf_arg->dummy_values[0]));
! 151: }
! 152:
! 153:
! 154: void f_pushd2(x)
! 155: union argument *x;
! 156: {
! 157: push(&(x->udf_arg->dummy_values[1]));
! 158: }
! 159:
! 160:
! 161: void f_pushd(x)
! 162: union argument *x;
! 163: {
! 164: struct value param;
! 165: (void) pop(¶m);
! 166: push(&(x->udf_arg->dummy_values[param.v.int_val]));
! 167: }
! 168:
! 169:
! 170: #define ERR_FUN "undefined function: "
! 171:
! 172: void f_call(x) /* execute a udf */
! 173: union argument *x;
! 174: {
! 175: static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
! 176: register struct udft_entry *udf;
! 177: struct value save_dummy;
! 178:
! 179: udf = x->udf_arg;
! 180: if (!udf->at) { /* undefined */
! 181: (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
! 182: udf->udf_name);
! 183: int_error(err_str, NO_CARET);
! 184: }
! 185: save_dummy = udf->dummy_values[0];
! 186: (void) pop(&(udf->dummy_values[0]));
! 187:
! 188: execute_at(udf->at);
! 189: udf->dummy_values[0] = save_dummy;
! 190: }
! 191:
! 192:
! 193: void f_calln(x) /* execute a udf of n variables */
! 194: union argument *x;
! 195: {
! 196: static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
! 197: register struct udft_entry *udf;
! 198: struct value save_dummy[MAX_NUM_VAR];
! 199:
! 200: int i;
! 201: int num_pop;
! 202: struct value num_params;
! 203:
! 204: udf = x->udf_arg;
! 205: if (!udf->at) { /* undefined */
! 206: (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
! 207: udf->udf_name);
! 208: int_error(err_str, NO_CARET);
! 209: }
! 210: for (i = 0; i < MAX_NUM_VAR; i++)
! 211: save_dummy[i] = udf->dummy_values[i];
! 212:
! 213: /* if there are more parameters than the function is expecting */
! 214: /* simply ignore the excess */
! 215: (void) pop(&num_params);
! 216:
! 217: if (num_params.v.int_val > MAX_NUM_VAR) {
! 218: /* pop the dummies that there is no room for */
! 219: num_pop = num_params.v.int_val - MAX_NUM_VAR;
! 220: for (i = 0; i < num_pop; i++)
! 221: (void) pop(&(udf->dummy_values[i]));
! 222:
! 223: num_pop = MAX_NUM_VAR;
! 224: } else {
! 225: num_pop = num_params.v.int_val;
! 226: }
! 227:
! 228: /* pop parameters we can use */
! 229: for (i = num_pop - 1; i >= 0; i--)
! 230: (void) pop(&(udf->dummy_values[i]));
! 231:
! 232: execute_at(udf->at);
! 233: for (i = 0; i < MAX_NUM_VAR; i++)
! 234: udf->dummy_values[i] = save_dummy[i];
! 235: }
! 236:
! 237:
! 238: static void int_check(v)
! 239: struct value *v;
! 240: {
! 241: if (v->type != INTGR)
! 242: int_error("non-integer passed to boolean operator", NO_CARET);
! 243: }
! 244:
! 245:
! 246: void f_lnot()
! 247: {
! 248: struct value a;
! 249: int_check(pop(&a));
! 250: push(Ginteger(&a, !a.v.int_val));
! 251: }
! 252:
! 253:
! 254: void f_bnot()
! 255: {
! 256: struct value a;
! 257: int_check(pop(&a));
! 258: push(Ginteger(&a, ~a.v.int_val));
! 259: }
! 260:
! 261:
! 262: void f_bool()
! 263: { /* converts top-of-stack to boolean */
! 264: int_check(&top_of_stack);
! 265: top_of_stack.v.int_val = !!top_of_stack.v.int_val;
! 266: }
! 267:
! 268:
! 269: void f_lor()
! 270: {
! 271: struct value a, b;
! 272: int_check(pop(&b));
! 273: int_check(pop(&a));
! 274: push(Ginteger(&a, a.v.int_val || b.v.int_val));
! 275: }
! 276:
! 277: void f_land()
! 278: {
! 279: struct value a, b;
! 280: int_check(pop(&b));
! 281: int_check(pop(&a));
! 282: push(Ginteger(&a, a.v.int_val && b.v.int_val));
! 283: }
! 284:
! 285:
! 286: void f_bor()
! 287: {
! 288: struct value a, b;
! 289: int_check(pop(&b));
! 290: int_check(pop(&a));
! 291: push(Ginteger(&a, a.v.int_val | b.v.int_val));
! 292: }
! 293:
! 294:
! 295: void f_xor()
! 296: {
! 297: struct value a, b;
! 298: int_check(pop(&b));
! 299: int_check(pop(&a));
! 300: push(Ginteger(&a, a.v.int_val ^ b.v.int_val));
! 301: }
! 302:
! 303:
! 304: void f_band()
! 305: {
! 306: struct value a, b;
! 307: int_check(pop(&b));
! 308: int_check(pop(&a));
! 309: push(Ginteger(&a, a.v.int_val & b.v.int_val));
! 310: }
! 311:
! 312:
! 313: void f_uminus()
! 314: {
! 315: struct value a;
! 316: (void) pop(&a);
! 317: switch (a.type) {
! 318: case INTGR:
! 319: a.v.int_val = -a.v.int_val;
! 320: break;
! 321: case CMPLX:
! 322: a.v.cmplx_val.real =
! 323: -a.v.cmplx_val.real;
! 324: a.v.cmplx_val.imag =
! 325: -a.v.cmplx_val.imag;
! 326: break;
! 327: BAD_DEFAULT
! 328: }
! 329: push(&a);
! 330: }
! 331:
! 332:
! 333: void f_eq()
! 334: {
! 335: /* note: floating point equality is rare because of roundoff error! */
! 336: struct value a, b;
! 337: register int result = 0;
! 338: (void) pop(&b);
! 339: (void) pop(&a);
! 340: switch (a.type) {
! 341: case INTGR:
! 342: switch (b.type) {
! 343: case INTGR:
! 344: result = (a.v.int_val ==
! 345: b.v.int_val);
! 346: break;
! 347: case CMPLX:
! 348: result = (a.v.int_val ==
! 349: b.v.cmplx_val.real &&
! 350: b.v.cmplx_val.imag == 0.0);
! 351: break;
! 352: BAD_DEFAULT
! 353: }
! 354: break;
! 355: case CMPLX:
! 356: switch (b.type) {
! 357: case INTGR:
! 358: result = (b.v.int_val == a.v.cmplx_val.real &&
! 359: a.v.cmplx_val.imag == 0.0);
! 360: break;
! 361: case CMPLX:
! 362: result = (a.v.cmplx_val.real ==
! 363: b.v.cmplx_val.real &&
! 364: a.v.cmplx_val.imag ==
! 365: b.v.cmplx_val.imag);
! 366: break;
! 367: BAD_DEFAULT
! 368: }
! 369: break;
! 370: BAD_DEFAULT
! 371: }
! 372: push(Ginteger(&a, result));
! 373: }
! 374:
! 375:
! 376: void f_ne()
! 377: {
! 378: struct value a, b;
! 379: register int result = 0;
! 380: (void) pop(&b);
! 381: (void) pop(&a);
! 382: switch (a.type) {
! 383: case INTGR:
! 384: switch (b.type) {
! 385: case INTGR:
! 386: result = (a.v.int_val !=
! 387: b.v.int_val);
! 388: break;
! 389: case CMPLX:
! 390: result = (a.v.int_val !=
! 391: b.v.cmplx_val.real ||
! 392: b.v.cmplx_val.imag != 0.0);
! 393: break;
! 394: BAD_DEFAULT
! 395: }
! 396: break;
! 397: case CMPLX:
! 398: switch (b.type) {
! 399: case INTGR:
! 400: result = (b.v.int_val !=
! 401: a.v.cmplx_val.real ||
! 402: a.v.cmplx_val.imag != 0.0);
! 403: break;
! 404: case CMPLX:
! 405: result = (a.v.cmplx_val.real !=
! 406: b.v.cmplx_val.real ||
! 407: a.v.cmplx_val.imag !=
! 408: b.v.cmplx_val.imag);
! 409: break;
! 410: BAD_DEFAULT
! 411: }
! 412: break;
! 413: BAD_DEFAULT
! 414: }
! 415: push(Ginteger(&a, result));
! 416: }
! 417:
! 418:
! 419: void f_gt()
! 420: {
! 421: struct value a, b;
! 422: register int result = 0;
! 423: (void) pop(&b);
! 424: (void) pop(&a);
! 425: switch (a.type) {
! 426: case INTGR:
! 427: switch (b.type) {
! 428: case INTGR:
! 429: result = (a.v.int_val >
! 430: b.v.int_val);
! 431: break;
! 432: case CMPLX:
! 433: result = (a.v.int_val >
! 434: b.v.cmplx_val.real);
! 435: break;
! 436: BAD_DEFAULT
! 437: }
! 438: break;
! 439: case CMPLX:
! 440: switch (b.type) {
! 441: case INTGR:
! 442: result = (a.v.cmplx_val.real >
! 443: b.v.int_val);
! 444: break;
! 445: case CMPLX:
! 446: result = (a.v.cmplx_val.real >
! 447: b.v.cmplx_val.real);
! 448: break;
! 449: BAD_DEFAULT
! 450: }
! 451: break;
! 452: BAD_DEFAULT
! 453: }
! 454: push(Ginteger(&a, result));
! 455: }
! 456:
! 457:
! 458: void f_lt()
! 459: {
! 460: struct value a, b;
! 461: register int result = 0;
! 462: (void) pop(&b);
! 463: (void) pop(&a);
! 464: switch (a.type) {
! 465: case INTGR:
! 466: switch (b.type) {
! 467: case INTGR:
! 468: result = (a.v.int_val <
! 469: b.v.int_val);
! 470: break;
! 471: case CMPLX:
! 472: result = (a.v.int_val <
! 473: b.v.cmplx_val.real);
! 474: break;
! 475: BAD_DEFAULT
! 476: }
! 477: break;
! 478: case CMPLX:
! 479: switch (b.type) {
! 480: case INTGR:
! 481: result = (a.v.cmplx_val.real <
! 482: b.v.int_val);
! 483: break;
! 484: case CMPLX:
! 485: result = (a.v.cmplx_val.real <
! 486: b.v.cmplx_val.real);
! 487: break;
! 488: BAD_DEFAULT
! 489: }
! 490: break;
! 491: BAD_DEFAULT
! 492: }
! 493: push(Ginteger(&a, result));
! 494: }
! 495:
! 496:
! 497: void f_ge()
! 498: {
! 499: struct value a, b;
! 500: register int result = 0;
! 501: (void) pop(&b);
! 502: (void) pop(&a);
! 503: switch (a.type) {
! 504: case INTGR:
! 505: switch (b.type) {
! 506: case INTGR:
! 507: result = (a.v.int_val >=
! 508: b.v.int_val);
! 509: break;
! 510: case CMPLX:
! 511: result = (a.v.int_val >=
! 512: b.v.cmplx_val.real);
! 513: break;
! 514: BAD_DEFAULT
! 515: }
! 516: break;
! 517: case CMPLX:
! 518: switch (b.type) {
! 519: case INTGR:
! 520: result = (a.v.cmplx_val.real >=
! 521: b.v.int_val);
! 522: break;
! 523: case CMPLX:
! 524: result = (a.v.cmplx_val.real >=
! 525: b.v.cmplx_val.real);
! 526: break;
! 527: BAD_DEFAULT
! 528: }
! 529: break;
! 530: BAD_DEFAULT
! 531: }
! 532: push(Ginteger(&a, result));
! 533: }
! 534:
! 535:
! 536: void f_le()
! 537: {
! 538: struct value a, b;
! 539: register int result = 0;
! 540: (void) pop(&b);
! 541: (void) pop(&a);
! 542: switch (a.type) {
! 543: case INTGR:
! 544: switch (b.type) {
! 545: case INTGR:
! 546: result = (a.v.int_val <=
! 547: b.v.int_val);
! 548: break;
! 549: case CMPLX:
! 550: result = (a.v.int_val <=
! 551: b.v.cmplx_val.real);
! 552: break;
! 553: BAD_DEFAULT
! 554: }
! 555: break;
! 556: case CMPLX:
! 557: switch (b.type) {
! 558: case INTGR:
! 559: result = (a.v.cmplx_val.real <=
! 560: b.v.int_val);
! 561: break;
! 562: case CMPLX:
! 563: result = (a.v.cmplx_val.real <=
! 564: b.v.cmplx_val.real);
! 565: break;
! 566: BAD_DEFAULT
! 567: }
! 568: break;
! 569: BAD_DEFAULT
! 570: }
! 571: push(Ginteger(&a, result));
! 572: }
! 573:
! 574:
! 575: void f_plus()
! 576: {
! 577: struct value a, b, result;
! 578: (void) pop(&b);
! 579: (void) pop(&a);
! 580: switch (a.type) {
! 581: case INTGR:
! 582: switch (b.type) {
! 583: case INTGR:
! 584: (void) Ginteger(&result, a.v.int_val +
! 585: b.v.int_val);
! 586: break;
! 587: case CMPLX:
! 588: (void) Gcomplex(&result, a.v.int_val +
! 589: b.v.cmplx_val.real,
! 590: b.v.cmplx_val.imag);
! 591: break;
! 592: BAD_DEFAULT
! 593: }
! 594: break;
! 595: case CMPLX:
! 596: switch (b.type) {
! 597: case INTGR:
! 598: (void) Gcomplex(&result, b.v.int_val +
! 599: a.v.cmplx_val.real,
! 600: a.v.cmplx_val.imag);
! 601: break;
! 602: case CMPLX:
! 603: (void) Gcomplex(&result, a.v.cmplx_val.real +
! 604: b.v.cmplx_val.real,
! 605: a.v.cmplx_val.imag +
! 606: b.v.cmplx_val.imag);
! 607: break;
! 608: BAD_DEFAULT
! 609: }
! 610: break;
! 611: BAD_DEFAULT
! 612: }
! 613: push(&result);
! 614: }
! 615:
! 616:
! 617: void f_minus()
! 618: {
! 619: struct value a, b, result;
! 620: (void) pop(&b);
! 621: (void) pop(&a); /* now do a - b */
! 622: switch (a.type) {
! 623: case INTGR:
! 624: switch (b.type) {
! 625: case INTGR:
! 626: (void) Ginteger(&result, a.v.int_val -
! 627: b.v.int_val);
! 628: break;
! 629: case CMPLX:
! 630: (void) Gcomplex(&result, a.v.int_val -
! 631: b.v.cmplx_val.real,
! 632: -b.v.cmplx_val.imag);
! 633: break;
! 634: BAD_DEFAULT
! 635: }
! 636: break;
! 637: case CMPLX:
! 638: switch (b.type) {
! 639: case INTGR:
! 640: (void) Gcomplex(&result, a.v.cmplx_val.real -
! 641: b.v.int_val,
! 642: a.v.cmplx_val.imag);
! 643: break;
! 644: case CMPLX:
! 645: (void) Gcomplex(&result, a.v.cmplx_val.real -
! 646: b.v.cmplx_val.real,
! 647: a.v.cmplx_val.imag -
! 648: b.v.cmplx_val.imag);
! 649: break;
! 650: BAD_DEFAULT
! 651: }
! 652: break;
! 653: BAD_DEFAULT
! 654: }
! 655: push(&result);
! 656: }
! 657:
! 658:
! 659: void f_mult()
! 660: {
! 661: struct value a, b, result;
! 662: (void) pop(&b);
! 663: (void) pop(&a); /* now do a*b */
! 664:
! 665: switch (a.type) {
! 666: case INTGR:
! 667: switch (b.type) {
! 668: case INTGR:
! 669: (void) Ginteger(&result, a.v.int_val *
! 670: b.v.int_val);
! 671: break;
! 672: case CMPLX:
! 673: (void) Gcomplex(&result, a.v.int_val *
! 674: b.v.cmplx_val.real,
! 675: a.v.int_val *
! 676: b.v.cmplx_val.imag);
! 677: break;
! 678: BAD_DEFAULT
! 679: }
! 680: break;
! 681: case CMPLX:
! 682: switch (b.type) {
! 683: case INTGR:
! 684: (void) Gcomplex(&result, b.v.int_val *
! 685: a.v.cmplx_val.real,
! 686: b.v.int_val *
! 687: a.v.cmplx_val.imag);
! 688: break;
! 689: case CMPLX:
! 690: (void) Gcomplex(&result, a.v.cmplx_val.real *
! 691: b.v.cmplx_val.real -
! 692: a.v.cmplx_val.imag *
! 693: b.v.cmplx_val.imag,
! 694: a.v.cmplx_val.real *
! 695: b.v.cmplx_val.imag +
! 696: a.v.cmplx_val.imag *
! 697: b.v.cmplx_val.real);
! 698: break;
! 699: BAD_DEFAULT
! 700: }
! 701: break;
! 702: BAD_DEFAULT
! 703: }
! 704: push(&result);
! 705: }
! 706:
! 707:
! 708: void f_div()
! 709: {
! 710: struct value a, b, result;
! 711: register double square;
! 712: (void) pop(&b);
! 713: (void) pop(&a); /* now do a/b */
! 714:
! 715: switch (a.type) {
! 716: case INTGR:
! 717: switch (b.type) {
! 718: case INTGR:
! 719: if (b.v.int_val)
! 720: (void) Ginteger(&result, a.v.int_val /
! 721: b.v.int_val);
! 722: else {
! 723: (void) Ginteger(&result, 0);
! 724: undefined = TRUE;
! 725: }
! 726: break;
! 727: case CMPLX:
! 728: square = b.v.cmplx_val.real *
! 729: b.v.cmplx_val.real +
! 730: b.v.cmplx_val.imag *
! 731: b.v.cmplx_val.imag;
! 732: if (square)
! 733: (void) Gcomplex(&result, a.v.int_val *
! 734: b.v.cmplx_val.real / square,
! 735: -a.v.int_val *
! 736: b.v.cmplx_val.imag / square);
! 737: else {
! 738: (void) Gcomplex(&result, 0.0, 0.0);
! 739: undefined = TRUE;
! 740: }
! 741: break;
! 742: BAD_DEFAULT
! 743: }
! 744: break;
! 745: case CMPLX:
! 746: switch (b.type) {
! 747: case INTGR:
! 748: if (b.v.int_val)
! 749: (void) Gcomplex(&result, a.v.cmplx_val.real /
! 750: b.v.int_val,
! 751: a.v.cmplx_val.imag /
! 752: b.v.int_val);
! 753: else {
! 754: (void) Gcomplex(&result, 0.0, 0.0);
! 755: undefined = TRUE;
! 756: }
! 757: break;
! 758: case CMPLX:
! 759: square = b.v.cmplx_val.real *
! 760: b.v.cmplx_val.real +
! 761: b.v.cmplx_val.imag *
! 762: b.v.cmplx_val.imag;
! 763: if (square)
! 764: (void) Gcomplex(&result, (a.v.cmplx_val.real *
! 765: b.v.cmplx_val.real +
! 766: a.v.cmplx_val.imag *
! 767: b.v.cmplx_val.imag) / square,
! 768: (a.v.cmplx_val.imag *
! 769: b.v.cmplx_val.real -
! 770: a.v.cmplx_val.real *
! 771: b.v.cmplx_val.imag) /
! 772: square);
! 773: else {
! 774: (void) Gcomplex(&result, 0.0, 0.0);
! 775: undefined = TRUE;
! 776: }
! 777: break;
! 778: BAD_DEFAULT
! 779: }
! 780: break;
! 781: BAD_DEFAULT
! 782: }
! 783: push(&result);
! 784: }
! 785:
! 786:
! 787: void f_mod()
! 788: {
! 789: struct value a, b;
! 790: (void) pop(&b);
! 791: (void) pop(&a); /* now do a%b */
! 792:
! 793: if (a.type != INTGR || b.type != INTGR)
! 794: int_error("can only mod ints", NO_CARET);
! 795: if (b.v.int_val)
! 796: push(Ginteger(&a, a.v.int_val % b.v.int_val));
! 797: else {
! 798: push(Ginteger(&a, 0));
! 799: undefined = TRUE;
! 800: }
! 801: }
! 802:
! 803:
! 804: void f_power()
! 805: {
! 806: struct value a, b, result;
! 807: register int i, t, count;
! 808: register double mag, ang;
! 809: (void) pop(&b);
! 810: (void) pop(&a); /* now find a**b */
! 811:
! 812: switch (a.type) {
! 813: case INTGR:
! 814: switch (b.type) {
! 815: case INTGR:
! 816: count = abs(b.v.int_val);
! 817: t = 1;
! 818: /* this ought to use bit-masks and squares, etc */
! 819: for (i = 0; i < count; i++)
! 820: t *= a.v.int_val;
! 821: if (b.v.int_val >= 0)
! 822: (void) Ginteger(&result, t);
! 823: else if (t != 0)
! 824: (void) Gcomplex(&result, 1.0 / t, 0.0);
! 825: else {
! 826: undefined = TRUE;
! 827: (void) Gcomplex(&result, 0.0, 0.0);
! 828: }
! 829: break;
! 830: case CMPLX:
! 831: if (a.v.int_val == 0) {
! 832: if (b.v.cmplx_val.imag != 0 || b.v.cmplx_val.real < 0) {
! 833: undefined = TRUE;
! 834: }
! 835: /* return 1.0 for 0**0 */
! 836: Gcomplex(&result, b.v.cmplx_val.real == 0 ? 1.0 : 0.0, 0.0);
! 837: } else {
! 838: mag =
! 839: pow(magnitude(&a), fabs(b.v.cmplx_val.real));
! 840: if (b.v.cmplx_val.real < 0.0) {
! 841: if (mag != 0.0)
! 842: mag = 1.0 / mag;
! 843: else
! 844: undefined = TRUE;
! 845: }
! 846: mag *= gp_exp(-b.v.cmplx_val.imag * angle(&a));
! 847: ang = b.v.cmplx_val.real * angle(&a) +
! 848: b.v.cmplx_val.imag * log(magnitude(&a));
! 849: (void) Gcomplex(&result, mag * cos(ang),
! 850: mag * sin(ang));
! 851: }
! 852: break;
! 853: BAD_DEFAULT
! 854: }
! 855: break;
! 856: case CMPLX:
! 857: switch (b.type) {
! 858: case INTGR:
! 859: if (a.v.cmplx_val.imag == 0.0) {
! 860: mag = pow(a.v.cmplx_val.real, (double) abs(b.v.int_val));
! 861: if (b.v.int_val < 0) {
! 862: if (mag != 0.0)
! 863: mag = 1.0 / mag;
! 864: else
! 865: undefined = TRUE;
! 866: }
! 867: (void) Gcomplex(&result, mag, 0.0);
! 868: } else {
! 869: /* not so good, but...! */
! 870: mag = pow(magnitude(&a), (double) abs(b.v.int_val));
! 871: if (b.v.int_val < 0) {
! 872: if (mag != 0.0)
! 873: mag = 1.0 / mag;
! 874: else
! 875: undefined = TRUE;
! 876: }
! 877: ang = angle(&a) * b.v.int_val;
! 878: (void) Gcomplex(&result, mag * cos(ang),
! 879: mag * sin(ang));
! 880: }
! 881: break;
! 882: case CMPLX:
! 883: if (a.v.cmplx_val.real == 0 && a.v.cmplx_val.imag == 0) {
! 884: if (b.v.cmplx_val.imag != 0 || b.v.cmplx_val.real < 0) {
! 885: undefined = TRUE;
! 886: }
! 887: /* return 1.0 for 0**0 */
! 888: Gcomplex(&result, b.v.cmplx_val.real == 0 ? 1.0 : 0.0, 0.0);
! 889: } else {
! 890: mag = pow(magnitude(&a), fabs(b.v.cmplx_val.real));
! 891: if (b.v.cmplx_val.real < 0.0) {
! 892: if (mag != 0.0)
! 893: mag = 1.0 / mag;
! 894: else
! 895: undefined = TRUE;
! 896: }
! 897: mag *= gp_exp(-b.v.cmplx_val.imag * angle(&a));
! 898: ang = b.v.cmplx_val.real * angle(&a) +
! 899: b.v.cmplx_val.imag * log(magnitude(&a));
! 900: (void) Gcomplex(&result, mag * cos(ang),
! 901: mag * sin(ang));
! 902: }
! 903: break;
! 904: BAD_DEFAULT
! 905: }
! 906: break;
! 907: BAD_DEFAULT
! 908: }
! 909: push(&result);
! 910: }
! 911:
! 912:
! 913: void f_factorial()
! 914: {
! 915: struct value a;
! 916: register int i;
! 917: register double val = 0.0;
! 918:
! 919: (void) pop(&a); /* find a! (factorial) */
! 920:
! 921: switch (a.type) {
! 922: case INTGR:
! 923: val = 1.0;
! 924: for (i = a.v.int_val; i > 1; i--) /*fpe's should catch overflows */
! 925: val *= i;
! 926: break;
! 927: default:
! 928: int_error("factorial (!) argument must be an integer", NO_CARET);
! 929: return; /* avoid gcc -Wall warning about val */
! 930: }
! 931:
! 932: push(Gcomplex(&a, val, 0.0));
! 933:
! 934: }
! 935:
! 936:
! 937: int f_jump(x)
! 938: union argument *x;
! 939: {
! 940: return (x->j_arg);
! 941: }
! 942:
! 943:
! 944: int f_jumpz(x)
! 945: union argument *x;
! 946: {
! 947: struct value a;
! 948: int_check(&top_of_stack);
! 949: if (top_of_stack.v.int_val) { /* non-zero */
! 950: (void) pop(&a);
! 951: return 1; /* no jump */
! 952: } else
! 953: return (x->j_arg); /* leave the argument on TOS */
! 954: }
! 955:
! 956:
! 957: int f_jumpnz(x)
! 958: union argument *x;
! 959: {
! 960: struct value a;
! 961: int_check(&top_of_stack);
! 962: if (top_of_stack.v.int_val) /* non-zero */
! 963: return (x->j_arg); /* leave the argument on TOS */
! 964: else {
! 965: (void) pop(&a);
! 966: return 1; /* no jump */
! 967: }
! 968: }
! 969:
! 970:
! 971: int f_jtern(x)
! 972: union argument *x;
! 973: {
! 974: struct value a;
! 975:
! 976: int_check(pop(&a));
! 977: if (a.v.int_val)
! 978: return (1); /* no jump; fall through to TRUE code */
! 979: else
! 980: return (x->j_arg); /* go jump to FALSE code */
! 981: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>