1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * David Korn <dgk@research.att.com> * 18*4887Schin * * 19*4887Schin ***********************************************************************/ 20*4887Schin #pragma prototyped 21*4887Schin #ifndef SEQPOINT 22*4887Schin /* 23*4887Schin * D. G. Korn 24*4887Schin * 25*4887Schin * arithmetic expression evaluator 26*4887Schin */ 27*4887Schin 28*4887Schin /* The following only is needed for const */ 29*4887Schin #include <ast.h> 30*4887Schin #include <math.h> 31*4887Schin #if _AST_VERSION >= 20030127L 32*4887Schin # include <ast_float.h> 33*4887Schin #endif 34*4887Schin 35*4887Schin #if _ast_fltmax_double 36*4887Schin #define LDBL_LLONG_MAX DBL_LLONG_MAX 37*4887Schin #define LDBL_ULLONG_MAX DBL_ULLONG_MAX 38*4887Schin #define LDBL_LLONG_MIN DBL_LLONG_MIN 39*4887Schin #endif 40*4887Schin 41*4887Schin #ifndef LDBL_LLONG_MAX 42*4887Schin # ifdef LLONG_MAX 43*4887Schin # define LDBL_LLONG_MAX ((Sfdouble_t)LLONG_MAX) 44*4887Schin # else 45*4887Schin # ifdef LLONG_MAX 46*4887Schin # define LDBL_LLONG_MAX ((Sfdouble_t)LLONG_MAX) 47*4887Schin # else 48*4887Schin # define LDBL_LLONG_MAX ((Sfdouble_t)((((Sflong_t)1) << (8*sizeof(Sflong_t)-1)) -1 )) 49*4887Schin # endif 50*4887Schin # endif 51*4887Schin #endif 52*4887Schin #ifndef LDBL_ULLONG_MAX 53*4887Schin # ifdef ULLONG_MAX 54*4887Schin # define LDBL_ULLONG_MAX ((Sfdouble_t)ULLONG_MAX) 55*4887Schin # else 56*4887Schin # define LDBL_ULLONG_MAX (2.*((Sfdouble_t)LDBL_LLONG_MAX)) 57*4887Schin # endif 58*4887Schin #endif 59*4887Schin #ifndef LDBL_LLONG_MIN 60*4887Schin # ifdef LLONG_MIN 61*4887Schin # define LDBL_LLONG_MIN ((Sfdouble_t)LLONG_MIN) 62*4887Schin # else 63*4887Schin # define LDBL_LLONG_MIN (-LDBL_LLONG_MAX) 64*4887Schin # endif 65*4887Schin #endif 66*4887Schin #ifndef LDBL_DIG 67*4887Schin # define LDBL_DIG DBL_DIG 68*4887Schin #endif 69*4887Schin 70*4887Schin struct lval 71*4887Schin { 72*4887Schin char *value; 73*4887Schin Sfdouble_t (*fun)(Sfdouble_t,...); 74*4887Schin const char *expr; 75*4887Schin short flag; 76*4887Schin char isfloat; 77*4887Schin char nargs; 78*4887Schin short emode; 79*4887Schin short level; 80*4887Schin short elen; 81*4887Schin }; 82*4887Schin 83*4887Schin struct mathtab 84*4887Schin { 85*4887Schin char fname[16]; 86*4887Schin Sfdouble_t (*fnptr)(Sfdouble_t,...); 87*4887Schin }; 88*4887Schin 89*4887Schin typedef struct _arith_ 90*4887Schin { 91*4887Schin unsigned char *code; 92*4887Schin const char *expr; 93*4887Schin Sfdouble_t (*fun)(const char**,struct lval*,int,Sfdouble_t); 94*4887Schin short size; 95*4887Schin short staksize; 96*4887Schin short emode; 97*4887Schin short elen; 98*4887Schin } Arith_t; 99*4887Schin #define ARITH_COMP 04 /* set when compile separate from execute */ 100*4887Schin 101*4887Schin #define MAXPREC 15 /* maximum precision level */ 102*4887Schin #define SEQPOINT 0200 /* sequence point */ 103*4887Schin #define NOASSIGN 0100 /* assignment legal with this operator */ 104*4887Schin #define RASSOC 040 /* right associative */ 105*4887Schin #define NOFLOAT 020 /* illegal with floating point */ 106*4887Schin #define PRECMASK 017 /* precision bit mask */ 107*4887Schin 108*4887Schin #define A_EOF 1 109*4887Schin #define A_NEQ 2 110*4887Schin #define A_NOT 3 111*4887Schin #define A_MOD 4 112*4887Schin #define A_ANDAND 5 113*4887Schin #define A_AND 6 114*4887Schin #define A_LPAR 7 115*4887Schin #define A_RPAR 8 116*4887Schin #define A_POW 9 117*4887Schin #define A_TIMES 10 118*4887Schin #define A_PLUSPLUS 11 119*4887Schin #define A_PLUS 12 120*4887Schin #define A_COMMA 13 121*4887Schin #define A_MINUSMINUS 14 122*4887Schin #define A_MINUS 15 123*4887Schin #define A_DIV 16 124*4887Schin #define A_LSHIFT 17 125*4887Schin #define A_LE 18 126*4887Schin #define A_LT 19 127*4887Schin #define A_EQ 20 128*4887Schin #define A_ASSIGN 21 129*4887Schin #define A_COLON 22 130*4887Schin #define A_RSHIFT 23 131*4887Schin #define A_GE 24 132*4887Schin #define A_GT 25 133*4887Schin #define A_QCOLON 26 134*4887Schin #define A_QUEST 27 135*4887Schin #define A_XOR 28 136*4887Schin #define A_OROR 29 137*4887Schin #define A_OR 30 138*4887Schin #define A_TILDE 31 139*4887Schin #define A_REG 32 140*4887Schin #define A_DIG 33 141*4887Schin #define A_INCR 34 142*4887Schin #define A_DECR 35 143*4887Schin #define A_PUSHV 36 144*4887Schin #define A_PUSHL 37 145*4887Schin #define A_PUSHN 38 146*4887Schin #define A_PUSHF 39 147*4887Schin #define A_STORE 40 148*4887Schin #define A_POP 41 149*4887Schin #define A_SWAP 42 150*4887Schin #define A_UMINUS 43 151*4887Schin #define A_JMPZ 44 152*4887Schin #define A_JMPNZ 45 153*4887Schin #define A_JMP 46 154*4887Schin #define A_CALL0 47 155*4887Schin #define A_CALL1 48 156*4887Schin #define A_CALL2 49 157*4887Schin #define A_CALL3 50 158*4887Schin #define A_DOT 51 159*4887Schin #define A_LIT 52 160*4887Schin #define A_NOTNOT 53 161*4887Schin 162*4887Schin 163*4887Schin /* define error messages */ 164*4887Schin extern const unsigned char strval_precedence[35]; 165*4887Schin extern const char strval_states[64]; 166*4887Schin extern const char e_moretokens[]; 167*4887Schin extern const char e_argcount[]; 168*4887Schin extern const char e_paren[]; 169*4887Schin extern const char e_badnum[]; 170*4887Schin extern const char e_badcolon[]; 171*4887Schin extern const char e_recursive[]; 172*4887Schin extern const char e_divzero[]; 173*4887Schin extern const char e_synbad[]; 174*4887Schin extern const char e_notlvalue[]; 175*4887Schin extern const char e_function[]; 176*4887Schin extern const char e_questcolon[]; 177*4887Schin extern const char e_incompatible[]; 178*4887Schin extern const char e_domain[]; 179*4887Schin extern const char e_overflow[]; 180*4887Schin extern const char e_singularity[]; 181*4887Schin extern const char e_dict[]; 182*4887Schin extern const char e_charconst[]; 183*4887Schin extern const struct mathtab shtab_math[]; 184*4887Schin 185*4887Schin /* function code for the convert function */ 186*4887Schin 187*4887Schin #define LOOKUP 0 188*4887Schin #define ASSIGN 1 189*4887Schin #define VALUE 2 190*4887Schin #define MESSAGE 3 191*4887Schin 192*4887Schin extern Sfdouble_t strval(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int); 193*4887Schin extern Arith_t *arith_compile(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int); 194*4887Schin extern Sfdouble_t arith_exec(Arith_t*); 195*4887Schin #endif /* !SEQPOINT */ 196