home *** CD-ROM | disk | FTP | other *** search
/ CICA 1995 May / cica_0595_4.zip / cica_0595_4 / UTIL / GPT34SRC / PARSE.C < prev    next >
C/C++ Source or Header  |  1993-05-25  |  12KB  |  613 lines

  1. #ifndef lint
  2. static char    *RCSid = "$Id: parse.c%v 3.38.2.121 1993/04/30 00:02:32 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - parse.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley 
  9.  *
  10.  * Permission to use, copy, and distribute this software and its documentation
  11.  * for any purpose with or without fee is hereby granted, provided that the
  12.  * above copyright notice appear in all copies and that both that copyright
  13.  * notice and this permission notice appear in supporting documentation. 
  14.  *
  15.  * Permission to modify the software is granted, but not the right to distribute
  16.  * the modified code.  Modifications are to be distributed as patches to
  17.  * released version. 
  18.  *
  19.  * This software is provided "as is" without express or implied warranty. 
  20.  *
  21.  *
  22.  * AUTHORS 
  23.  *
  24.  * Original Software: Thomas Williams,  Colin Kelley. 
  25.  *
  26.  * Gnuplot 2.0 additions: Russell Lang, Dave Kotz, John Campbell. 
  27.  *
  28.  * Gnuplot 3.0 additions: Gershon Elber and many others. 
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <setjmp.h>
  34. #include <signal.h>
  35. #include <errno.h>
  36. #include <math.h>
  37. #include "plot.h"
  38.  
  39. #ifndef vms
  40. #if !defined(__ZTC__) && !defined(__MSC__)
  41. extern int      errno;
  42. #endif
  43. #endif
  44.  
  45. extern int      num_tokens, c_token;
  46. extern struct lexical_unit token[];
  47. extern char     c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN + 1];    /* name of current dummy
  48.                                  * vars */
  49. extern struct udft_entry *dummy_func;    /* pointer to dummy variable's func */
  50.  
  51. struct value   *
  52. pop(), *Ginteger(), *Gcomplex();
  53. struct at_type *
  54. temp_at(), *perm_at();
  55. struct udft_entry *add_udf();
  56. struct udvt_entry *add_udv();
  57. union argument *add_action();
  58.  
  59. struct at_type  at;
  60. #ifdef _Windows
  61. static jmp_buf far fpe_env;
  62. #else
  63. static jmp_buf  fpe_env;
  64. #endif
  65.  
  66. #define dummy (struct value *) 0
  67.  
  68. #if defined(__TURBOC__) || defined(DJGPP)
  69. void
  70. fpe()
  71. #else
  72. #if defined( __ZTC__ ) || defined( _CRAY ) || defined( sgi )|| defined( OS2 ) || defined(__EMX__)
  73. void
  74. fpe(an_int)
  75.     int             an_int;
  76. #else
  77. #if defined( NEXT ) || defined( VMS)
  78. void
  79. fpe(int an_int)
  80. #else
  81. #ifdef sgi
  82. void
  83. fpe(int sig, int code, struct sigcontext * sc)
  84. /*
  85.  * void fpe(an_int) int an_int; 
  86.  */
  87. #else
  88. fpe()
  89. #endif
  90. #endif
  91. #endif                /* __ZTC__ || _CRAY */
  92. #endif                /* __TURBOC__ */
  93. {
  94. #if defined(MSDOS) && !defined(__EMX__) && !defined(DJGPP) && !defined(_Windows) || defined(DOS386)
  95.     /* thanks to lotto@wjh12.UUCP for telling us about this  */
  96.     _fpreset();
  97. #endif
  98. #if defined(MSDOS) && defined(__EMX__)
  99.     (void)signal(SIGFPE, (void *)fpe);
  100. #else
  101. #ifdef DJGPP
  102.     (void)signal(SIGFPE, (SignalHandler)fpe);
  103. #else
  104. #ifdef OS2
  105.     (void) signal(an_int, SIG_ACK);
  106. #else
  107.     (void)signal(SIGFPE, fpe);
  108. #endif
  109. #endif
  110. #endif
  111. #ifdef ATARI
  112.     /* do we need this ? (AL) */
  113.     fprintf(stderr, "floating point exception!\n");
  114. #endif
  115.     undefined = TRUE;
  116.     longjmp(fpe_env, TRUE);
  117. }
  118.  
  119.  
  120. #ifdef apollo
  121. #include <apollo/base.h>
  122. #include <apollo/pfm.h>
  123. #include <apollo/fault.h>
  124.  
  125. /*
  126.  * On an Apollo, the OS can signal a couple errors that are not mapped into
  127.  * SIGFPE, namely signalling NaN and branch on an unordered comparison.  I
  128.  * suppose there are others, but none of these are documented, so I handle
  129.  * them as they arise. 
  130.  *
  131.  * Anyway, we need to catch these faults and signal SIGFPE. 
  132.  */
  133.  
  134. pfm_$fh_func_val_t apollo_sigfpe(pfm_$fault_rec_t & fault_rec)
  135. {
  136.     kill(getpid(), SIGFPE);
  137.     return pfm_$continue_fault_handling;
  138. }
  139.  
  140. apollo_pfm_catch()
  141. {
  142.     status_$t status;
  143.     pfm_$establish_fault_handler(fault_$fp_bsun, pfm_$fh_backstop,
  144.                        apollo_sigfpe, &status);
  145.     pfm_$establish_fault_handler(fault_$fp_sig_nan, pfm_$fh_backstop,
  146.                        apollo_sigfpe, &status);
  147. }
  148. #endif
  149.  
  150.  
  151. evaluate_at(at_ptr, val_ptr)
  152.     struct at_type *at_ptr;
  153.     struct value   *val_ptr;
  154. {
  155.     double          temp, real();
  156.  
  157.     undefined = FALSE;
  158.     errno = 0;
  159.     reset_stack();
  160.  
  161. #ifndef DOSX286
  162.     if (setjmp(fpe_env))
  163.         return(0);        /* just bail out */
  164. #if defined(MSDOS) && defined(__EMX__)
  165.     (void)signal(SIGFPE, (void *)fpe);
  166. #else
  167. #if DJGPP
  168.     (void)signal(SIGFPE, (SignalHandler)fpe);
  169. #else
  170.     (void)signal(SIGFPE, fpe);    /* catch core dumps on FPEs */
  171. #endif
  172. #endif
  173. #endif
  174.  
  175.     execute_at(at_ptr);
  176.  
  177. #ifndef DOSX286
  178.     (void)signal(SIGFPE, SIG_DFL);
  179. #endif
  180.  
  181.     if (errno == EDOM || errno == ERANGE) {
  182.         undefined = TRUE;
  183.     } else {
  184.         (void)pop(val_ptr);
  185.         check_stack();
  186.     }
  187.     /* At least one machine (ATT 3b1) computes Inf without a SIGFPE */
  188.     temp = real(val_ptr);
  189.     if (temp > VERYLARGE || temp < -VERYLARGE) {
  190.         undefined = TRUE;
  191.     }
  192. }
  193.  
  194.  
  195. struct value   *
  196. const_express(valptr)
  197.     struct value   *valptr;
  198. {
  199.     register int    tkn = c_token;
  200.     if (END_OF_COMMAND)
  201.         int_error("constant expression required", c_token);
  202.     evaluate_at(temp_at(), valptr);    /* run it and send answer back */
  203.     if (undefined) {
  204.         int_error("undefined value", tkn);
  205.     }
  206.     return (valptr);
  207. }
  208.  
  209.  
  210. struct at_type *
  211. temp_at()
  212. {                /* build a static action table and return its
  213.                  * pointer */
  214.     at.a_count = 0;        /* reset action table !!! */
  215.     express();
  216.     return (&at);
  217. }
  218.  
  219.  
  220. /* build an action table, put it in dynamic memory, and return its pointer */
  221.  
  222. struct at_type *
  223. perm_at()
  224. {
  225.     register struct at_type *at_ptr;
  226.     register unsigned int len;
  227.  
  228.     (void)temp_at();
  229.     len = sizeof(struct at_type) -
  230.         (MAX_AT_LEN - at.a_count) * sizeof(struct at_entry);
  231.     at_ptr = (struct at_type *) alloc((unsigned long)len, "action table");
  232.     (void)memcpy(at_ptr, &at, len);
  233.     return (at_ptr);
  234. }
  235.  
  236.  
  237. #ifdef NOCOPY
  238. /*
  239.  * cheap and slow version of memcpy() in case you don't have one 
  240.  */
  241. memcpy(dest, src, len)
  242.     char           *dest, *src;
  243.     unsigned int    len;
  244. {
  245.     while (len--)
  246.         *dest++ = *src++;
  247. }
  248. #endif                /* NOCOPY */
  249.  
  250.  
  251. express()
  252. {                /* full expressions */
  253.     xterm();
  254.     xterms();
  255. }
  256.  
  257. xterm()
  258. {                /* ? : expressions */
  259.     aterm();
  260.     aterms();
  261. }
  262.  
  263.  
  264. aterm()
  265. {
  266.     bterm();
  267.     bterms();
  268. }
  269.  
  270.  
  271. bterm()
  272. {
  273.     cterm();
  274.     cterms();
  275. }
  276.  
  277.  
  278. cterm()
  279. {
  280.     dterm();
  281.     dterms();
  282. }
  283.  
  284.  
  285. dterm()
  286. {
  287.     eterm();
  288.     eterms();
  289. }
  290.  
  291.  
  292. eterm()
  293. {
  294.     fterm();
  295.     fterms();
  296. }
  297.  
  298.  
  299. fterm()
  300. {
  301.     gterm();
  302.     gterms();
  303. }
  304.  
  305.  
  306. gterm()
  307. {
  308.     hterm();
  309.     hterms();
  310. }
  311.  
  312.  
  313. hterm()
  314. {
  315.     unary();        /* - things */
  316.     iterms();        /* * / % */
  317. }
  318.  
  319.  
  320. factor()
  321. {
  322.     register int    value;
  323.  
  324.     if (equals(c_token, "(")) {
  325.         c_token++;
  326.         express();
  327.         if (!equals(c_token, ")"))
  328.             int_error("')' expected", c_token);
  329.         c_token++;
  330.     } else if (isnumber(c_token)) {
  331.         convert(&(add_action(PUSHC)->v_arg), c_token);
  332.         c_token++;
  333.     } else if (isletter(c_token)) {
  334.         if ((c_token + 1 < num_tokens) && equals(c_token + 1, "(")) {
  335.             value = standard(c_token);
  336.             if (value) {    /* it's a standard function */
  337.                 c_token += 2;
  338.                 express();
  339.                 if (equals(c_token, ",")) {
  340.                     while (equals(c_token, ",")) {
  341.                         c_token += 1;
  342.                         express();
  343.                     }
  344.                 }
  345.                 if (!equals(c_token, ")"))
  346.                     int_error("')' expected", c_token);
  347.                 c_token++;
  348.                 (void)add_action(value);
  349.             } else {
  350.                 int             call_type = (int)CALL;
  351.                 value = c_token;
  352.                 c_token += 2;
  353.                 express();
  354.                 if (equals(c_token, ",")) {
  355.                     struct value    num_params;
  356.                     num_params.type = INTGR;
  357.                     num_params.v.int_val = 1;
  358.                     while (equals(c_token, ",")) {
  359.                         num_params.v.int_val += 1;
  360.                         c_token += 1;
  361.                         express();
  362.                     }
  363.                     add_action(PUSHC)->v_arg = num_params;
  364.                     call_type = (int)CALLN;
  365.                 }
  366.                 if (!equals(c_token, ")"))
  367.                     int_error("')' expected", c_token);
  368.                 c_token++;
  369.                 add_action(call_type)->udf_arg = add_udf(value);
  370.             }
  371.         } else {
  372.             if (equals(c_token, c_dummy_var[0])) {
  373.                 c_token++;
  374.                 add_action(PUSHD1)->udf_arg = dummy_func;
  375.             } else if (equals(c_token, c_dummy_var[1])) {
  376.                 c_token++;
  377.                 add_action(PUSHD2)->udf_arg = dummy_func;
  378.             } else {
  379.                 int             i, param = 0;
  380.                 for (i = 2; i < MAX_NUM_VAR; i++) {
  381.                     if (equals(c_token, c_dummy_var[i])) {
  382.                         struct value    num_params;
  383.                         num_params.type = INTGR;
  384.                         num_params.v.int_val = i;
  385.                         param = 1;
  386.                         c_token++;
  387.                         add_action(PUSHC)->v_arg = num_params;
  388.                         add_action(PUSHD)->udf_arg = dummy_func;
  389.                         break;
  390.                     }
  391.                 }
  392.                 if (!param) {    /* defined variable */
  393.                     add_action(PUSH)->udv_arg = add_udv(c_token);
  394.                     c_token++;
  395.                 }
  396.             }
  397.         }
  398.     }
  399.     /* end if letter */
  400.     else
  401.         int_error("invalid expression ", c_token);
  402.  
  403.     /* add action code for ! (factorial) operator */
  404.     while (equals(c_token, "!")) {
  405.         c_token++;
  406.         (void)add_action(FACTORIAL);
  407.     }
  408.     /* add action code for ** operator */
  409.     if (equals(c_token, "**")) {
  410.         c_token++;
  411.         unary();
  412.         (void)add_action(POWER);
  413.     }
  414. }
  415.  
  416.  
  417.  
  418. xterms()
  419. {                /* create action code for ? : expressions */
  420.  
  421.     if (equals(c_token, "?")) {
  422.         register int    savepc1, savepc2;
  423.         register union argument *argptr1, *argptr2;
  424.         c_token++;
  425.         savepc1 = at.a_count;
  426.         argptr1 = add_action(JTERN);
  427.         express();
  428.         if (!equals(c_token, ":"))
  429.             int_error("expecting ':'", c_token);
  430.         c_token++;
  431.         savepc2 = at.a_count;
  432.         argptr2 = add_action(JUMP);
  433.         argptr1->j_arg = at.a_count - savepc1;
  434.         express();
  435.         argptr2->j_arg = at.a_count - savepc2;
  436.     }
  437. }
  438.  
  439.  
  440. aterms()
  441. {                /* create action codes for || operator */
  442.  
  443.     while (equals(c_token, "||")) {
  444.         register int    savepc;
  445.         register union argument *argptr;
  446.         c_token++;
  447.         savepc = at.a_count;
  448.         argptr = add_action(JUMPNZ);    /* short-circuit if already
  449.                          * TRUE */
  450.         aterm();
  451.         argptr->j_arg = at.a_count - savepc;    /* offset for jump */
  452.         (void)add_action(BOOLE);
  453.     }
  454. }
  455.  
  456.  
  457. bterms()
  458. {                /* create action code for && operator */
  459.  
  460.     while (equals(c_token, "&&")) {
  461.         register int    savepc;
  462.         register union argument *argptr;
  463.         c_token++;
  464.         savepc = at.a_count;
  465.         argptr = add_action(JUMPZ);    /* short-circuit if already
  466.                          * FALSE */
  467.         bterm();
  468.         argptr->j_arg = at.a_count - savepc;    /* offset for jump */
  469.         (void)add_action(BOOLE);
  470.     }
  471. }
  472.  
  473.  
  474. cterms()
  475. {                /* create action code for | operator */
  476.  
  477.     while (equals(c_token, "|")) {
  478.         c_token++;
  479.         cterm();
  480.         (void)add_action(BOR);
  481.     }
  482. }
  483.  
  484.  
  485. dterms()
  486. {                /* create action code for ^ operator */
  487.  
  488.     while (equals(c_token, "^")) {
  489.         c_token++;
  490.         dterm();
  491.         (void)add_action(XOR);
  492.     }
  493. }
  494.  
  495.  
  496. eterms()
  497. {                /* create action code for & operator */
  498.  
  499.     while (equals(c_token, "&")) {
  500.         c_token++;
  501.         eterm();
  502.         (void)add_action(BAND);
  503.     }
  504. }
  505.  
  506.  
  507. fterms()
  508. {                /* create action codes for == and !=
  509.                  * operators */
  510.  
  511.     while (TRUE) {
  512.         if (equals(c_token, "==")) {
  513.             c_token++;
  514.             fterm();
  515.             (void)add_action(EQ);
  516.         } else if (equals(c_token, "!=")) {
  517.             c_token++;
  518.             fterm();
  519.             (void)add_action(NE);
  520.         } else
  521.             break;
  522.     }
  523. }
  524.  
  525.  
  526. gterms()
  527. {                /* create action code for < > >= or <=
  528.                  * operators */
  529.  
  530.     while (TRUE) {
  531.         /* I hate "else if" statements */
  532.         if (equals(c_token, ">")) {
  533.             c_token++;
  534.             gterm();
  535.             (void)add_action(GT);
  536.         } else if (equals(c_token, "<")) {
  537.             c_token++;
  538.             gterm();
  539.             (void)add_action(LT);
  540.         } else if (equals(c_token, ">=")) {
  541.             c_token++;
  542.             gterm();
  543.             (void)add_action(GE);
  544.         } else if (equals(c_token, "<=")) {
  545.             c_token++;
  546.             gterm();
  547.             (void)add_action(LE);
  548.         } else
  549.             break;
  550.     }
  551.  
  552. }
  553.  
  554.  
  555.  
  556. hterms()
  557. {                /* create action codes for + and - operators */
  558.  
  559.     while (TRUE) {
  560.         if (equals(c_token, "+")) {
  561.             c_token++;
  562.             hterm();
  563.             (void)add_action(PLUS);
  564.         } else if (equals(c_token, "-")) {
  565.             c_token++;
  566.             hterm();
  567.             (void)add_action(MINUS);
  568.         } else
  569.             break;
  570.     }
  571. }
  572.  
  573.  
  574. iterms()
  575. {                /* add action code for * / and % operators */
  576.  
  577.     while (TRUE) {
  578.         if (equals(c_token, "*")) {
  579.             c_token++;
  580.             unary();
  581.             (void)add_action(MULT);
  582.         } else if (equals(c_token, "/")) {
  583.             c_token++;
  584.             unary();
  585.             (void)add_action(DIV);
  586.         } else if (equals(c_token, "%")) {
  587.             c_token++;
  588.             unary();
  589.             (void)add_action(MOD);
  590.         } else
  591.             break;
  592.     }
  593. }
  594.  
  595.  
  596. unary()
  597. {                /* add code for unary operators */
  598.     if (equals(c_token, "!")) {
  599.         c_token++;
  600.         unary();
  601.         (void)add_action(LNOT);
  602.     } else if (equals(c_token, "~")) {
  603.         c_token++;
  604.         unary();
  605.         (void)add_action(BNOT);
  606.     } else if (equals(c_token, "-")) {
  607.         c_token++;
  608.         unary();
  609.         (void)add_action(UMINUS);
  610.     } else
  611.         factor();
  612. }
  613.