On Mon, Aug 19, 2013 at 8:10 PM, David Korn <[email protected]> wrote:
> cc: [email protected]
> Subject: Re: Re: [ast-developers] float i; (( i.MAX, i.MIN, i.EPSILON )) 
> constants?
> --------
>> Erm... doesn't this just require a small modification of the
>> arithmetic engine (I don't know how to do the same for a plain
>> ${i.MAX}), e.g. do a type-based (technically we "only" have six types
>> - three integer and three float) lookup of the matching constant value
>> if an integer name is followed by a '.' ?
>
> First of all there are 9 types, 3 float, 3 integer, and 3 unsigned.
>
> Secondly, it is much simpler of i.MAX only appears in arithmetic
> expressions and cannot be used as ${i.MAX} because ${i.MAX} is
> more complex because it needs to work with ${i.MAX op string}
> and ${op i.MAX} as well.
>
> I am not even sure how to implement ${!i.M*} given the current
> architecture.
>
> Maybe I should restrict b.true to arithmetic expressions only.
> Programs that want ${i.MAX} can do $((i.MAX)).
>
> Anyway, I have enough bug reports to keep me busy for now.

Attached (as "astksh20130814_math_constants001.diff.txt") is a
prototype patch which allows constants to be defined like this:
-- snip --
$ ksh -o nounset -c 'compound .sh.mathconst=( float LDBL_M_PI=3.14 ) ;
float x=5.5 ; print $((x.M_PI)) ${x.M_PI}'
3.14 3.14
-- snip --

AFAIK we need the following constants (mostly derived from X/OPEN and
my own math code):
1. min/max/etc. limits:
-- snip --
# integer for $((i.MIN)) and $((i.MAX))
SHRT_MIN
SHRT_MAX
USHRT_MAX
INT_MIN
INT_MAX
UINT_MAX
LONG_MAX
LONG_MAX
LONG_MIN
ULONG_MAX
ULONG_MAX

# float for $((i.MANT_DIG , i.MIN_EXP , i.MIN_10_EXP, i.MAX_EXP ,
i.MAX_10_EXP , i.MIN , i.MAX, i.EPSILON , i.DECIMAL_DIG)
FLT_MANT_DIG
DBL_MANT_DIG
LDBL_MANT_DIG
FLT_MIN_EXP
DBL_MIN_EXP
LDBL_MIN_EXP
FLT_MIN_10_EXP
DBL_MIN_10_EXP
LDBL_MIN_10_EXP
FLT_MAX_EXP
DBL_MAX_EXP
LDBL_MAX_EXP
FLT_MAX_10_EXP
DBL_MAX_10_EXP
LDBL_MAX_10_EXP
FLT_MAX
DBL_MAX
LDBL_MAX
FLT_EPSILON
DBL_EPSILON
LDBL_EPSILON
FLT_MIN
DBL_MIN
LDBL_MIN
FLT_DECIMAL_DIG
DBL_DECIMAL_DIG
LDBL_DECIMAL_DIG
-- snip --

2. constants (need to be per-type to get round-offs correct):
-- snip --
M_E           2.718281828459045235360287471352662498L /* e */
M_LOG2E       1.442695040888963407359924681001892137L /* log_2 e */
M_LOG10E      0.434294481903251827651128918916605082L /* log_10 e */
M_LN2         0.693147180559945309417232121458176568L /* log_e 2 */
M_LN10        2.302585092994045684017991454684364208L /* log_e 10 */
M_PI          3.141592653589793238462643383279502884L /* pi */
M_PI_2        1.570796326794896619231321691639751442L /* pi/2 */
M_PI_4        0.785398163397448309615660845819875721L /* pi/4 */
M_1_PI        0.318309886183790671537767526745028724L /* 1/pi */
M_2_PI        0.636619772367581343075535053490057448L /* 2/pi */
M_2_SQRTPI    1.128379167095512573896158903121545172L /* 2/sqrt(pi) */
M_SQRT2       1.414213562373095048801688724209698079L /* sqrt(2) */
M_SQRT1_2     0.707106781186547524400844362104849039L /* 1/sqrt(2) */
-- snip --
On a 2nd thought... maybe we should define these constants via C99
hexfloat to make sure the last bits are OK...

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) [email protected]
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL +49 641 3992797
 (;O/ \/ \O;)
diff -r -u original/src/cmd/ksh93/include/defs.h 
build_numconstants/src/cmd/ksh93/include/defs.h
--- src/cmd/ksh93/include/defs.h        2013-08-12 16:31:56.000000000 +0200
+++ src/cmd/ksh93/include/defs.h        2013-08-19 22:24:21.258321372 +0200
@@ -423,6 +423,7 @@
 extern char            *sh_mactrim(Shell_t*,char*,int);
 extern int             sh_macexpand(Shell_t*,struct argnod*,struct 
argnod**,int);
 extern bool            sh_macfun(Shell_t*,const char*,int);
