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