From e7d17c45b37c145eff23a8fc6e602346f9b65fe3 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 21 Mar 2012 07:59:24 -0700 Subject: * 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. --- stream.c | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) (limited to 'stream.c') 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); -- cgit v1.2.3