da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * D. G. Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * arithmetic expression evaluator
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this version compiles the expression onto a stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and has a separate executor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following are used with tokenbits() macro
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define T_NOFLOAT 0x80 /* non floating point operator */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define pow2size(x) ((x)<=2?2:(x)<=4?4:(x)<=8?8:(x)<=16?16:(x)<=32?32:64)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define stakpush(v,val,type) ((((v)->offset=round(staktell(),pow2size(sizeof(type)))),\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define roundptr(ep,cp,type) (((unsigned char*)(ep))+round(cp-((unsigned char*)(ep)),pow2size(sizeof(type))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *nextchr; /* next char in current expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t (*convert)(const char**,struct lval*,int,Sfdouble_t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef Sfdouble_t (*Math_2f_f)(Sfdouble_t,Sfdouble_t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef int (*Math_2i_f)(Sfdouble_t,Sfdouble_t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef Sfdouble_t (*Math_3f_f)(Sfdouble_t,Sfdouble_t,Sfdouble_t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef int (*Math_3i_f)(Sfdouble_t,Sfdouble_t,Sfdouble_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((c)=='|'?A_OR:((c)=='^'?A_XOR:((c)=='~'?A_TILDE:A_REG))):\
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define getop(c) (isdigit(c)?A_DIG:((c==' '||c=='\t'||c=='\n'||c=='"')?0: \
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (c=='.'?A_DOT:(c=='~'?A_TILDE:A_REG)))))))))))))))))))))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define seterror(v,msg) _seterror(v,ERROR_dictionary(msg))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set error message string and return(0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void arith_error(const char *message,const char *expr, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = u / 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (u & 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = (Sfdouble_t*)stakalloc(ep->staksize*(sizeof(Sfdouble_t)+1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c = *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==1 || ((c&T_BINARY) && (c&T_OP)!=A_MOD && tp[-1]==1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(short*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(short*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp += sizeof(short);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This returns operator tokens or A_REG or A_NUM
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(sh.decomma && (c=peekchr(vp))>='0' && c<='9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * evaluate a subexpression with precedence
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int expr(register struct vars *vp,register int precedence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for assignment operation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(peekchr(vp)== '=' && !(strval_precedence[op]&NOASSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* from here on c is the new precedence level */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c < (2*MAXPREC+1)) && !(strval_precedence[op]&SEQPOINT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* character constants */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* posix allows the trailing ' to be optional */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for function call */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinArith_t *arith_compile(const char *string,char **last,Sfdouble_t(*fun)(const char**,struct lval*,int,Sfdouble_t),int emode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * evaluate an integer arithmetic expression in s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (Sfdouble_t)(*convert)(char** end, struct lval* string, int type, Sfdouble_t value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is a user supplied conversion routine that is called when unknown
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * chars are encountered.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * *end points to the part to be converted and must be adjusted by convert to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * point to the next non-converted character; if typ is MESSAGE then string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * points to an error message string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: (*convert)() may call strval()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t strval(const char *s,char **end,Sfdouble_t(*conv)(const char**,struct lval*,int,Sfdouble_t),int emode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define extern __EXPORT__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _mem_name_exception */