14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*8462SApril.Chin@Sun.COM *          Copyright (c) 1982-2008 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
7*8462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                  David Korn <dgk@research.att.com>                   *
184887Schin *                                                                      *
194887Schin ***********************************************************************/
204887Schin #pragma prototyped
214887Schin #ifndef SEQPOINT
224887Schin /*
234887Schin  * D. G. Korn
244887Schin  *
254887Schin  * arithmetic expression evaluator
264887Schin  */
274887Schin 
284887Schin /* The following only is needed for const */
294887Schin #include	<ast.h>
304887Schin #include	<math.h>
314887Schin #if _AST_VERSION >= 20030127L
324887Schin #   include	<ast_float.h>
334887Schin #endif
344887Schin 
354887Schin #if _ast_fltmax_double
364887Schin #define LDBL_LLONG_MAX		DBL_LLONG_MAX
374887Schin #define LDBL_ULLONG_MAX		DBL_ULLONG_MAX
384887Schin #define LDBL_LLONG_MIN		DBL_LLONG_MIN
394887Schin #endif
404887Schin 
414887Schin #ifndef LDBL_LLONG_MAX
424887Schin #   ifdef LLONG_MAX
434887Schin #	define LDBL_LLONG_MAX	((Sfdouble_t)LLONG_MAX)
444887Schin #   else
454887Schin #	ifdef LLONG_MAX
464887Schin #	   define LDBL_LLONG_MAX	((Sfdouble_t)LLONG_MAX)
474887Schin #	else
484887Schin #	   define LDBL_LLONG_MAX	((Sfdouble_t)((((Sflong_t)1) << (8*sizeof(Sflong_t)-1)) -1 ))
494887Schin #	endif
504887Schin #   endif
514887Schin #endif
524887Schin #ifndef LDBL_ULLONG_MAX
534887Schin #   ifdef ULLONG_MAX
544887Schin #	define LDBL_ULLONG_MAX		((Sfdouble_t)ULLONG_MAX)
554887Schin #   else
564887Schin #	define LDBL_ULLONG_MAX		(2.*((Sfdouble_t)LDBL_LLONG_MAX))
574887Schin #   endif
584887Schin #endif
594887Schin #ifndef LDBL_LLONG_MIN
604887Schin #   ifdef LLONG_MIN
614887Schin #	define LDBL_LLONG_MIN		((Sfdouble_t)LLONG_MIN)
624887Schin #   else
634887Schin #	define LDBL_LLONG_MIN		(-LDBL_LLONG_MAX)
644887Schin #   endif
654887Schin #endif
664887Schin #ifndef LDBL_DIG
674887Schin #   define LDBL_DIG DBL_DIG
684887Schin #endif
694887Schin 
704887Schin struct lval
714887Schin {
724887Schin 	char		*value;
734887Schin 	Sfdouble_t	(*fun)(Sfdouble_t,...);
744887Schin 	const char	*expr;
754887Schin 	short		flag;
764887Schin 	char		isfloat;
774887Schin 	char		nargs;
784887Schin 	short		emode;
794887Schin 	short		level;
804887Schin 	short		elen;
814887Schin };
824887Schin 
834887Schin struct mathtab
844887Schin {
854887Schin 	char		fname[16];
864887Schin 	Sfdouble_t	(*fnptr)(Sfdouble_t,...);
874887Schin };
884887Schin 
894887Schin typedef struct _arith_
904887Schin {
914887Schin 	unsigned char	*code;
924887Schin 	const char	*expr;
934887Schin 	Sfdouble_t	(*fun)(const char**,struct lval*,int,Sfdouble_t);
944887Schin 	short		size;
954887Schin 	short		staksize;
964887Schin 	short		emode;
974887Schin 	short		elen;
984887Schin } Arith_t;
994887Schin #define ARITH_COMP	04	/* set when compile separate from execute */
1004887Schin 
1014887Schin #define MAXPREC		15	/* maximum precision level */
1024887Schin #define SEQPOINT	0200	/* sequence point */
1034887Schin #define NOASSIGN	0100	/* assignment legal with this operator */
1044887Schin #define RASSOC		040	/* right associative */
1054887Schin #define NOFLOAT		020	/* illegal with floating point */
1064887Schin #define PRECMASK	017	/* precision bit mask */
1074887Schin 
1084887Schin #define A_EOF		1
1094887Schin #define A_NEQ		2
1104887Schin #define A_NOT		3
1114887Schin #define A_MOD		4
1124887Schin #define A_ANDAND	5
1134887Schin #define A_AND		6
1144887Schin #define A_LPAR		7
1154887Schin #define A_RPAR		8
1164887Schin #define A_POW		9
1174887Schin #define A_TIMES		10
1184887Schin #define A_PLUSPLUS	11
1194887Schin #define A_PLUS		12
1204887Schin #define A_COMMA		13
1214887Schin #define A_MINUSMINUS	14
1224887Schin #define A_MINUS		15
1234887Schin #define A_DIV		16
1244887Schin #define A_LSHIFT	17
1254887Schin #define A_LE		18
1264887Schin #define A_LT		19
1274887Schin #define A_EQ		20
1284887Schin #define A_ASSIGN	21
1294887Schin #define A_COLON		22
1304887Schin #define A_RSHIFT	23
1314887Schin #define A_GE		24
1324887Schin #define A_GT		25
1334887Schin #define A_QCOLON	26
1344887Schin #define A_QUEST		27
1354887Schin #define A_XOR		28
1364887Schin #define A_OROR		29
1374887Schin #define A_OR		30
1384887Schin #define A_TILDE		31
1394887Schin #define A_REG		32
1404887Schin #define A_DIG		33
1414887Schin #define A_INCR		34
1424887Schin #define A_DECR  	35
1434887Schin #define A_PUSHV 	36
1444887Schin #define A_PUSHL 	37
1454887Schin #define A_PUSHN 	38
1464887Schin #define A_PUSHF 	39
1474887Schin #define A_STORE 	40
1484887Schin #define A_POP   	41
1494887Schin #define A_SWAP  	42
1504887Schin #define A_UMINUS	43
1514887Schin #define A_JMPZ  	44
1524887Schin #define A_JMPNZ		45
1534887Schin #define A_JMP		46
1544887Schin #define A_CALL0		47
1554887Schin #define A_CALL1		48
1564887Schin #define A_CALL2		49
1574887Schin #define A_CALL3		50
1584887Schin #define A_DOT		51
1594887Schin #define A_LIT		52
1604887Schin #define A_NOTNOT        53
1614887Schin 
1624887Schin 
1634887Schin /* define error messages */
1644887Schin extern const unsigned char	strval_precedence[35];
1654887Schin extern const char		strval_states[64];
1664887Schin extern const char		e_moretokens[];
1674887Schin extern const char		e_argcount[];
1684887Schin extern const char		e_paren[];
1694887Schin extern const char		e_badnum[];
1704887Schin extern const char		e_badcolon[];
1714887Schin extern const char		e_recursive[];
1724887Schin extern const char		e_divzero[];
1734887Schin extern const char		e_synbad[];
1744887Schin extern const char		e_notlvalue[];
1754887Schin extern const char		e_function[];
1764887Schin extern const char		e_questcolon[];
1774887Schin extern const char		e_incompatible[];
1784887Schin extern const char		e_domain[];
1794887Schin extern const char		e_overflow[];
1804887Schin extern const char		e_singularity[];
1814887Schin extern const char		e_dict[];
1824887Schin extern const char		e_charconst[];
1834887Schin extern const struct 		mathtab shtab_math[];
1844887Schin 
1854887Schin /* function code for the convert function */
1864887Schin 
1874887Schin #define LOOKUP	0
1884887Schin #define ASSIGN	1
1894887Schin #define VALUE	2
1904887Schin #define MESSAGE	3
1914887Schin 
1924887Schin extern Sfdouble_t strval(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int);
1934887Schin extern Arith_t *arith_compile(const char*,char**,Sfdouble_t(*)(const char**,struct lval*,int,Sfdouble_t),int);
1944887Schin extern Sfdouble_t arith_exec(Arith_t*);
1954887Schin #endif /* !SEQPOINT */
196