1 /* $XConsortium: streval.c /main/3 1995/11/01 16:51:05 rswiston $ */
2 /***************************************************************
6 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF *
7 * AT&T BELL LABORATORIES *
8 * AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN *
9 * ACCORDANCE WITH APPLICABLE AGREEMENTS *
11 * Copyright (c) 1995 AT&T Corp. *
12 * Unpublished & Not for Publication *
13 * All Rights Reserved *
15 * The copyright notice above does not evidence any *
16 * actual or intended publication of such source code *
18 * This software was created by the *
19 * Advanced Software Technology Department *
20 * AT&T Bell Laboratories *
22 * For further information contact *
23 * {research,attmail}!dgk *
25 ***************************************************************/
27 /* : : generated by proto : : */
29 #if !defined(__PROTO__)
30 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
31 #if defined(__cplusplus)
32 #define __MANGLE__ "C"
37 #define __PROTO__(x) x
39 #define __PARAM__(n,o) n
40 #if !defined(__STDC__) && !defined(__cplusplus)
41 #if !defined(c_plusplus)
52 #define __PROTO__(x) ()
53 #define __OTORP__(x) x
54 #define __PARAM__(n,o) o
62 #if defined(__cplusplus) || defined(c_plusplus)
63 #define __VARARG__ ...
67 #if defined(__STDARG__)
68 #define __VA_START__(p,a) va_start(p,a)
70 #define __VA_START__(p,a) va_start(p)
76 #include "FEATURE/externs"
80 struct vars /* vars stacked per invocation */
82 const char* nextchr; /* next char in current expression */
83 const char* errchr; /* next char after error */
84 struct lval errmsg; /* error message text */
85 const char* errstr; /* error string */
86 unsigned char paren; /* parenthesis level */
87 char isfloat; /* set when floating number */
91 #define getchr() (*cur.nextchr++)
92 #define peekchr() (*cur.nextchr)
93 #define ungetchr() (cur.nextchr--)
95 #define pushchr(s) {struct vars old;old=cur;cur.nextchr=((char*)(s));cur.errmsg.value=0;cur.errstr=0;cur.paren=0;
96 #define popchr() cur=old;}
97 #define ERROR(msg) return(seterror(msg))
99 static struct vars cur;
100 static char noassign; /* set to skip assignment */
102 static double (*convert) __PROTO__((const char**,struct lval*,int,double));
103 /* external conversion routine */
104 static double expr __PROTO__((int)); /* subexpression evaluator */
105 static double seterror __PROTO__((const char[])); /* set error message string */
109 * evaluate an integer arithmetic expression in s
111 * (double)(*convert)(char** end, struct lval* string, int type, double value)
112 * is a user supplied conversion routine that is called when unknown
113 * chars are encountered.
114 * *end points to the part to be converted and must be adjusted by convert to
115 * point to the next non-converted character; if typ is ERRMSG then string
116 * points to an error message string
118 * NOTE: (*convert)() may call strval()
121 double strval __PARAM__((const char *s, char** end, double(*conv)(const char**,struct lval*,int,double)), (s, end, conv)) __OTORP__(const char *s; char** end; double(*conv)();){
127 if(level++ >= MAXLEVEL)
128 (void)seterror(e_recursive);
131 if (cur.errmsg.value)
133 if(cur.errstr) s = cur.errstr;
134 (void)(*convert)( &s , &cur.errmsg, ERRMSG, n);
135 cur.nextchr = cur.errchr;
138 if (end) *end = (char*)cur.nextchr;
145 * evaluate a subexpression with precedence
148 static double expr __PARAM__((register int precedence), (precedence)) __OTORP__(register int precedence;){
150 register double n, x;
152 struct lval lvalue, assignop;
156 while ((c=getchr()) && isspace(c));
171 /* unary plus or minus */
172 n = incr*expr(2*MAXPREC-1);
183 n = !expr(2*MAXPREC-1);
188 n = expr(2*MAXPREC-1);
191 ERROR(e_incompatible);
206 cur.errchr = cur.nextchr;
207 if((c=getchr()) >= sizeof(strval_states))
208 op = (c=='|' ? A_OR: (c=='^'?A_XOR:A_REG));
209 else if((op=strval_states[c])==0)
219 while((c=getchr()), isdigit(c))
220 n = (10*n) + (c-'0');
225 case A_REG: case A_DOT:
229 if(*cur.nextchr==':')
235 case A_LT: case A_GT:
243 case A_NOT: case A_COLON:
247 case A_PLUS: case A_MINUS:
248 case A_OR: case A_AND:
256 if(op && wasop++ && op!=A_LPAR)
258 /* check for assignment operation */
259 if(peekchr()== '=' && !(strval_precedence[op]&NOASSIGN))
261 if(!noassign && (!lvalue.value || precedence > 2))
269 c = (strval_precedence[op]&PRECMASK);
272 /* from here on c is the new precedence level */
273 if(lvalue.value && (op!=A_ASSIGN))
280 n = (*convert)(&cur.nextchr, &lvalue, VALUE, n);
281 if (cur.nextchr!=pos)
283 if(cur.errmsg.value = lvalue.value)
284 cur.errstr = cur.nextchr;
290 if(!(strval_precedence[op]&SEQPOINT))
294 if(invalid && op>A_ASSIGN)
298 if(strval_precedence[op]&RASSOC)
300 if(c < 2*MAXPREC && !(strval_precedence[op]&SEQPOINT))
305 if((strval_precedence[op]&NOFLOAT) && !noassign && cur.isfloat)
306 ERROR(e_incompatible);
324 char savefloat = cur.isfloat;
325 double (*fun) __PROTO__((double));
337 cur.isfloat = (fun!=floor);
339 cur.isfloat |= savefloat;
355 if(!noassign && !lvalue.value)
384 (void)seterror(e_badcolon);
388 n = (long)n | (long)x;
408 n = (long)n ^ (long)x;
415 n = (long)n & (long)x;
444 n = (long)n << (long)x;
456 n = (long)n >> (long)x;
481 n = (long)n / (long)x;
487 n = (long)n % (long)x;
498 n = (*convert)(&cur.nextchr, &lvalue, LOOKUP, n);
499 if (cur.nextchr == pos)
501 if(cur.errmsg.value = lvalue.value)
505 cur.isfloat |= lvalue.isfloat;
507 /* check for function call */
510 /* this handles ++x and --x */
511 if(!noassign && incr)
516 n = (*convert)(&cur.nextchr, &lvalue, VALUE, n);
517 if (cur.nextchr!=pos)
519 if(cur.errmsg.value = lvalue.value)
520 cur.errstr=cur.nextchr;
531 if(!noassign && assignop.value)
532 (void)(*convert)(&cur.nextchr,&assignop,ASSIGN,n+incr);
536 cur.nextchr = cur.errchr;
541 * set error message string
544 static double seterror __PARAM__((const char *msg), (msg)) __OTORP__(const char *msg;){
545 if(!cur.errmsg.value)
546 cur.errmsg.value = (char*)msg;
547 cur.errchr = cur.nextchr;
553 #ifdef _mem_name_exception
555 int matherr __PARAM__((struct exception *ep), (ep)) __OTORP__(struct exception *ep;){
563 message = e_singularity;
566 message = e_overflow;
572 error(ERROR_exit(1),message,ep->name);
575 #endif /* _mem_name_exception */