[BACK]Return to internal.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/internal.c, Revision 1.1.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(&param);
                    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>