Author: particle
Date: Tue Jan 27 10:24:45 2009
New Revision: 36057

Added:
   trunk/config/auto/format/floatval_maxmin.in   (contents, props changed)
   trunk/config/auto/format/intval_maxmin.in   (props changed)
      - copied unchanged from r35875, /trunk/config/auto/format/maxmin.in
Removed:
   trunk/config/auto/format/maxmin.in
Modified:
   trunk/MANIFEST
   trunk/config/auto/format.pm
   trunk/config/gen/config_h/config_h.in
   trunk/include/parrot/datatypes.h
   trunk/src/datatypes.c
   trunk/src/spf_render.c
   trunk/t/compilers/imcc/syn/veracity.t
   trunk/t/op/arithmetics.t

Log:
[core] portable Inf/NaN support
~ adds configure code to set min/max constants for FLOATVAL
~ modifies Parrot_sprintf_format and string_to_num to handle two-way 
string/number conversion
~ adds basic Inf/NaN math test
note: currently parrot accepts 'Inf' and 'NaN' values in N registers, which 
disagrees with the open group's spec, but agrees with Tcl and Perl 6 specs

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Tue Jan 27 10:24:45 2009
@@ -238,7 +238,8 @@
 config/auto/env/test_unsetenv.in                            []
 config/auto/fink.pm                                         []
 config/auto/format.pm                                       []
-config/auto/format/maxmin.in                                []
+config/auto/format/floatval_maxmin.in                       []
+config/auto/format/intval_maxmin.in                         []
 config/auto/funcptr.pm                                      []
 config/auto/funcptr/test_c.in                               []
 config/auto/gc.pm                                           []

Modified: trunk/config/auto/format.pm
==============================================================================
--- trunk/config/auto/format.pm (original)
+++ trunk/config/auto/format.pm Tue Jan 27 10:24:45 2009
@@ -38,6 +38,8 @@
 
     _set_floatvalfmt_nvsize($conf);
 
+    _set_floatvalmaxmin($conf);
+
     return 1;
 }
 
@@ -89,7 +91,7 @@
     $conf->data->set( intvalmin   => $ivmin );
     $conf->data->set( intvalmax   => $ivmax );
 
-    $conf->cc_gen('config/auto/format/maxmin.in');
+    $conf->cc_gen('config/auto/format/intval_maxmin.in');
     eval { $conf->cc_build(); };
     if ( $@ ) {
         $ivmin = '0';
@@ -125,6 +127,40 @@
     );
 }
 
+# This is unrelated to format, may be moved to other place later
+sub _set_floatvalmaxmin {
+    my $conf = shift;
+    my $nvmin;
+    my $nvmax;
+    my $nv = $conf->data->get(qw(nv));
+
+    if ( $nv eq "double" ) {
+        $nvmin = 'DBL_MIN';
+        $nvmax = 'DBL_MAX';
+    }
+    elsif ( $nv eq "long double" ) {
+
+        # Stay way from long double for now (it may be 64 or 80 bits)
+        # die "long double not supported at this time, use double.";
+        $nvmin = 'LDBL_MIN';
+        $nvmax = 'LDBL_MAX';
+    }
+    else {
+        die qq{Configure.pl:  Can't find limits for type '$nv'\n};
+    }
+
+    $conf->data->set( floatvalmin => $nvmin );
+    $conf->data->set( floatvalmax => $nvmax );
+
+    $conf->cc_gen('config/auto/format/floatval_maxmin.in');
+    eval { $conf->cc_build(); };
+    if ( $@ ) {
+        $nvmin = '0';
+        $nvmax = '0';
+    }
+
+}
+
 1;
 
 # Local Variables:

Added: trunk/config/auto/format/floatval_maxmin.in
==============================================================================
--- (empty file)
+++ trunk/config/auto/format/floatval_maxmin.in Tue Jan 27 10:24:45 2009
@@ -0,0 +1,15 @@
+/* Copyright (C) 2008, The Perl Foundation. */
+/* $Id:  */
+
+#include <float.h>
+
+int main(int argc, char *argv[])
+{
+    double i, j;
+
+    i = @floatvalmin@;
+    j = @floatvalmax@;
+
+
+    return 0;
+}

Modified: trunk/config/gen/config_h/config_h.in
==============================================================================
--- trunk/config/gen/config_h/config_h.in       (original)
+++ trunk/config/gen/config_h/config_h.in       Tue Jan 27 10:24:45 2009
@@ -51,6 +51,13 @@
 #define PARROT_INTVAL_MAX              @intvalmax@
 #endif
 
+#ifndef PARROT_FLOATVAL_MIN
+#define PARROT_FLOATVAL_MIN            @floatvalmin@
+#endif
+#ifndef PARROT_FLOATVAL_MAX
+#define PARROT_FLOATVAL_MAX            @floatvalmax@
+#endif
+
 /* Temporary until we find a way to make it work in the right place. */
 struct PackFile;      typedef struct PackFile * Parrot_PackFile;
 

Modified: trunk/include/parrot/datatypes.h
==============================================================================
--- trunk/include/parrot/datatypes.h    (original)
+++ trunk/include/parrot/datatypes.h    Tue Jan 27 10:24:45 2009
@@ -125,6 +125,15 @@
 };
 #endif /* INSIDE_GLOBAL_SETUP */
 
