home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 334_02 / internal.c < prev    next >
Text File  |  1991-02-05  |  16KB  |  812 lines

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