+Namval_t               *sh_get_arith_constant(Shell_t *, char *);
 extern void            sh_machere(Shell_t*,Sfio_t*, Sfio_t*, char*);
 extern void            *sh_macopen(Shell_t*);
 extern char            *sh_macpat(Shell_t*,struct argnod*,int);
diff -r -u original/src/cmd/ksh93/sh/arith.c 
build_numconstants/src/cmd/ksh93/sh/arith.c
--- src/cmd/ksh93/sh/arith.c    2013-08-12 16:43:47.000000000 +0200
+++ src/cmd/ksh93/sh/arith.c    2013-08-19 22:29:29.156356354 +0200
@@ -59,6 +59,79 @@
        "?",
 };
 
+Namval_t *sh_get_arith_constant(Shell_t *shp, char *cp)
+{
+       Namval_t        *np;
+       char            *ld;
+       char            saved_ld;
+       const char      *prefix = NULL;
+
+       ld = strrchr(cp, '.');
+       if (!ld)
+               return (0);
+       saved_ld = *ld;
+       *ld = '\0';
+       np = nv_open(cp, shp->var_tree, NV_VARNAME|NV_NOADD|NV_NOFAIL);
+       *ld = saved_ld;
+       if (!np)
+               return (NULL);
+
+       if(nv_isattr(np, NV_INTEGER))
+       {
+               if(nv_isattr(np, NV_LDOUBLE) == NV_LDOUBLE)
+               {
+                       prefix = "LDBL";
+               }
+               else if(nv_isattr(np, NV_FLOAT) == NV_FLOAT)
+               {
+                       prefix = "FLT";
+               }
+               else if(nv_isattr(np, NV_DOUBLE) == NV_DOUBLE)
+               {
+                       prefix = "DBL";
+               }
+               else if(nv_isattr(np, NV_UINT64) == NV_UINT64)
+               {
+                       prefix = "UINT64";
+               }
+               else if(nv_isattr(np, NV_UINT16) == NV_UINT16)
+               {
+                       prefix = "UINT16";
+               }
+               else if(nv_isattr(np, NV_UNT32) == NV_UNT32)
+               {
+                       prefix = "UINT32";
+               }
+               else if(nv_isattr(np, NV_INT64) == NV_INT64)
+               {
+                       prefix = "INT64";
+               }
+               else if(nv_isattr(np, NV_INT16) == NV_INT16)
+               {
+                       prefix = "INT16";
+               }
+               else if(nv_isattr(np, NV_INT32) == NV_INT32)
+               {
+                       prefix = "INT32";
+               }
+       }
+
+       nv_close(np);
+
+       if (prefix)
+       {
+               char buff[256];
+               sprintf(buff, ".sh.mathconst.%s_%s", prefix, ld+1);
+               np = nv_open(buff, shp->var_tree 
,NV_VARNAME|NV_NOADD|NV_NOFAIL);
+       }
+       else
+       {
+               np = NULL;
+       }
+
+       return (np);
+}
+
 static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int 
assign)
 {
        register int flag = lvalue->flag;
@@ -90,8 +163,14 @@
                        cp[flag] = d;
                        return(&FunNode);
                }
-               if(!np && assign)
-                       np = nv_open(cp,shp->var_tree,assign|NV_VARNAME);
+               if (!np)
+               {
+                       if (assign)
+                               np = 
nv_open(cp,shp->var_tree,assign|NV_VARNAME);
+                       else
+                               np = sh_get_arith_constant(shp, cp);
+               }
+                       
                cp[flag] = d;
                if(!np)
                        return(0);
diff -r -u original/src/cmd/ksh93/sh/macro.c 
build_numconstants/src/cmd/ksh93/sh/macro.c
--- src/cmd/ksh93/sh/macro.c    2013-07-31 22:08:40.000000000 +0200
+++ src/cmd/ksh93/sh/macro.c    2013-08-19 22:24:40.206242082 +0200
@@ -1349,6 +1349,11 @@
                                fcmbget(&LEN);
                                return(true);
                        }
+
+                       if(!np && (flag&NV_NOADD))
+                       {
+                               np = sh_get_arith_constant(mp->shp, id);
+                       }
                }
                if(np && (flag&NV_NOADD) && nv_isnull(np))
                {
_______________________________________________
ast-developers mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-developers

Reply via email to