+#define PARROT_FLOATVAL_INF_POSITIVE  floatval_divide_by_zero(interp, 1.0)
+#define PARROT_FLOATVAL_INF_NEGATIVE  floatval_divide_by_zero(interp, -1.0)
+#define PARROT_FLOATVAL_NAN_QUIET     floatval_divide_by_zero(interp, 0.0)
+
+#define PARROT_CSTRING_INF_POSITIVE    "Inf"
+#define PARROT_CSTRING_INF_NEGATIVE    "-Inf"
+#define PARROT_CSTRING_NAN_QUIET       "NaN"
+
+
 /* HEADERIZER BEGIN: src/datatypes.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 
@@ -141,6 +150,10 @@
 STRING * Parrot_get_datatype_name(PARROT_INTERP, INTVAL type)
         __attribute__nonnull__(1);
 
+PARROT_EXPORT
+FLOATVAL
+floatval_divide_by_zero(PARROT_INTERP, FLOATVAL num);
+
 #define ASSERT_ARGS_Parrot_get_datatype_enum __attribute__unused__ int 
_ASSERT_ARGS_CHECK = \
        PARROT_ASSERT_ARG(interp) \
     || PARROT_ASSERT_ARG(type_name)

Modified: trunk/src/datatypes.c
==============================================================================
--- trunk/src/datatypes.c       (original)
+++ trunk/src/datatypes.c       Tue Jan 27 10:24:45 2009
@@ -81,6 +81,16 @@
     return string_make(interp, s, strlen(s), NULL, PObj_external_FLAG);
 }
 
+
+PARROT_EXPORT
+FLOATVAL
+floatval_divide_by_zero(PARROT_INTERP, FLOATVAL num)
+{
+    FLOATVAL zero = 0.0;
+    return num / zero;
+}
+
+
 /*
 
 =back

Modified: trunk/src/spf_render.c
==============================================================================
--- trunk/src/spf_render.c      (original)
+++ trunk/src/spf_render.c      Tue Jan 27 10:24:45 2009
@@ -741,9 +741,26 @@
                             const HUGEFLOATVAL thefloat =
                                 obj->getfloat(interp, info.type, obj);
 
-                            /* turn -0.0 into 0.0 */
-                            gen_sprintf_call(tc, &info, ch);
-                            ts = cstr2pstr(tc);
+                            /* check for Inf and NaN values */
+                            if (thefloat == PARROT_FLOATVAL_INF_POSITIVE) {
+                                ts = cstr2pstr(PARROT_CSTRING_INF_POSITIVE);
+                            }
+                            else if (thefloat == PARROT_FLOATVAL_INF_NEGATIVE) 
{
+                                ts = cstr2pstr(PARROT_CSTRING_INF_NEGATIVE);
+                            }
+                            /* XXX for some reason, this comparison isn't 
working
+                            else if (thefloat == PARROT_FLOATVAL_NAN_QUIET) {
+                                ts = cstr2pstr(PARROT_CSTRING_NAN_QUIET);
+                            }
+                            */
+                            else if (thefloat != thefloat) {
+                                ts = cstr2pstr(PARROT_CSTRING_NAN_QUIET);
+                            }
+                            else {
+                                /* turn -0.0 into 0.0 */
+                                gen_sprintf_call(tc, &info, ch);
+                                ts = cstr2pstr(tc);
+                            }
 
                             /* XXX lost precision if %Hg or whatever */
                             {

Modified: trunk/t/compilers/imcc/syn/veracity.t
==============================================================================
--- trunk/t/compilers/imcc/syn/veracity.t       (original)
+++ trunk/t/compilers/imcc/syn/veracity.t       Tue Jan 27 10:24:45 2009
@@ -107,12 +107,11 @@
 
 #}
 
-SKIP: {
-    skip 'failing on win32' => 1 if $^O =~ m/win32/i;
 
 pir_output_is( <<'CODE', <<'OUT', "Float NaN" );
 .sub test :main
     $N0 = 'NaN'
+    say $N0
     unless $N0 goto not_nan
     say "NaN is true"
 
@@ -120,10 +119,10 @@
     end
 .end
 CODE
+NaN
 NaN is true
 OUT
 
-}
 
 # Local Variables:
 #   mode: cperl

Modified: trunk/t/op/arithmetics.t
==============================================================================
--- trunk/t/op/arithmetics.t    (original)
+++ trunk/t/op/arithmetics.t    Tue Jan 27 10:24:45 2009
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 27;
+use Parrot::Test tests => 28;
 
 # test for GMP
 use Parrot::Config;
@@ -866,7 +866,7 @@
 # In the meantime, make sure it overflows nicely
 # on 32 bit.
     unless i2 > 40 goto next
-.end
+`.end
 CODE
 2
 4
@@ -911,6 +911,20 @@
 OUTPUT
 }
 
+
+pir_output_is( <<'CODE', <<OUTPUT, "Inf/NaN - basic arith" );
+.sub 'test' :main
+    $N0 = 'Inf'
+    say $N0
+    $N0 -= $N0
+    say $N0
+.end
+CODE
+Inf
+NaN
+OUTPUT
+
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Reply via email to