[svn:parrot] r48754 - in trunk: src/pmc t/pmc

Paul at osuosl.org Paul at osuosl.org
Wed Sep 1 21:34:20 UTC 2010


Author: Paul C. Anagnostopoulos
Date: Wed Sep  1 21:34:19 2010
New Revision: 48754
URL: https://trac.parrot.org/parrot/changeset/48754

Log:
Integer neg and absolute now promote to BigInt

Modified:
   trunk/src/pmc/boolean.pmc
   trunk/src/pmc/integer.pmc
   trunk/t/pmc/bigint.t

Modified: trunk/src/pmc/boolean.pmc
==============================================================================
--- trunk/src/pmc/boolean.pmc	Wed Sep  1 21:11:46 2010	(r48753)
+++ trunk/src/pmc/boolean.pmc	Wed Sep  1 21:34:19 2010	(r48754)
@@ -99,6 +99,28 @@
     VTABLE void set_string_native(STRING *value) {
         SELF.set_bool(Parrot_str_boolean(INTERP, value));
     }
+
+/*
+
+=item C<PMC *neg(PMC *dest)>
+
+=item C<void i_neg()>
+
+Set C<dest> to the ''negated'' value of C<SELF>. The negative of a
+boolean value is the identical value.
+
+=cut
+
+*/
+
+    VTABLE PMC *neg(PMC *dest) {
+        dest = Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF),
+                                       SELF.get_bool());
+        return dest;
+    }
+
+    VTABLE void i_neg() {
+    }
 }
 
 /*

Modified: trunk/src/pmc/integer.pmc
==============================================================================
--- trunk/src/pmc/integer.pmc	Wed Sep  1 21:11:46 2010	(r48753)
+++ trunk/src/pmc/integer.pmc	Wed Sep  1 21:34:19 2010	(r48754)
@@ -257,7 +257,7 @@
 
 =item C<void set_integer_native(INTVAL value)>
 
-Sets the value of the integer to the value of the C<Integer> C<*value>.
+Sets the value of the integer to the value of the native integer C<*value>.
 
 =cut
 
@@ -987,6 +987,46 @@
 
 /*
 
+=item C<PMC *neg(PMC *dest)>
+
+=item C<void i_neg()>
+
+Set C<dest> to the negated value of C<SELF>. If the value of C<SELF>
+is the minimum integer, a BigInt is created.
+
+=cut
+
+*/
+
+    VTABLE PMC *neg(PMC *dest) {
+        const INTVAL a = SELF.get_integer();
+
+        if (a != PARROT_INTVAL_MIN)
+            return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF),
+                                                   -a);
+        else {
+            PMC *promoted;
+            maybe_throw_overflow_error(INTERP);
+            promoted = Parrot_pmc_new_init_int(INTERP, enum_class_BigInt, 0);   
+            return VTABLE_subtract_int(INTERP, promoted, a, promoted);
+        }
+    }
+
+    VTABLE void i_neg() {
+        const INTVAL a = SELF.get_integer();
+   
+        if (a != PARROT_INTVAL_MIN)
+            VTABLE_set_integer_native(INTERP, SELF, -a);
+        else {
+            maybe_throw_overflow_error(INTERP);
+            SELF = upgrade_self_to_bignum(INTERP, SELF);
+            VTABLE_set_integer_native(INTERP, SELF, 0);
+            VTABLE_i_subtract_int(INTERP, SELF, a);
+        }
+    }
+
+/*
+
 =item C<INTVAL is_equal(PMC *value)>
 
 The C<==> operation.
@@ -1158,23 +1198,38 @@
 
 =item C<void absolute()>
 
-Sets C<dest> to the absolute value of SELF.
+Sets C<dest> to the absolute value of C<SELF>. If the value of C<SELF>
+is the minimum integer, a BigInt is created.
 
 =cut
 
 */
 
     VTABLE PMC *absolute(PMC *dest) {
-        const INTVAL a = abs(SELF.get_integer());
+        const INTVAL a = SELF.get_integer();
 
-        /* TT # 1245 overflow for -maxint */
-        return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF), a);
+        if (a != PARROT_INTVAL_MIN)
+            return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF),
+                                                   abs(a));
+        else {
+            PMC *promoted;
+            maybe_throw_overflow_error(INTERP);
+            promoted = Parrot_pmc_new_init_int(INTERP, enum_class_BigInt, a);   
+            return VTABLE_neg(INTERP, promoted, dest);
+        }
     }
 
 
     VTABLE void i_absolute() {
-        const INTVAL a = abs(SELF.get_integer());
-        VTABLE_set_integer_native(INTERP, SELF, a);
+        const INTVAL a = SELF.get_integer();
+
+        if (a != PARROT_INTVAL_MIN)
+            VTABLE_set_integer_native(INTERP, SELF, abs(a));
+        else {
+            maybe_throw_overflow_error(INTERP);
+            SELF = upgrade_self_to_bignum(INTERP, SELF);
+            return VTABLE_i_neg(INTERP, SELF);
+        }
     }
 
 

