summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-03-21 07:59:24 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-03-21 07:59:24 -0700
commite7d17c45b37c145eff23a8fc6e602346f9b65fe3 (patch)
tree4707fff0bfd23dea474923bf31edac2e56511626 /stream.c
parente399295ee017de3fe490c4c952701c95baa019e9 (diff)
downloadtxr-e7d17c45b37c145eff23a8fc6e602346f9b65fe3.tar.gz
txr-e7d17c45b37c145eff23a8fc6e602346f9b65fe3.tar.bz2
txr-e7d17c45b37c145eff23a8fc6e602346f9b65fe3.zip
* arith.c (neg): Floating-point support.
* parser.l: FLO and FLODOT cases had to be reordered because the lex trailing context counts as part of the match length, causing 3.0 to be matched as three characters with 0 as the trailing context. The cases are split up to eliminate a flex warning. * stream.c (vformat): Support bignum in floating point conversion. Bugfixes: floating point conversion was accessing obj->fl.n instead of using n. Changed some if/else ladders to switches.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/stream.c b/stream.c
index f9b1eb25..6110e1d6 100644
--- a/stream.c
+++ b/stream.c
@@ -1122,18 +1122,21 @@ val vformat(val stream, val fmtstr, va_list vl)
{
double n;
- if (bignump(obj))
- uw_throwf(error_s, lit("format: ~s: bignum to float "
- "conversion unsupported\n"), obj, nao);
-
- if (fixnump(obj))
+ switch (type(obj)) {
+ case BGNUM:
+ obj = flo_int(obj);
+ /* fallthrough */
+ case FLNUM:
+ n = c_flo(obj);
+ break;
+ case NUM:
n = (double) c_num(obj);
- else if (floatp(obj))
- n = obj->fl.n;
- else
+ break;
+ default:
uw_throwf(error_s, lit("format: ~~~a conversion requires "
"numeric arg: ~s given\n"),
chr(ch), obj, nao);
+ }
/* guard against num_buf overflow */
if (precision > 128)
@@ -1141,9 +1144,9 @@ val vformat(val stream, val fmtstr, va_list vl)
num(precision), nao);
if (ch == 'e')
- sprintf(num_buf, "%.*e", precision, obj->fl.n);
+ sprintf(num_buf, "%.*e", precision, n);
else
- sprintf(num_buf, "%.*f", precision, obj->fl.n);
+ sprintf(num_buf, "%.*f", precision, n);
precision = 0;
goto output_num;
}
@@ -1151,17 +1154,20 @@ val vformat(val stream, val fmtstr, va_list vl)
obj = va_arg(vl, val);
if (obj == nao)
goto premature;
- if (fixnump(obj)) {
+ switch (type(obj)) {
+ case NUM:
value = c_num(obj);
sprintf(num_buf, num_fmt->dec, value);
goto output_num;
- } else if (bignump(obj)) {
- int nchars = mp_radix_size(mp(obj), 10);
- if (nchars >= (int) sizeof (num_buf))
- pnum = (char *) chk_malloc(nchars + 1);
- mp_toradix(mp(obj), (unsigned char *) pnum, 10);
+ case BGNUM:
+ {
+ int nchars = mp_radix_size(mp(obj), 10);
+ if (nchars >= (int) sizeof (num_buf))
+ pnum = (char *) chk_malloc(nchars + 1);
+ mp_toradix(mp(obj), (unsigned char *) pnum, 10);
+ }
goto output_num;
- } else if (floatp(obj)) {
+ case FLNUM:
sprintf(num_buf, "%g", obj->fl.n);
if (!precision) {
@@ -1180,11 +1186,14 @@ val vformat(val stream, val fmtstr, va_list vl)
precision = 0;
}
goto output_num;
- } else if (width != 0) {
- val str = format(nil, ch == 'a' ? lit("~a") : lit("~s"), obj, nao);
- if (!vformat_str(stream, str, width, left, precision))
- return nil;
- continue;
+ default:
+ if (width != 0) {
+ val str = format(nil, ch == 'a' ? lit("~a") : lit("~s"),
+ obj, nao);
+ if (!vformat_str(stream, str, width, left, precision))
+ return nil;
+ continue;
+ }
}
if (ch == 'a')
obj_pprint(obj, stream);