zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <pws@cambridgesiliconradio.com>
To: zsh-workers@sunsite.auc.dk (Zsh hackers list)
Subject: PATCH: output base for math evals
Date: Fri, 19 May 2000 13:02:01 +0100	[thread overview]
Message-ID: <0FUT00JIN2RCPB@la-la.cambridgesiliconradio.com> (raw)

Here's a feature I've wanted for ages, but it never occurred to me before
how to do it.  It's reasonably self contained and doesn't affect any
currently valid syntax, but even so if anyone objects either on the grounds
that it should go in later or that it's fundamentally silly I'll leave it
out.

The (formerly invalid) syntax [#<base>], e.g. [#16], specifies an output
base in a math expression.  It has no precedence and hence is ignored for
syntactic purposes.  For example,

% print $(( [#16] 255 + 14 ))
16#10D

See the manual entry for further details --- note that it doesn't affect
the way existing numeric parameters are handled, only scalars and
parameters implicitly typed by the expression itself.

Note that it also has the effect of converting floating point numbers
(again, explicitly typed parameters are not affected and the conversion is
only performed on output):

% print $(( [#16] 2.5 + 24.5 ))
16#1B

This seemed logical, but it's the one point where I had doubts on the
natural way of doing things.

(This is inspired by the fact that my boss insists on defining numbers in
decimal in header files but the debugger insists on outputting everything
in hex.)

Index: Doc/Zsh/arith.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/arith.yo,v
retrieving revision 1.2
diff -u -r1.2 arith.yo
--- Doc/Zsh/arith.yo	2000/05/14 22:08:41	1.2
+++ Doc/Zsh/arith.yo	2000/05/19 11:50:30
@@ -43,6 +43,28 @@
 base 10 is used.  For backwards compatibility the form
 `tt([)var(base)tt(])var(n)' is also accepted.
 
+It is also possible to specify a base to be used for output in the form
+`tt([#)var(base)tt(])', for example `tt([#16])'.  This is used when
+outputting arithmetical substitutions or when assigning to scalar
+parameters, but an explicitly defined integer or floating point parameter
+will not be affected.  If an integer variable is implicitly defined by an
+arithmetic expression, any base specified in this way will be set as the
+variable's output arithmetic base as if the option `tt(-i) var(base)' to
+the tt(typeset) builtin had been used.  The expression has no precedence
+and if it occurs more than once in a mathematical expression, the last
+encountered is used.  For clarity it is recommended that it appear at the
+beginning of an expression.  As an example:
+
+example(typeset -i 16 y
+print $(( [#8] x = 32, y = 32 ))
+print $x $y)
+
+outputs first `tt(8#40)', the rightmost value in the given output base, and
+then `tt(8#40 16#20)', because tt(y) has been explicitly declared to
+have output base 16, while tt(x) (assuming it does not already exist) is
+implicitly typed by the arithmetic evaluation, where it acquires the output
+base 8.
+
 Floating point constants are recognized by the presence of a decimal point
 or an exponent.  The decimal point may be the first character of the
 constant, but the exponent character tt(e) or tt(E) may not, as it will be
Index: Src/math.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/math.c,v
retrieving revision 1.4
diff -u -r1.4 math.c
--- Src/math.c	2000/05/15 18:48:21	1.4
+++ Src/math.c	2000/05/19 11:50:30
@@ -186,6 +186,8 @@
 /* 50 */  LR|OP_OPF, RL|OP_E2, LR|OP_OPF
 };
 
+/**/
+int outputradix;
 
 /**/
 static int
@@ -340,12 +342,22 @@
 	    return EOI;
 	case '[':
 	    {
-		int base = zstrtol(ptr, &ptr, 10);
+		int base, setradix = 0;
+		if (*ptr == '#') {
+		    ptr++;
+		    setradix = 1;
+		}
+		base = zstrtol(ptr, &ptr, 10);
 
 		if (*ptr == ']')
 		    ptr++;
-		yyval.u.l = zstrtol(ptr, &ptr, lastbase = base);
-		return NUM;
+		if (setradix)
+		    outputradix = base;
+		else {
+		    yyval.u.l = zstrtol(ptr, &ptr, lastbase = base);
+		    return NUM;
+		}
+		break;
 	    }
 	case ' ':
 	case '\t':
@@ -934,6 +946,7 @@
     char *junk;
     mnumber x;
     int xmtok = mtok;
+    outputradix = 0;
 
     if (!*s) {
 	x.type = MN_INTEGER;
Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.9
diff -u -r1.9 params.c
--- Src/params.c	2000/05/10 23:54:26	1.9
+++ Src/params.c	2000/05/19 11:50:31
@@ -1577,9 +1577,11 @@
     switch (PM_TYPE(v->pm->flags)) {
     case PM_SCALAR:
     case PM_ARRAY:
-	if (val.type & MN_INTEGER)
-	    convbase(p = buf, val.u.l, 0);
-	else
+	if ((val.type & MN_INTEGER) || outputradix) {
+	    if (!(val.type & MN_INTEGER))
+		val.u.l = (zlong) val.u.d;
+	    convbase(p = buf, val.u.l, outputradix);
+	} else
 	    p = convfloat(val.u.d, 0, 0, NULL);
 	setstrvalue(v, ztrdup(p));
 	break;
@@ -1909,9 +1911,10 @@
 	pm = createparam(t, (val.type & MN_INTEGER) ? PM_INTEGER
 			 : PM_FFLOAT);
 	DPUTS(!pm, "BUG: parameter not created");
-	if (val.type & MN_INTEGER)
+	if (val.type & MN_INTEGER) {
+	    pm->ct = outputradix;
 	    pm->u.val = val.u.l;
-	else
+	} else
 	    pm->u.dval = val.u.d;
 	return pm;
     }
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.5
diff -u -r1.5 subst.c
--- Src/subst.c	2000/05/15 14:59:01	1.5
+++ Src/subst.c	2000/05/19 11:50:31
@@ -1964,10 +1964,13 @@
 
     singsub(&a);
     v = matheval(a);
-    if (v.type & MN_FLOAT)
+    if ((v.type & MN_FLOAT) && !outputradix)
 	b = convfloat(v.u.d, 0, 0, NULL);
-    else
-	convbase(buf, v.u.l, 0);
+    else {
+	if (v.type & MN_FLOAT)
+	    v.u.l = (zlong) v.u.d;
+	convbase(buf, v.u.l, outputradix);
+    }
     t = *bptr = (char *) hcalloc(strlen(*bptr) + strlen(b) + 
 				 strlen(rest) + 1);
     t--;

-- 
Peter Stephenson <pws@cambridgesiliconradio.com>
Cambridge Silicon Radio, Unit 300, Science Park, Milton Road,
Cambridge, CB4 0XL, UK                          Tel: +44 (0)1223 392070


                 reply	other threads:[~2000-05-19 12:03 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0FUT00JIN2RCPB@la-la.cambridgesiliconradio.com \
    --to=pws@cambridgesiliconradio.com \
    --cc=zsh-workers@sunsite.auc.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).