Modified: trunk/t/pmc/bigint.t
==============================================================================
--- trunk/t/pmc/bigint.t	Wed Sep  1 21:11:46 2010	(r48753)
+++ trunk/t/pmc/bigint.t	Wed Sep  1 21:34:19 2010	(r48754)
@@ -20,7 +20,7 @@
 
     .include 'test_more.pir'
 
-    plan(34)
+    plan(32)
     check_libgmp_good()
 
     set_and_get()
@@ -28,9 +28,10 @@
     subtraction()
     multiplication()
     division()
-    division_by_zero()
     negation()
+    negate_min_integer()
     absolute_value()
+    absolute_min_integer()
     overflow_coercion()
     interface()
     boolean()
@@ -504,6 +505,23 @@
     ok($I1, 'negation')
 .end
 
+.loadlib 'sys_ops'
+.include 'sysinfo.pasm'
+
+.sub negate_min_integer
+    .local int max
+    .local int min
+    .local pmc max_1
+    .local pmc neg_min
+    max = sysinfo .SYSINFO_PARROT_INTMAX
+    min = sysinfo .SYSINFO_PARROT_INTMIN
+    max_1 = box max
+    inc max_1
+    neg_min = box min
+    neg neg_min                         # Use 1-operand form of neg.
+    is(neg_min, max_1, 'negate minimum native integer')
+.end
+
 .sub absolute_value
     $P0 = new ['BigInt']
     $P0 = '-1230000000000000000000'
@@ -522,6 +540,21 @@
     is($S0,'1230000000000000000000','... and in-place works too')
 .end
 
+.sub absolute_min_integer
+    .local int max
+    .local int min
+    .local pmc max_1
+    .local pmc neg_min
+    .local pmc result
+    max = sysinfo .SYSINFO_PARROT_INTMAX
+    min = sysinfo .SYSINFO_PARROT_INTMIN
+    max_1 = box max
+    inc max_1
+    neg_min = box min
+    result = abs neg_min                # Use 2-operand form of abs.
+    is(result, max_1, 'absolute minimum native integer')
+.end
+
 .sub overflow_coercion
     # check libgmp included in Parrot build
     $P0 = getinterp
@@ -745,7 +778,7 @@
     ne $S0, $S6, k25
     inc $I1
 k25:
-    todo( $I1, 'integer negation of MinInt converts MaxInt+1 to BigInt', 'TT #1616')
+    ok($I1, 'integer negation of MinInt converts to BigInt')
 
     $I1 = 0
     $P0 = new ['Integer']
@@ -760,7 +793,7 @@
     ne $S0, $S6, k27
     inc $I1
 k27:
-    todo( $I1, 'integer absolute-value of MinInt converts MaxInt+1 to BigInt', 'TT #1616')
+    ok($I1, 'integer abs(MinInt) converts to BigInt')
 
     $P0 = new ['Integer']
     $P0 = $I3


More information about the parrot-commits mailing list