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

  1. /*
  2.  *
  3.  *    G N U P L O T  --  parse.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 <stdio.h>
  17. #include <setjmp.h>
  18. #include <signal.h>
  19. #include <errno.h>
  20. #include "plot.h"
  21.  
  22. extern BOOLEAN undefined;
  23.  
  24. #ifndef vms
  25. extern int errno;
  26. #endif
  27.  
  28. extern int num_tokens,c_token;
  29. extern struct lexical_unit token[];
  30. extern char c_dummy_var[];            /* name of current dummy variable */
  31. extern struct udft_entry *dummy_func;    /* pointer to dummy variable's func */
  32.  
  33. char *malloc();
  34.  
  35. struct value *pop(),*integer(),*complex();
  36. struct at_type *temp_at(), *perm_at();
  37. struct udft_entry *add_udf();
  38. struct udvt_entry *add_udv();
  39. union argument *add_action();
  40.  
  41. struct at_type at;
  42. static jmp_buf fpe_env;
  43.  
  44. #define dummy (struct value *) 0
  45. #ifdef __TURBOC__
  46. void fpe(int xXx)
  47. #else
  48. fpe()
  49. #endif
  50. {
  51. #ifdef PC    /* thanks to lotto@wjh12.UUCP for telling us about this  */
  52.     _fpreset();
  53. #endif
  54.     (void) signal(SIGFPE, fpe);
  55.     undefined = TRUE;
  56.     longjmp(fpe_env, TRUE);
  57. }
  58.  
  59.  
  60. evaluate_at(at_ptr,val_ptr)
  61. struct at_type *at_ptr;
  62. struct value *val_ptr;
  63. {
  64.     undefined = FALSE;
  65.     errno = 0;
  66.     reset_stack();
  67.     if (setjmp(fpe_env))
  68.         return;                /* just bail out */
  69.     (void) signal(SIGFPE, fpe);    /* catch core dumps on FPEs */
  70.  
  71.     execute_at(at_ptr);
  72.  
  73.     (void) signal(SIGFPE, SIG_DFL);
  74.  
  75.     if (errno == EDOM || errno == ERANGE) {
  76.         undefined = TRUE;
  77.     } else {
  78.         (void) pop(val_ptr);
  79.         check_stack();
  80.     }
  81. }
  82.  
  83.  
  84. struct value *
  85. const_express(valptr)
  86. struct value *valptr;
  87. {
  88. register int tkn = c_token;
  89.     if (END_OF_COMMAND)
  90.         int_error("constant expression required",c_token);
  91.     evaluate_at(temp_at(),valptr);    /* run it and send answer back */
  92.     if (undefined) {
  93.         int_error("undefined value",tkn);
  94.     }
  95.     return(valptr);
  96. }
  97.  
  98.  
  99. struct at_type *
  100. temp_at()    /* build a static action table and return its pointer */
  101. {
  102.     at.a_count = 0;        /* reset action table !!! */
  103.     express();
  104.     return(&at);
  105. }
  106.  
  107.  
  108. /* build an action table, put it in dynamic memory, and return its pointer */
  109.  
  110. struct at_type *
  111. perm_at()
  112. {
  113. register struct at_type *at_ptr;
  114. register unsigned int len;
  115.  
  116.     (void) temp_at();
  117.     len = sizeof(struct at_type) -
  118.         (MAX_AT_LEN - at.a_count)*sizeof(struct at_entry);
  119.     if (at_ptr = (struct at_type *) malloc(len))
  120.         (void) memcpy(at_ptr,&at,len);
  121.     return(at_ptr);
  122. }
  123.  
  124.  
  125. #ifdef NOCOPY
  126. /*
  127.  * cheap and slow version of memcpy() in case you don't have one
  128.  */
  129. memcpy(dest,src,len)
  130. char *dest,*src;
  131. unsigned int len;
  132. {
  133.     while (len--)
  134.         *dest++ = *src++;
  135. }
  136. #endif /* NOCOPY */
  137.  
  138.  
  139. express()  /* full expressions */
  140. {
  141.     xterm();
  142.     xterms();
  143. }
  144.  
  145. xterm()  /* ? : expressions */
  146. {
  147.     aterm();
  148.     aterms();
  149. }
  150.  
  151.  
  152. aterm()
  153. {
  154.     bterm();
  155.     bterms();
  156. }
  157.  
  158.  
  159. bterm()
  160. {
  161.     cterm();
  162.     cterms();
  163. }
  164.  
  165.  
  166. cterm()
  167. {
  168.     dterm();
  169.     dterms();
  170. }
  171.  
  172.  
  173. dterm()
  174. {    
  175.     eterm();
  176.     eterms();
  177. }
  178.  
  179.  
  180. eterm()
  181. {
  182.     fterm();
  183.     fterms();
  184. }
  185.  
  186.  
  187. fterm()
  188. {
  189.     gterm();
  190.     gterms();
  191. }
  192.  
  193.  
  194. gterm()
  195. {
  196.     hterm();
  197.     hterms();
  198. }
  199.  
  200.  
  201. hterm()
  202. {
  203.     unary(); /* - things */
  204.     iterms(); /* * / % */
  205. }
  206.  
  207.  
  208. factor()
  209. {
  210. register int value;
  211.  
  212.     if (equals(c_token,"(")) {
  213.         c_token++;
  214.         express();
  215.         if (!equals(c_token,")"))
  216.             int_error("')' expected",c_token);
  217.         c_token++;
  218.     }
  219.     else if (isnumber(c_token)) {
  220.         convert(&(add_action(PUSHC)->v_arg),c_token);
  221.         c_token++;
  222.     }
  223.     else if (isletter(c_token)) {
  224.         if ((c_token+1 < num_tokens)  && equals(c_token+1,"(")) {
  225.             value = standard(c_token);
  226.             if (value) {    /* it's a standard function */
  227.                 c_token += 2;
  228.                 express();
  229.                 if (!equals(c_token,")"))
  230.                     int_error("')' expected",c_token);
  231.                 c_token++;
  232.                 (void) add_action(value);
  233.             }
  234.             else {
  235.                 value = c_token;
  236.                 c_token += 2;
  237.                 express();
  238.                 if (!equals(c_token,")"))
  239.                     int_error("')' expected",c_token);
  240.                 c_token++;
  241.                 add_action(CALL)->udf_arg = add_udf(value);
  242.             }
  243.         }
  244.         else {
  245.             if (equals(c_token,c_dummy_var)) {
  246.                 c_token++;
  247.                 add_action(PUSHD)->udf_arg = dummy_func;
  248.             }
  249.             else {
  250.                 add_action(PUSH)->udv_arg = add_udv(c_token);
  251.                 c_token++;
  252.             }
  253.         }
  254.     } /* end if letter */
  255.     else
  256.         int_error("invalid expression ",c_token);
  257.  
  258.     /* add action code for ! (factorial) operator */
  259.     while (equals(c_token,"!")) {
  260.         c_token++;
  261.         (void) add_action(FACTORIAL);
  262.     }
  263.     /* add action code for ** operator */
  264.     if (equals(c_token,"**")) {
  265.             c_token++;
  266.             unary();
  267.             (void) add_action(POWER);
  268.     }
  269.  
  270. }
  271.  
  272.  
  273.  
  274. xterms()
  275. {  /* create action code for ? : expressions */
  276.  
  277.     if (equals(c_token,"?")) {
  278.         register int savepc1, savepc2;
  279.         register union argument *argptr1,*argptr2;
  280.         c_token++;
  281.         savepc1 = at.a_count;
  282.         argptr1 = add_action(JTERN);
  283.         express();
  284.         if (!equals(c_token,":"))
  285.             int_error("expecting ':'",c_token);
  286.         c_token++;
  287.         savepc2 = at.a_count;
  288.         argptr2 = add_action(JUMP);
  289.         argptr1->j_arg = at.a_count - savepc1;
  290.         express();
  291.         argptr2->j_arg = at.a_count - savepc2;
  292.     }
  293. }
  294.  
  295.  
  296. aterms()
  297. {  /* create action codes for || operator */
  298.  
  299.     while (equals(c_token,"||")) {
  300.         register int savepc;
  301.         register union argument *argptr;
  302.         c_token++;
  303.         savepc = at.a_count;
  304.         argptr = add_action(JUMPNZ);    /* short-circuit if already TRUE */
  305.         aterm();
  306.         argptr->j_arg = at.a_count - savepc;/* offset for jump */
  307.         (void) add_action(BOOL);
  308.     }
  309. }
  310.  
  311.  
  312. bterms()
  313. { /* create action code for && operator */
  314.  
  315.     while (equals(c_token,"&&")) {
  316.         register int savepc;
  317.         register union argument *argptr;
  318.         c_token++;
  319.         savepc = at.a_count;
  320.         argptr = add_action(JUMPZ);    /* short-circuit if already FALSE */
  321.         bterm();
  322.         argptr->j_arg = at.a_count - savepc;/* offset for jump */
  323.         (void) add_action(BOOL);
  324.     }
  325. }
  326.  
  327.  
  328. cterms()
  329. { /* create action code for | operator */
  330.  
  331.     while (equals(c_token,"|")) {
  332.         c_token++;
  333.         cterm();
  334.         (void) add_action(BOR);
  335.     }
  336. }
  337.  
  338.  
  339. dterms()
  340. { /* create action code for ^ operator */
  341.  
  342.     while (equals(c_token,"^")) {
  343.         c_token++;
  344.         dterm();
  345.         (void) add_action(XOR);
  346.     }
  347. }
  348.  
  349.  
  350. eterms()
  351. { /* create action code for & operator */
  352.  
  353.     while (equals(c_token,"&")) {
  354.         c_token++;
  355.         eterm();
  356.         (void) add_action(BAND);
  357.     }
  358. }
  359.  
  360.  
  361. fterms()
  362. { /* create action codes for == and != operators */
  363.  
  364.     while (TRUE) {
  365.         if (equals(c_token,"==")) {
  366.             c_token++;
  367.             fterm();
  368.             (void) add_action(EQ);
  369.         }
  370.         else if (equals(c_token,"!=")) {
  371.             c_token++;
  372.             fterm();
  373.             (void) add_action(NE);
  374.         }
  375.         else break;
  376.     }
  377. }
  378.  
  379.  
  380. gterms()
  381. { /* create action code for < > >= or <= operators */
  382.     
  383.     while (TRUE) {
  384.         /* I hate "else if" statements */
  385.         if (equals(c_token,">")) {
  386.             c_token++;
  387.             gterm();
  388.             (void) add_action(GT);
  389.         }
  390.         else if (equals(c_token,"<")) {
  391.             c_token++;
  392.             gterm();
  393.             (void) add_action(LT);
  394.         }        
  395.         else if (equals(c_token,">=")) {
  396.             c_token++;
  397.             gterm();
  398.             (void) add_action(GE);
  399.         }
  400.         else if (equals(c_token,"<=")) {
  401.             c_token++;
  402.             gterm();
  403.             (void) add_action(LE);
  404.         }
  405.         else break;
  406.     }
  407.  
  408. }
  409.  
  410.  
  411.  
  412. hterms()
  413. { /* create action codes for + and - operators */
  414.  
  415.     while (TRUE) {
  416.             if (equals(c_token,"+")) {
  417.                 c_token++;
  418.                 hterm();
  419.                 (void) add_action(PLUS);
  420.             }
  421.             else if (equals(c_token,"-")) {
  422.                 c_token++;
  423.                 hterm();
  424.                 (void) add_action(MINUS);
  425.             }
  426.             else break;
  427.     }
  428. }
  429.  
  430.  
  431. iterms()
  432. { /* add action code for * / and % operators */
  433.  
  434.     while (TRUE) {
  435.             if (equals(c_token,"*")) {
  436.                 c_token++;
  437.                 unary();
  438.                 (void) add_action(MULT);
  439.             }
  440.             else if (equals(c_token,"/")) {
  441.                 c_token++;
  442.                 unary();
  443.                 (void) add_action(DIV);
  444.             }
  445.             else if (equals(c_token,"%")) {
  446.                 c_token++;
  447.                 unary();
  448.                 (void) add_action(MOD);
  449.             }
  450.             else break;
  451.     }
  452. }
  453.  
  454.  
  455. unary()
  456. { /* add code for unary operators */
  457.     if (equals(c_token,"!")) {
  458.         c_token++;
  459.         unary();
  460.         (void) add_action(LNOT);
  461.     }
  462.     else if (equals(c_token,"~")) {
  463.         c_token++;
  464.         unary();
  465.         (void) add_action(BNOT);
  466.     }
  467.     else if (equals(c_token,"-")) {
  468.         c_token++;
  469.         unary();
  470.         (void) add_action(UMINUS);
  471.     }
  472.     else
  473.         factor();
  474. }
  475.