]> gitweb.factorcode.org Git - factor.git/commitdiff
prettyprinter, locale independant float printing
authorJon Harper <jon.harper87@gmail.com>
Mon, 15 Jun 2015 22:29:02 +0000 (00:29 +0200)
committerJohn Benediktsson <mrjbq7@gmail.com>
Tue, 8 Mar 2016 15:55:25 +0000 (07:55 -0800)
basis/calendar/format/format.factor
basis/formatting/formatting.factor
basis/stack-checker/known-words/known-words.factor
core/bootstrap/primitives.factor
core/math/parser/parser.factor
vm/math.cpp

index 35c7f032cec9e94b077f7c9bc95db874a92e817e..96d4afcfae70f09982e38a0e58cb703494ed6dfb 100644 (file)
@@ -150,7 +150,7 @@ M: timestamp year. ( timestamp -- )
 ! Should be enough for anyone, allows to not do a fancy
 ! algorithm to detect infinite decimals (e.g 1/3)
 : ss.SSSSSS ( timestamp -- )
-    second>> >float "%09.6f" format-float write ;
+    second>> >float "0" 9 6 "f" "C" format-float write ;
 
 : (timestamp>rfc3339) ( timestamp -- )
     {
index f36b04262240f45ac8b475d4ac079b1d30a86c02..697dc693ccc75fd69d0e08bcdeef9f3e290f4118 100644 (file)
@@ -30,8 +30,7 @@ IN: formatting
     [ 0 ] [ string>number ] if-empty ;
 
 : format-simple ( x digits string -- string )
-    [ [ >float ] [ number>string ] bi* "%." ] dip
-    surround format-float ;
+    [ >float "" -1 ] 2dip "" format-float ;
 
 : format-scientific ( x digits -- string ) "e" format-simple ;
 
index 02b4f2956203282ce8e0bb7558c5389812999bb1..5ad4733548335ccac08d7c56b77170f4ee67723a 100644 (file)
@@ -420,7 +420,7 @@ M: object infer-call* \ call bad-macro-input ;
     { fixnum>float { fixnum } { float } }
 
     ! float
-    { (format-float) { float byte-array } { byte-array } }
+    { (format-float) { float byte-array fixnum fixnum byte-array byte-array } { byte-array } }
     { bits>float { integer } { float } }
     { float* { float float } { float } }
     { float+ { float float } { float } }
index ca5bb6f95dbf97fb6d09c183f78fb8f148e21d2e..5079cf6acfb7d27104738da162ae670a933761bc 100755 (executable)
@@ -476,7 +476,7 @@ tuple
     { "bits>float" "math" "primitive_bits_float" ( n -- x ) }
     { "double>bits" "math" "primitive_double_bits" ( x -- n ) }
     { "float>bits" "math" "primitive_float_bits" ( x -- n ) }
-    { "(format-float)" "math.parser.private" "primitive_format_float" ( n format -- byte-array ) }
+    { "(format-float)" "math.parser.private" "primitive_format_float" ( n fill width precision format locale -- byte-array ) }
     { "bignum*" "math.private" "primitive_bignum_multiply" ( x y -- z ) }
     { "bignum+" "math.private" "primitive_bignum_add" ( x y -- z ) }
     { "bignum-" "math.private" "primitive_bignum_subtract" ( x y -- z ) }
index de8f60ce1d71541c55730b807a2b84d2297bfffc..0c4ecd89341d835bcbc91965512e7fc02e863407 100644 (file)
@@ -6,7 +6,7 @@ sequences.private splitting strings strings.private ;
 IN: math.parser
 
 <PRIVATE
-PRIMITIVE: (format-float) ( n format -- byte-array )
+PRIMITIVE: (format-float) ( n fill width precision format locale -- byte-array )
 PRIVATE>
 
 : digit> ( ch -- n )
@@ -488,12 +488,12 @@ M: ratio >base
 
 <PRIVATE
 
-: fix-float ( str -- newstr )
-    CHAR: e over index [
-        cut [ fix-float ] dip append
+: fix-float ( str exponent -- newstr )
+    2dup first swap member? [
+         [ [ split1 ] keep swap [ fix-float ] dip ] [ glue ] bi
     ] [
-        CHAR: . over member? [ ".0" append ] unless
-    ] if* ;
+        drop CHAR: . over member? [ ".0" append ] unless
+    ] if ;
 
 : mantissa-expt-normalize ( mantissa expt -- mantissa' expt' )
     [ dup log2 52 swap - [ shift 52 2^ 1 - bitand ] [ 1022 + neg ] bi ]
@@ -548,14 +548,17 @@ M: ratio >base
         ] 2curry each-integer
     ] keep ; inline
 
-: format-float ( n format -- string )
-    format-string (format-float)
-    dup [ 0 = ] find drop
-    format-head fix-float ; inline
+: format-float ( n fill width precision format locale -- string )
+    [
+        [ format-string ] 4dip [ format-string ] bi@ (format-float)
+        dup [ 0 = ] find drop format-head
+    ] [
+        "C" = [ [ "G" = ] [ "E" = ] bi or "E" "e" ? fix-float ] [ drop ] if
+    ] 2bi ; inline
 
 : float>base ( n radix -- str )
     {
-        { 10 [ "%.16g" format-float ] }
+        { 10 [ "" -1 16 "" "C" format-float ] }
         [ bin-float>base ]
     } case ; inline
 
index e46dc80b62a1287ac67d56cdb56ebed41ebb379b..c2b57140136f7d3068daa375be17d80f840c72c9 100644 (file)
@@ -1,4 +1,6 @@
 #include "master.hpp"
+#include <sstream>
+#include <iomanip>
 
 namespace factor {
 
@@ -211,10 +213,36 @@ void factor_vm::primitive_fixnum_to_float() {
 
 /* Allocates memory */
 void factor_vm::primitive_format_float() {
-  byte_array* array = allot_byte_array(100);
+  char* locale = alien_offset(ctx->pop());
   char* format = alien_offset(ctx->pop());
+  fixnum precision = untag_fixnum(ctx->pop());
+  fixnum width = untag_fixnum(ctx->pop());
+  char* fill = alien_offset(ctx->pop());
   double value = untag_float_check(ctx->peek());
-  SNPRINTF(array->data<char>(), 99, format, value);
+  std::ostringstream localized_stream;
+  localized_stream.imbue(std::locale(locale));
+  switch (format[0]) {
+    case 'f': localized_stream << std::fixed; break;
+    case 'e': localized_stream << std::scientific; break;
+  }
+  if (isupper(format[0])) {
+    localized_stream << std::uppercase;
+  }
+  if (fill[0] != '\0') {
+    localized_stream << std::setfill(fill[0]);
+  }
+  if (width >= 0) {
+    localized_stream << std::setw(width);
+  }
+  if (precision >= 0) {
+    localized_stream << std::setprecision(precision);
+  }
+  localized_stream << value;
+  const std::string& tmp = localized_stream.str();
+  const char* cstr = tmp.c_str();
+  int size = tmp.length()+1;
+  byte_array* array = allot_byte_array(size);
+  memcpy(array->data<char>(), cstr, size);
   ctx->replace(tag<byte_array>(array));
 }