home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume8 / gnuplot1.10A / part02 / internal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-09  |  13.3 KB  |  767 lines

  1. /*
  2.  *
  3.  *    G N U P L O T  --  internal.c
  4.  *
  5.  *  Copyright (C) 1986, 1987  Colin Kelley, Thomas Williams
  6.  *
  7.  *  You may use this code as you wish if credit is given and this message
  8.  *  is retained.
  9.  *
  10.  *  Please e-mail any useful additions to vu-vlsi!plot so they may be
  11.  *  included in later releases.
  12.  *
  13.  *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
  14.  */
  15.  
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include "plot.h"
  19.  
  20. extern BOOLEAN undefined;
  21.  
  22. char *strcpy();
  23.  
  24. struct value *pop(), *complex(), *integer();
  25. double magnitude(), angle(), real();
  26.  
  27. struct value stack[STACK_DEPTH];
  28.  
  29. int s_p = -1;   /* stack pointer */
  30.  
  31.  
  32. /*
  33.  * System V and MSC 4.0 call this when they wants to print an error message.
  34.  * Don't!
  35.  */
  36. matherr()
  37. {
  38.     return (undefined = TRUE);        /* don't print error message */
  39. }
  40.  
  41.  
  42. reset_stack()
  43. {
  44.     s_p = -1;
  45. }
  46.  
  47.  
  48. check_stack()    /* make sure stack's empty */
  49. {
  50.     if (s_p != -1)
  51.         fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
  52. }
  53.  
  54.  
  55. struct value *pop(x)
  56. struct value *x;
  57. {
  58.     if (s_p  < 0 )
  59.         int_error("stack underflow",NO_CARET);
  60.     *x = stack[s_p--];
  61.     return(x);
  62. }
  63.  
  64.  
  65. push(x)
  66. struct value *x;
  67. {
  68.     if (s_p == STACK_DEPTH - 1)
  69.         int_error("stack overflow",NO_CARET);
  70.     stack[++s_p] = *x;
  71. }
  72.  
  73.  
  74. #define ERR_VAR "undefined variable: "
  75.  
  76. f_push(x)
  77. union argument *x;        /* contains pointer to value to push; */
  78. {
  79. static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
  80. struct udvt_entry *udv;
  81.  
  82.     udv = x->udv_arg;
  83.     if (udv->udv_undef) {     /* undefined */
  84.         (void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
  85.         int_error(err_str,NO_CARET);
  86.     }
  87.     push(&(udv->udv_value));
  88. }
  89.  
  90.  
  91. f_pushc(x)
  92. union argument *x;
  93. {
  94.     push(&(x->v_arg));
  95. }
  96.  
  97.  
  98. f_pushd(x)
  99. union argument *x;
  100. {
  101.     push(&(x->udf_arg->dummy_value));
  102. }
  103.  
  104.  
  105. #define ERR_FUN "undefined function: "
  106.  
  107. f_call(x)  /* execute a udf */
  108. union argument *x;
  109. {
  110. static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
  111. register struct udft_entry *udf;
  112.  
  113.     udf = x->udf_arg;
  114.     if (!udf->at) { /* undefined */
  115.         (void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
  116.                 udf->udf_name);
  117.         int_error(err_str,NO_CARET);
  118.     }
  119.     (void) pop(&(udf->dummy_value));
  120.  
  121.     execute_at(udf->at);
  122. }
  123.  
  124.  
  125. static int_check(v)
  126. struct value *v;
  127. {
  128.     if (v->type != INT)
  129.         int_error("non-integer passed to boolean operator",NO_CARET);
  130. }
  131.  
  132.  
  133. f_lnot()
  134. {
  135. struct value a;
  136.     int_check(pop(&a));
  137.     push(integer(&a,!a.v.int_val) );
  138. }
  139.  
  140.  
  141. f_bnot()
  142. {
  143. struct value a;
  144.     int_check(pop(&a));
  145.     push( integer(&a,~a.v.int_val) );
  146. }
  147.  
  148.  
  149. f_bool()
  150. {            /* converts top-of-stack to boolean */
  151.     int_check(&top_of_stack);
  152.     top_of_stack.v.int_val = !!top_of_stack.v.int_val;
  153. }
  154.  
  155.  
  156. f_lor()
  157. {
  158. struct value a,b;
  159.     int_check(pop(&b));
  160.     int_check(pop(&a));
  161.     push( integer(&a,a.v.int_val || b.v.int_val) );
  162. }
  163.  
  164. f_land()
  165. {
  166. struct value a,b;
  167.     int_check(pop(&b));
  168.     int_check(pop(&a));
  169.     push( integer(&a,a.v.int_val && b.v.int_val) );
  170. }
  171.  
  172.  
  173. f_bor()
  174. {
  175. struct value a,b;
  176.     int_check(pop(&b));
  177.     int_check(pop(&a));
  178.     push( integer(&a,a.v.int_val | b.v.int_val) );
  179. }
  180.  
  181.  
  182. f_xor()
  183. {
  184. struct value a,b;
  185.     int_check(pop(&b));
  186.     int_check(pop(&a));
  187.     push( integer(&a,a.v.int_val ^ b.v.int_val) );
  188. }
  189.  
  190.  
  191. f_band()
  192. {
  193. struct value a,b;
  194.     int_check(pop(&b));
  195.     int_check(pop(&a));
  196.     push( integer(&a,a.v.int_val & b.v.int_val) );
  197. }
  198.  
  199.  
  200. f_uminus()
  201. {
  202. struct value a;
  203.     (void) pop(&a);
  204.     switch(a.type) {
  205.         case INT:
  206.             a.v.int_val = -a.v.int_val;
  207.             break;
  208.         case CMPLX:
  209.             a.v.cmplx_val.real =
  210.                 -a.v.cmplx_val.real;
  211.             a.v.cmplx_val.imag =
  212.                 -a.v.cmplx_val.imag;
  213.     }
  214.     push(&a);
  215. }
  216.  
  217.  
  218. f_eq() /* note: floating point equality is rare because of roundoff error! */
  219. {
  220. struct value a, b;
  221.     register int result;
  222.     (void) pop(&b);
  223.     (void) pop(&a);
  224.     switch(a.type) {
  225.         case INT:
  226.             switch (b.type) {
  227.                 case INT:
  228.                     result = (a.v.int_val ==
  229.                         b.v.int_val);
  230.                     break;
  231.                 case CMPLX:
  232.                     result = (a.v.int_val ==
  233.                         b.v.cmplx_val.real &&
  234.                        b.v.cmplx_val.imag == 0.0);
  235.             }
  236.             break;
  237.         case CMPLX:
  238.             switch (b.type) {
  239.                 case INT:
  240.                     result = (b.v.int_val == a.v.cmplx_val.real &&
  241.                        a.v.cmplx_val.imag == 0.0);
  242.                     break;
  243.                 case CMPLX:
  244.                     result = (a.v.cmplx_val.real==
  245.                         b.v.cmplx_val.real &&
  246.                         a.v.cmplx_val.imag==
  247.                         b.v.cmplx_val.imag);
  248.             }
  249.     }
  250.     push(integer(&a,result));
  251. }
  252.  
  253.  
  254. f_ne()
  255. {
  256. struct value a, b;
  257.     register int result;
  258.     (void) pop(&b);
  259.     (void) pop(&a);
  260.     switch(a.type) {
  261.         case INT:
  262.             switch (b.type) {
  263.                 case INT:
  264.                     result = (a.v.int_val !=
  265.                         b.v.int_val);
  266.                     break;
  267.                 case CMPLX:
  268.                     result = (a.v.int_val !=
  269.                         b.v.cmplx_val.real ||
  270.                        b.v.cmplx_val.imag != 0.0);
  271.             }
  272.             break;
  273.         case CMPLX:
  274.             switch (b.type) {
  275.                 case INT:
  276.                     result = (b.v.int_val !=
  277.                         a.v.cmplx_val.real ||
  278.                        a.v.cmplx_val.imag != 0.0);
  279.                     break;
  280.                 case CMPLX:
  281.                     result = (a.v.cmplx_val.real !=
  282.                         b.v.cmplx_val.real ||
  283.                         a.v.cmplx_val.imag !=
  284.                         b.v.cmplx_val.imag);
  285.             }
  286.     }
  287.     push(integer(&a,result));
  288. }
  289.  
  290.  
  291. f_gt()
  292. {
  293. struct value a, b;
  294.     register int result;
  295.     (void) pop(&b);
  296.     (void) pop(&a);
  297.     switch(a.type) {
  298.         case INT:
  299.             switch (b.type) {
  300.                 case INT:
  301.                     result = (a.v.int_val >
  302.                         b.v.int_val);
  303.                     break;
  304.                 case CMPLX:
  305.                     result = (a.v.int_val >
  306.                         b.v.cmplx_val.real);
  307.             }
  308.             break;
  309.         case CMPLX:
  310.             switch (b.type) {
  311.                 case INT:
  312.                     result = (a.v.cmplx_val.real >
  313.                         b.v.int_val);
  314.                     break;
  315.                 case CMPLX:
  316.                     result = (a.v.cmplx_val.real >
  317.                         b.v.cmplx_val.real);
  318.             }
  319.     }
  320.     push(integer(&a,result));
  321. }
  322.  
  323.  
  324. f_lt()
  325. {
  326. struct value a, b;
  327.     register int result;
  328.     (void) pop(&b);
  329.     (void) pop(&a);
  330.     switch(a.type) {
  331.         case INT:
  332.             switch (b.type) {
  333.                 case INT:
  334.                     result = (a.v.int_val <
  335.                         b.v.int_val);
  336.                     break;
  337.                 case CMPLX:
  338.                     result = (a.v.int_val <
  339.                         b.v.cmplx_val.real);
  340.             }
  341.             break;
  342.         case CMPLX:
  343.             switch (b.type) {
  344.                 case INT:
  345.                     result = (a.v.cmplx_val.real <
  346.                         b.v.int_val);
  347.                     break;
  348.                 case CMPLX:
  349.                     result = (a.v.cmplx_val.real <
  350.                         b.v.cmplx_val.real);
  351.             }
  352.     }
  353.     push(integer(&a,result));
  354. }
  355.  
  356.  
  357. f_ge()
  358. {
  359. struct value a, b;
  360.     register int result;
  361.     (void) pop(&b);
  362.     (void) pop(&a);
  363.     switch(a.type) {
  364.         case INT:
  365.             switch (b.type) {
  366.                 case INT:
  367.                     result = (a.v.int_val >=
  368.                         b.v.int_val);
  369.                     break;
  370.                 case CMPLX:
  371.                     result = (a.v.int_val >=
  372.                         b.v.cmplx_val.real);
  373.             }
  374.             break;
  375.         case CMPLX:
  376.             switch (b.type) {
  377.                 case INT:
  378.                     result = (a.v.cmplx_val.real >=
  379.                         b.v.int_val);
  380.                     break;
  381.                 case CMPLX:
  382.                     result = (a.v.cmplx_val.real >=
  383.                         b.v.cmplx_val.real);
  384.             }
  385.     }
  386.     push(integer(&a,result));
  387. }
  388.  
  389.  
  390. f_le()
  391. {
  392. struct value a, b;
  393.     register int result;
  394.     (void) pop(&b);
  395.     (void) pop(&a);
  396.     switch(a.type) {
  397.         case INT:
  398.             switch (b.type) {
  399.                 case INT:
  400.                     result = (a.v.int_val <=
  401.                         b.v.int_val);
  402.                     break;
  403.                 case CMPLX:
  404.                     result = (a.v.int_val <=
  405.                         b.v.cmplx_val.real);
  406.             }
  407.             break;
  408.         case CMPLX:
  409.             switch (b.type) {
  410.                 case INT:
  411.                     result = (a.v.cmplx_val.real <=
  412.                         b.v.int_val);
  413.                     break;
  414.                 case CMPLX:
  415.                     result = (a.v.cmplx_val.real <=
  416.                         b.v.cmplx_val.real);
  417.             }
  418.     }
  419.     push(integer(&a,result));
  420. }
  421.  
  422.  
  423. f_plus()
  424. {
  425. struct value a, b, result;
  426.     (void) pop(&b);
  427.     (void) pop(&a);
  428.     switch(a.type) {
  429.         case INT:
  430.             switch (b.type) {
  431.                 case INT:
  432.                     (void) integer(&result,a.v.int_val +
  433.                         b.v.int_val);
  434.                     break;
  435.                 case CMPLX:
  436.                     (void) complex(&result,a.v.int_val +
  437.                         b.v.cmplx_val.real,
  438.                        b.v.cmplx_val.imag);
  439.             }
  440.             break;
  441.         case CMPLX:
  442.             switch (b.type) {
  443.                 case INT:
  444.                     (void) complex(&result,b.v.int_val +
  445.                         a.v.cmplx_val.real,
  446.                        a.v.cmplx_val.imag);
  447.                     break;
  448.                 case CMPLX:
  449.                     (void) complex(&result,a.v.cmplx_val.real+
  450.                         b.v.cmplx_val.real,
  451.                         a.v.cmplx_val.imag+
  452.                         b.v.cmplx_val.imag);
  453.             }
  454.     }
  455.     push(&result);
  456. }
  457.  
  458.  
  459. f_minus()
  460. {
  461. struct value a, b, result;
  462.     (void) pop(&b);
  463.     (void) pop(&a);        /* now do a - b */
  464.     switch(a.type) {
  465.         case INT:
  466.             switch (b.type) {
  467.                 case INT:
  468.                     (void) integer(&result,a.v.int_val -
  469.                         b.v.int_val);
  470.                     break;
  471.                 case CMPLX:
  472.                     (void) complex(&result,a.v.int_val -
  473.                         b.v.cmplx_val.real,
  474.                        -b.v.cmplx_val.imag);
  475.             }
  476.             break;
  477.         case CMPLX:
  478.             switch (b.type) {
  479.                 case INT:
  480.                     (void) complex(&result,a.v.cmplx_val.real -
  481.                         b.v.int_val,
  482.                         a.v.cmplx_val.imag);
  483.                     break;
  484.                 case CMPLX:
  485.                     (void) complex(&result,a.v.cmplx_val.real-
  486.                         b.v.cmplx_val.real,
  487.                         a.v.cmplx_val.imag-
  488.                         b.v.cmplx_val.imag);
  489.             }
  490.     }
  491.     push(&result);
  492. }
  493.  
  494.  
  495. f_mult()
  496. {
  497. struct value a, b, result;
  498.     (void) pop(&b);
  499.     (void) pop(&a);    /* now do a*b */
  500.  
  501.     switch(a.type) {
  502.         case INT:
  503.             switch (b.type) {
  504.                 case INT:
  505.                     (void) integer(&result,a.v.int_val *
  506.                         b.v.int_val);
  507.                     break;
  508.                 case CMPLX:
  509.                     (void) complex(&result,a.v.int_val *
  510.                         b.v.cmplx_val.real,
  511.                         a.v.int_val *
  512.                         b.v.cmplx_val.imag);
  513.             }
  514.             break;
  515.         case CMPLX:
  516.             switch (b.type) {
  517.                 case INT:
  518.                     (void) complex(&result,b.v.int_val *
  519.                         a.v.cmplx_val.real,
  520.                         b.v.int_val *
  521.                         a.v.cmplx_val.imag);
  522.                     break;
  523.                 case CMPLX:
  524.                     (void) complex(&result,a.v.cmplx_val.real*
  525.                         b.v.cmplx_val.real-
  526.                         a.v.cmplx_val.imag*
  527.                         b.v.cmplx_val.imag,
  528.                         a.v.cmplx_val.real*
  529.                         b.v.cmplx_val.imag+
  530.                         a.v.cmplx_val.imag*
  531.                         b.v.cmplx_val.real);
  532.             }
  533.     }
  534.     push(&result);
  535. }
  536.  
  537.  
  538. f_div()
  539. {
  540. struct value a, b, result;
  541. register double square;
  542.     (void) pop(&b);
  543.     (void) pop(&a);    /* now do a/b */
  544.  
  545.     switch(a.type) {
  546.         case INT:
  547.             switch (b.type) {
  548.                 case INT:
  549.                     if (b.v.int_val)
  550.                       (void) integer(&result,a.v.int_val /
  551.                         b.v.int_val);
  552.                     else {
  553.                       (void) integer(&result,0);
  554.                       undefined = TRUE;
  555.                     }
  556.                     break;
  557.                 case CMPLX:
  558.                     square = b.v.cmplx_val.real*
  559.                         b.v.cmplx_val.real +
  560.                         b.v.cmplx_val.imag*
  561.                         b.v.cmplx_val.imag;
  562.                     if (square)
  563.                         (void) complex(&result,a.v.int_val*
  564.                         b.v.cmplx_val.real/square,
  565.                         -a.v.int_val*
  566.                         b.v.cmplx_val.imag/square);
  567.                     else {
  568.                         (void) complex(&result,0.0,0.0);
  569.                         undefined = TRUE;
  570.                     }
  571.             }
  572.             break;
  573.         case CMPLX:
  574.             switch (b.type) {
  575.                 case INT:
  576.                     if (b.v.int_val)
  577.                       
  578.                       (void) complex(&result,a.v.cmplx_val.real/
  579.                         b.v.int_val,
  580.                         a.v.cmplx_val.imag/
  581.                         b.v.int_val);
  582.                     else {
  583.                         (void) complex(&result,0.0,0.0);
  584.                         undefined = TRUE;
  585.                     }
  586.                     break;
  587.                 case CMPLX:
  588.                     square = b.v.cmplx_val.real*
  589.                         b.v.cmplx_val.real +
  590.                         b.v.cmplx_val.imag*
  591.                         b.v.cmplx_val.imag;
  592.                     if (square)
  593.                     (void) complex(&result,(a.v.cmplx_val.real*
  594.                         b.v.cmplx_val.real+
  595.                         a.v.cmplx_val.imag*
  596.                         b.v.cmplx_val.imag)/square,
  597.                         (a.v.cmplx_val.imag*
  598.                         b.v.cmplx_val.real-
  599.                         a.v.cmplx_val.real*
  600.                         b.v.cmplx_val.imag)/
  601.                             square);
  602.                     else {
  603.                         (void) complex(&result,0.0,0.0);
  604.                         undefined = TRUE;
  605.                     }
  606.             }
  607.     }
  608.     push(&result);
  609. }
  610.  
  611.  
  612. f_mod()
  613. {
  614. struct value a, b;
  615.     (void) pop(&b);
  616.     (void) pop(&a);    /* now do a%b */
  617.  
  618.     if (a.type != INT || b.type != INT)
  619.         int_error("can only mod ints",NO_CARET);
  620.     if (b.v.int_val)
  621.         push(integer(&a,a.v.int_val % b.v.int_val));
  622.     else {
  623.         push(integer(&a,0));
  624.         undefined = TRUE;
  625.     }
  626. }
  627.  
  628.  
  629. f_power()
  630. {
  631. struct value a, b, result;
  632. register int i, t, count;
  633. register double mag, ang;
  634.     (void) pop(&b);
  635.     (void) pop(&a);    /* now find a**b */
  636.  
  637.     switch(a.type) {
  638.         case INT:
  639.             switch (b.type) {
  640.                 case INT:
  641.                     count = abs(b.v.int_val);
  642.                     t = 1;
  643.                     for(i = 0; i < count; i++)
  644.                         t *= a.v.int_val;
  645.                     if (b.v.int_val >= 0)
  646.                         (void) integer(&result,t);
  647.                     else
  648.                         (void) complex(&result,1.0/t,0.0);
  649.                     break;
  650.                 case CMPLX:
  651.                     mag =
  652.                       pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  653.                     if (b.v.cmplx_val.real < 0.0)
  654.                         mag = 1.0/mag;
  655.                     ang = angle(&a)*b.v.cmplx_val.real+
  656.                       b.v.cmplx_val.imag;
  657.                     (void) complex(&result,mag*cos(ang),
  658.                         mag*sin(ang));
  659.             }
  660.             break;
  661.         case CMPLX:
  662.             switch (b.type) {
  663.                 case INT:
  664.                     if (a.v.cmplx_val.imag == 0.0) {
  665.                         mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
  666.                         if (b.v.int_val < 0)
  667.                             mag = 1.0/mag;
  668.                         (void) complex(&result,mag,0.0);
  669.                     }
  670.                     else {
  671.                         /* not so good, but...! */
  672.                         mag = pow(magnitude(&a),(double)abs(b.v.int_val));
  673.                         if (b.v.int_val < 0)
  674.                             mag = 1.0/mag;
  675.                         ang = angle(&a)*b.v.int_val;
  676.                         (void) complex(&result,mag*cos(ang),
  677.                             mag*sin(ang));
  678.                     }
  679.                     break;
  680.                 case CMPLX:
  681.                     mag = pow(magnitude(&a),fabs(b.v.cmplx_val.real));
  682.                     if (b.v.cmplx_val.real < 0.0)
  683.                       mag = 1.0/mag;
  684.                     ang = angle(&a)*b.v.cmplx_val.real+ b.v.cmplx_val.imag;
  685.                     (void) complex(&result,mag*cos(ang),
  686.                         mag*sin(ang));
  687.             }
  688.     }
  689.     push(&result);
  690. }
  691.  
  692.  
  693. f_factorial()
  694. {
  695. struct value a;
  696. register int i;
  697. register double val;
  698.  
  699.     (void) pop(&a);    /* find a! (factorial) */
  700.  
  701.     switch (a.type) {
  702.         case INT:
  703.             val = 1.0;
  704.             for (i = a.v.int_val; i > 1; i--)  /*fpe's should catch overflows*/
  705.                 val *= i;
  706.             break;
  707.         default:
  708.             int_error("factorial (!) argument must be an integer",
  709.             NO_CARET);
  710.         }
  711.  
  712.     push(complex(&a,val,0.0));
  713.             
  714. }
  715.  
  716.  
  717. int
  718. f_jump(x)
  719. union argument *x;
  720. {
  721.     return(x->j_arg);
  722. }
  723.  
  724.  
  725. int
  726. f_jumpz(x)
  727. union argument *x;
  728. {
  729. struct value a;
  730.     int_check(&top_of_stack);
  731.     if (top_of_stack.v.int_val) {    /* non-zero */
  732.         (void) pop(&a);
  733.         return 1;                /* no jump */
  734.     }
  735.     else
  736.         return(x->j_arg);        /* leave the argument on TOS */
  737. }
  738.  
  739.  
  740. int
  741. f_jumpnz(x)
  742. union argument *x;
  743. {
  744. struct value a;
  745.     int_check(&top_of_stack);
  746.     if (top_of_stack.v.int_val)    /* non-zero */
  747.         return(x->j_arg);        /* leave the argument on TOS */
  748.     else {
  749.         (void) pop(&a);
  750.         return 1;                /* no jump */
  751.     }
  752. }
  753.  
  754.  
  755. int
  756. f_jtern(x)
  757. union argument *x;
  758. {
  759. struct value a;
  760.  
  761.     int_check(pop(&a));
  762.     if (a.v.int_val)
  763.         return(1);                /* no jump; fall through to TRUE code */
  764.     else
  765.         return(x->j_arg);        /* go jump to FALSE code */
  766. }
  767.