On Mon, Aug 26, 2013 at 7:41 PM, Wendy Lin <[email protected]> wrote:
> On 19 August 2013 23:24, Roland Mainz <[email protected]> wrote:
>> 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]
> Roland, one of David Korn's concerns is that ${!x.M*} patterns no longer work:
>
>>2.      The implementation is inconsistant in that ${!foo*} does not
>>        expand all integer variables starting with foo to each of the
>>        18 integer or 27 possible float suffices for integer and float
>>        respectively.
>
> Is it hard to fix this?

Yes and no. Implementing ${!x.M*} is "easy" but with the limitation
that it will return the name of the variable containing the value and
not something under the x.* naming hieracy.
This isn't technically bad since it basically returns the static
properly of the class (or type) and therefore should return a name
under the class/type hieracy (for example java does it in a similar
way, e.g. |Double x; x.getClass.MIN_EXPONENT|) and not a name under
the variable itself.

I've attached a new patch as "astksh20130814_math_constants002.diff.txt" ...

Example usage:
-- snip --
$ ksh -o nounset -c 'compound .mathconst=( compound _binary80=(float
MYVAL=nan M_PI=3.1415) _binary64=( float MYVAL=inf M_PI=3.14 )) ;
typeset -lE x=5.5 ; print "${!x.*}" ; true'
.mathconst._binary80.MYVAL .mathconst._binary80.M_PI

$ ksh -o nounset -c 'compound .mathconst=( compound _binary80=(float
MYVAL=nan M_PI=3.1415) _binary64=( float MYVAL=inf M_PI=3.14 )) ;
typeset -E x=5.5 ; print "${!x.*}" ; true'
.mathconst._binary64.MYVAL .mathconst._binary64.M_PI
-- snip --

* Notes:
- I changed the naming scheme a bit and also renamed ".sh.mathconst"
to ".mathconst" because a compound variable under ".sh" has somehow
trouble with ${!var*} constructs... and I'm a bit lazy tonight and
didn't want to dig around to squish this bug

- I'm now using the IEEE764-2008 names of the floating-point values.
Maybe someday we make typeset -E/-F/-G/-X an alias to _Binary64 and
add _Binary32/_Binary@(80|128) and later Binary16 (half float) plus
_Decimal@(32|64|128). That would require a minor reorg of the
arithmetric code, e.g. replacing the Sfdouble_t with a per-type
variable and add a per-type function lookup table (similar to how C++
does this stuff). The advantage would be that we can just plug-in more
types with little or no effort, get much better performance because we
have much less casting between floating-point and integer types and
far less |if() ... else ...| in the code (at the expense of having
more indirections) and can handle integers with maximum values greater
than the largest floating-point type can reliably accept (e.g. larger
than |LDBL_MAX_10_EXP|), e.g. an |int128_t|'s maximum value can't be
converted into a |long double| and back... you loose some digits in
that process...).

----

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-26 20:30:55.380701728 +0200
@@ -423,6 +423,8 @@
 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);
+extern const char      *sh_get_arith_constant_prefix(Shell_t *, Namval_t *);
+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-26 21:53:30.109673997 +0200
@@ -59,6 +59,98 @@
        "?",
 };
 
+const char *sh_get_arith_constant_prefix(Shell_t *shp, Namval_t *np)
+{
+       const char *prefix = NULL;
+
+       if(nv_isattr(np, NV_INTEGER))
+       {
+               /*
+                * See 
http://en.wikipedia.org/wiki/IEEE_floating_point#Basic_formats
+                * for the basic IEEE 764-2008 |_binary*| names
+                */
+               if((LDBL_MANT_DIG > 64) && (nv_isattr(np, NV_LDOUBLE) == 
NV_LDOUBLE))
+               {
+                       prefix = "_binary128";
+               }
+               else if((LDBL_MANT_DIG == 64) && (nv_isattr(np, NV_LDOUBLE) == 
NV_LDOUBLE))
+               {
+                       prefix = "_binary80";
+               }
+               else if((LDBL_MANT_DIG < 64) && (nv_isattr(np, NV_LDOUBLE) == 
NV_LDOUBLE))
+               {
+                       prefix = "_binary64";
+               }
+               else if(nv_isattr(np, NV_FLOAT) == NV_FLOAT)
+               {
+                       prefix = "_binary32";
+               }
+               else if(nv_isattr(np, NV_DOUBLE) == NV_DOUBLE)
+               {
+                       prefix = "_binary64";
+               }
+               else if(nv_isattr(np, NV_UINT64) == NV_UINT64)
+               {
+                       prefix = "uint64_t";
+               }
+               else if(nv_isattr(np, NV_UINT16) == NV_UINT16)
+               {
+                       prefix = "uint16_t";
+               }
+               else if(nv_isattr(np, NV_UNT32) == NV_UNT32)
+               {
+                       prefix = "uint32_t";
+               }
+               else if(nv_isattr(np, NV_INT64) == NV_INT64)
+               {
+                       prefix = "int64_t";
+               }
+               else if(nv_isattr(np, NV_INT16) == NV_INT16)
+               {
+                       prefix = "int16_t";
+               }
+               else if(nv_isattr(np, NV_INT32) == NV_INT32)
+               {
+                       prefix = "int32_t";
+               }
+       }
+
+       return prefix;
+}
+
+Namval_t *sh_get_arith_constant(Shell_t *shp, char *cp)
+{
+       Namval_t        *np;
+       char            *ld;
+       char            saved_ld;
+       const char      *prefix;
+
+       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);
+       prefix = sh_get_arith_constant_prefix(shp, np);
+       nv_close(np);
+
+       if (prefix)
+       {
+               char buff[256];
+               sprintf(buff, ".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 +182,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-26 20:53:37.804249920 +0200
@@ -1083,12 +1083,43 @@
        return(count);
 }
 
-static char *nextname(Mac_t *mp,const char *prefix, int len)
+static char *nextname(Mac_t *mp, char *prefix, int len)
 {
        char *cp;
        if(len==0)
        {
-               mp->nvwalk = nv_diropen((Namval_t*)0,prefix,mp->shp);
+               
+#if 1
+               Namval_t        *np;
+               char            *ld;
+               char            saved_ld;
+               const char      *acp = NULL;
+
+               mp->nvwalk = NULL;
+
+               ld = strrchr(prefix, '.');
+               if (ld)
+               {
+                       saved_ld = *ld;
+                       *ld = '\0';
+                       np = nv_open(prefix, mp->shp->var_tree, 
NV_VARNAME|NV_NOADD|NV_NOFAIL);
+                       if (np)
+                       {
+                               acp = sh_get_arith_constant_prefix(mp->shp, np);
+                               if (acp)
+                               {
+                                       char buff[256];
+                                       sprintf(buff, ".mathconst.%s.%s", acp, 
ld+1);
+                                       mp->nvwalk = nv_diropen((Namval_t*)0, 
buff, mp->shp);
+                               }
+                               nv_close(np);
+                       }
+                       *ld = saved_ld;
+               }
+
+               if (!acp && !mp->nvwalk)
+                       mp->nvwalk = nv_diropen((Namval_t*)0,prefix,mp->shp);
+#endif
                return((char*)mp->nvwalk);
        }
        if(!(cp=nv_dirnext(mp->nvwalk)))
@@ -1349,6 +1380,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