Ticket #1616: PCA-patch-008.patch

File PCA-patch-008.patch, 6.1 KB (added by Paul C. Anagnostopoulos, 4 years ago)
  • src/pmc/boolean.pmc

     
    9999    VTABLE void set_string_native(STRING *value) { 
    100100        SELF.set_bool(Parrot_str_boolean(INTERP, value)); 
    101101    } 
     102 
     103/* 
     104 
     105=item C<PMC *neg(PMC *dest)> 
     106 
     107=item C<void i_neg()> 
     108 
     109Set C<dest> to the ''negated'' value of C<SELF>. The negative of a 
     110boolean value is the identical value. 
     111 
     112=cut 
     113 
     114*/ 
     115 
     116    VTABLE PMC *neg(PMC *dest) { 
     117        dest = Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF), 
     118                                       SELF.get_bool()); 
     119        return dest; 
     120    } 
     121 
     122    VTABLE void i_neg() { 
     123    } 
    102124} 
    103125 
    104126/* 
  • src/pmc/integer.pmc

     
    257257 
    258258=item C<void set_integer_native(INTVAL value)> 
    259259 
    260 Sets the value of the integer to the value of the C<Integer> C<*value>. 
     260Sets the value of the integer to the value of the native integer C<*value>. 
    261261 
    262262=cut 
    263263 
     
    987987 
    988988/* 
    989989 
     990=item C<PMC *neg(PMC *dest)> 
     991 
     992=item C<void i_neg()> 
     993 
     994Set C<dest> to the negated value of C<SELF>. If the value of C<SELF> 
     995is the minimum integer, a BigInt is created. 
     996 
     997=cut 
     998 
     999*/ 
     1000 
     1001    VTABLE PMC *neg(PMC *dest) { 
     1002        const INTVAL a = SELF.get_integer(); 
     1003 
     1004        if (a != PARROT_INTVAL_MIN) 
     1005            return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF), 
     1006                                                   -a); 
     1007        else { 
     1008            PMC *promoted; 
     1009            maybe_throw_overflow_error(INTERP); 
     1010            promoted = Parrot_pmc_new_init_int(INTERP, enum_class_BigInt, 0);    
     1011            return VTABLE_subtract_int(INTERP, promoted, a, promoted); 
     1012        } 
     1013    } 
     1014 
     1015    VTABLE void i_neg() { 
     1016        const INTVAL a = SELF.get_integer(); 
     1017    
     1018        if (a != PARROT_INTVAL_MIN) 
     1019            VTABLE_set_integer_native(INTERP, SELF, -a); 
     1020        else { 
     1021            maybe_throw_overflow_error(INTERP); 
     1022            SELF = upgrade_self_to_bignum(INTERP, SELF); 
     1023            VTABLE_set_integer_native(INTERP, SELF, 0); 
     1024            VTABLE_i_subtract_int(INTERP, SELF, a); 
     1025        } 
     1026    } 
     1027 
     1028/* 
     1029 
    9901030=item C<INTVAL is_equal(PMC *value)> 
    9911031 
    9921032The C<==> operation. 
     
    11581198 
    11591199=item C<void absolute()> 
    11601200 
    1161 Sets C<dest> to the absolute value of SELF. 
     1201Sets C<dest> to the absolute value of C<SELF>. If the value of C<SELF> 
     1202is the minimum integer, a BigInt is created. 
    11621203 
    11631204=cut 
    11641205 
    11651206*/ 
    11661207 
    11671208    VTABLE PMC *absolute(PMC *dest) { 
    1168         const INTVAL a = abs(SELF.get_integer()); 
     1209        const INTVAL a = SELF.get_integer(); 
    11691210 
    1170         /* TT # 1245 overflow for -maxint */ 
    1171         return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF), a); 
     1211        if (a != PARROT_INTVAL_MIN) 
     1212            return Parrot_pmc_new_init_int(INTERP, VTABLE_type(INTERP, SELF), 
     1213                                                   abs(a)); 
     1214        else { 
     1215            PMC *promoted; 
     1216            maybe_throw_overflow_error(INTERP); 
     1217            promoted = Parrot_pmc_new_init_int(INTERP, enum_class_BigInt, a);    
     1218            return VTABLE_neg(INTERP, promoted, dest); 
     1219        } 
    11721220    } 
    11731221 
    11741222 
    11751223    VTABLE void i_absolute() { 
    1176         const INTVAL a = abs(SELF.get_integer()); 
    1177         VTABLE_set_integer_native(INTERP, SELF, a); 
     1224        const INTVAL a = SELF.get_integer(); 
     1225 
     1226        if (a != PARROT_INTVAL_MIN) 
     1227            VTABLE_set_integer_native(INTERP, SELF, abs(a)); 
     1228        else { 
     1229            maybe_throw_overflow_error(INTERP); 
     1230            SELF = upgrade_self_to_bignum(INTERP, SELF); 
     1231            return VTABLE_i_neg(INTERP, SELF); 
     1232        } 
    11781233    } 
    11791234 
    11801235 
  • t/pmc/bigint.t

     
    2020 
    2121    .include 'test_more.pir' 
    2222 
    23     plan(34) 
     23    plan(32) 
    2424    check_libgmp_good() 
    2525 
    2626    set_and_get() 
     
    2828    subtraction() 
    2929    multiplication() 
    3030    division() 
    31     division_by_zero() 
    3231    negation() 
     32    negate_min_integer() 
    3333    absolute_value() 
     34    absolute_min_integer() 
    3435    overflow_coercion() 
    3536    interface() 
    3637    boolean() 
     
    504505    ok($I1, 'negation') 
    505506.end 
    506507 
     508.loadlib 'sys_ops' 
     509.include 'sysinfo.pasm' 
     510 
     511.sub negate_min_integer 
     512    .local int max 
     513    .local int min 
     514    .local pmc max_1 
     515    .local pmc neg_min 
     516    max = sysinfo .SYSINFO_PARROT_INTMAX 
     517    min = sysinfo .SYSINFO_PARROT_INTMIN 
     518    max_1 = box max 
     519    inc max_1 
     520    neg_min = box min 
     521    neg neg_min                         # Use 1-operand form of neg. 
     522    is(neg_min, max_1, 'negate minimum native integer') 
     523.end 
     524 
    507525.sub absolute_value 
    508526    $P0 = new ['BigInt'] 
    509527    $P0 = '-1230000000000000000000' 
     
    522540    is($S0,'1230000000000000000000','... and in-place works too') 
    523541.end 
    524542 
     543.sub absolute_min_integer 
     544    .local int max 
     545    .local int min 
     546    .local pmc max_1 
     547    .local pmc neg_min 
     548    .local pmc result 
     549    max = sysinfo .SYSINFO_PARROT_INTMAX 
     550    min = sysinfo .SYSINFO_PARROT_INTMIN 
     551    max_1 = box max 
     552    inc max_1 
     553    neg_min = box min 
     554    result = abs neg_min                # Use 2-operand form of abs. 
     555    is(result, max_1, 'absolute minimum native integer') 
     556.end 
     557 
    525558.sub overflow_coercion 
    526559    # check libgmp included in Parrot build 
    527560    $P0 = getinterp 
     
    745778    ne $S0, $S6, k25 
    746779    inc $I1 
    747780k25: 
    748     todo( $I1, 'integer negation of MinInt converts MaxInt+1 to BigInt', 'TT #1616') 
     781    ok($I1, 'integer negation of MinInt converts to BigInt') 
    749782 
    750783    $I1 = 0 
    751784    $P0 = new ['Integer'] 
     
    760793    ne $S0, $S6, k27 
    761794    inc $I1 
    762795k27: 
    763     todo( $I1, 'integer absolute-value of MinInt converts MaxInt+1 to BigInt', 'TT #1616') 
     796    ok($I1, 'integer abs(MinInt) converts to BigInt') 
    764797 
    765798    $P0 = new ['Integer'] 
    766799    $P0 = $I3