[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