[svn:parrot] r36765 - in trunk: . src/pmc t/pmc
rurban at svn.parrot.org
rurban at svn.parrot.org
Sun Feb 15 16:56:02 UTC 2009
Author: rurban
Date: Sun Feb 15 16:56:01 2009
New Revision: 36765
URL: https://trac.parrot.org/parrot/changeset/36765
Log:
TT #280: add bignum (again)
- some stringification and overflow tests are failing: todo
- bigint inheritence not yet enabled
Added:
trunk/t/pmc/bignum.t (contents, props changed)
Modified:
trunk/MANIFEST
trunk/NEWS
trunk/src/pmc/bignum.pmc
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST Sun Feb 15 16:29:48 2009 (r36764)
+++ trunk/MANIFEST Sun Feb 15 16:56:01 2009 (r36765)
@@ -2687,6 +2687,7 @@
t/pmc/addrregistry.t [test]
t/pmc/array.t [test]
t/pmc/bigint.t [test]
+t/pmc/bignum.t [test]
t/pmc/boolean.t [test]
t/pmc/bound_nci.t [test]
t/pmc/callsignature.t [test]
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS Sun Feb 15 16:29:48 2009 (r36764)
+++ trunk/NEWS Sun Feb 15 16:56:01 2009 (r36765)
@@ -1,11 +1,11 @@
# $Id$
-New in February 2009 release (r35855 to r36683)
+New in February 2009 release (r35855 to r36724)
- Implementation
- + Support for portable 'Inf' and 'NaN'
+ + Support for portable 'Inf', 'NaN' and -0.0
+ pbc_disassemble prints constants in constants table
- + Disabled incomplete BigNum implementation
+ + New experimental BigNum implementation
+ Pair is now a dynamic loadable PMC
+ Various function name sanification
+ New implementation of Strings component
Modified: trunk/src/pmc/bignum.pmc
==============================================================================
--- trunk/src/pmc/bignum.pmc Sun Feb 15 16:29:48 2009 (r36764)
+++ trunk/src/pmc/bignum.pmc Sun Feb 15 16:56:01 2009 (r36765)
@@ -8,16 +8,47 @@
=head1 DESCRIPTION
-C<BigNum> provides arbitrary precision integer mathematic functions.
+C<BigNum> provides arbitrary precision floating point mathematic
+functions, based on the GMP mpf library.
+
+=head1 SYNOPSIS
+
+Make mixing of classes work, like in:
+
+ new $P0 ['BigInt']
+ new $P1 ['BigNum']
+ set $P0, 10
+ set $P1, 2
+ div P2, P0, P1 # $P2 = $P0 / $P1; (BigNum) 5.0
+
+Make auto-upgrading/downgrading work.
+
+ set $N1, $P0
+ set $N1, $P1
+ set $I1, $P0
+ set $I1, $P1
+ set $P0, $I1
+ set $P0, $N1
+ set $P1, $I1
+ set $P1, $N1
+
+ BigNum
+ => BigInt => Integer
+ => Number: float (can be long double) and double
+ => Integer (unsigned long)
=head2 Functions
=over 4
-=item C<static void bignum_set_long(Interp*, PMC *, long value)>
+=item C<static void bignum_set(Interp*, PMC *, PMC *)>
+
+=item C<static void bignum_set_si(Interp*, PMC *, long value)>
=item C<static void bignum_set_double(Interp*, PMC *, double value)>
+=item C<static void bignum_set_str(Interp*, PMC *, char *, int base)>
+
=cut
*/
@@ -28,17 +59,20 @@
# undef PARROT_HAS_GMP /* splint barfs on the gmp.h header */
#endif /* S_SPLINT_S */
-/* Temporariliy disabled until someone fix it */
+/* Uncomment to easily disable it */
+/*
#ifdef PARROT_HAS_GMP
# undef PARROT_HAS_GMP
#endif
+*/
+#undef PARROT_BIGNUM_CAN_BIGINT
#ifdef PARROT_HAS_GMP
+# include "pmc_bigint.h"
# include <gmp.h>
typedef struct BIGNUM {
mpf_t b;
} BIGNUM;
-
#endif
static void
@@ -46,10 +80,11 @@
Parrot_BigNum_attributes *attrs =
mem_allocate_zeroed_typed(Parrot_BigNum_attributes);
#ifdef PARROT_HAS_GMP
- attrs->bi = mem_allocate_zeroed_typed(BIGNUM);
- mpf_init(attrs->bi->b);
+ attrs->bn = mem_allocate_zeroed_typed(BIGNUM);
+ mpf_clear(attrs->bn->b);
+ mpf_init(attrs->bn->b);
#else
- attrs->bi = NULL;
+ attrs->bn = NULL;
#endif
PMC_data(self) = attrs;
}
@@ -58,74 +93,108 @@
static void
bignum_clear(PARROT_INTERP, PMC *self) {
#ifdef PARROT_HAS_GMP
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- mpf_clear(bi->b);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_clear(bn->b);
#endif
}
+
#ifdef PARROT_HAS_GMP
static void
bignum_set(PARROT_INTERP, PMC *dest, PMC *src) {
- BIGNUM *bi_dest, *bi_src;
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- GETATTR_BigNum_bi(interp, src, bi_src);
- mpf_clear(bi_dest->b);
- mpf_init(bi_dest->b);
- mpf_set(bi_dest->b, bi_src->b);
+ BIGNUM *bn_dest, *bn_src;
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ GETATTR_BigNum_bn(interp, src, bn_src);
+ mpf_set(bn_dest->b, bn_src->b);
}
static void
-bignum_set_long(PARROT_INTERP, PMC *self, long value) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- mpf_set_si(bi->b, value);
+bignum_set_si(PARROT_INTERP, PMC *self, long value) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set_si(bn->b, value);
+}
+
+static void
+bignum_set_ui(PARROT_INTERP, PMC *self, unsigned long value) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set_ui(bn->b, value);
+}
+
+static void
+bignum_set_float(PARROT_INTERP, PMC *self, FLOATVAL value) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set_d(bn->b, (double)value);
}
static void
bignum_set_double(PARROT_INTERP, PMC *self, double value) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- mpf_set_d(bi->b, value);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set_d(bn->b, value);
}
static void
bignum_set_str(PARROT_INTERP, PMC *self, char *value, int base) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- mpf_set_str(bi->b, value, base);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set_str(bn->b, value, base);
}
+# ifdef PARROT_BIGNUM_CAN_BIGINT
+static void
+bignum_set_bigint(PARROT_INTERP, PMC *self, struct BIGINT *value) {
+ BIGNUM *bn;
+ struct BIGINT *bi;
+ GETATTR_BigNum_bn(interp, self, bn);
+ bi->b = PARROT_BIGINT(value);
+ mpf_set(bn->b, (mpf_srcptr)bi->b);
+}
+# endif
+
static BIGNUM*
bignum_get_self(PARROT_INTERP, PMC *self) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- return bi;
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return bn;
}
static void
bignum_set_self(PARROT_INTERP, PMC *self, BIGNUM *value) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- mpf_set(bi->b, (mpf_srcptr)((BIGNUM*)value)->b);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpf_set(bn->b, (mpf_srcptr)((BIGNUM*)value)->b);
}
static long
-bignum_get_long(PARROT_INTERP, PMC *self) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- if (mpf_fits_slong_p(bi->b))
- return mpf_get_si(bi->b);
+bignum_get_si(PARROT_INTERP, PMC *self) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ if (mpf_fits_slong_p(bn->b))
+ return mpf_get_si(bn->b);
+
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_si: number too big");
+}
+
+static unsigned long
+bignum_get_ui(PARROT_INTERP, PMC *self) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ if (mpf_fits_slong_p(bn->b))
+ return mpf_get_ui(bn->b);
- Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_long: number too big");
+ Parrot_ex_throw_from_c_args(interp, NULL, 1, "bignum_get_ui: number too big");
}
static int
bignum_get_bool(PARROT_INTERP, PMC *self) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- if (mpf_sgn(bi->b) != 0)
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ if (mpf_sgn(bn->b) != 0)
return 1;
else
return 0;
@@ -133,86 +202,152 @@
static char *
bignum_get_string(PARROT_INTERP, PMC *self, int base) {
- BIGNUM *bi;
+ BIGNUM *bn;
+ size_t n;
+ char *s;
+ mp_exp_t exponent;
+
+ GETATTR_BigNum_bn(interp, self, bn);
+ n = (mpf_get_prec(bn->b)) / log(base) * log(2);
+ s = (char *)mem_sys_allocate(n + 5);
+ return mpf_get_str(s, &exponent, base, 0, bn->b);
+}
+
+static char *
+bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) {
+ BIGNUM *bn;
size_t n;
char *s;
+ mp_exp_t exponent;
- GETATTR_BigNum_bi(interp, self, bi);
- n = mpf_sizeinbase(bi->b, base) + 2;
- s = (char *)mem_sys_allocate(n);
- return mpf_get_str(s, base, bi->b);
+ GETATTR_BigNum_bn(interp, self, bn);
+ s = (char *)mem_sys_allocate(digits + 5);
+ return mpf_get_str(s, &exponent, base, digits, bn->b);
}
static double
bignum_get_double(PARROT_INTERP, PMC *self) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- return mpf_get_d(bi->b);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return mpf_get_d(bn->b);
+}
+
+static FLOATVAL
+bignum_get_float(PARROT_INTERP, PMC *self) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return mpf_get_d(bn->b);
+}
+
+# ifdef PARROT_BIGNUM_CAN_BIGINT
+static struct BIGINT
+bignum_get_bigint(PARROT_INTERP, PMC *self) {
+ BIGNUM *bn;
+ struct BIGINT *bi_dest;
+ GETATTR_BigNum_bn(interp, self, bn);
+ mpz_clear(bi_dest->b);
+ mpz_init(bi_dest->b);
+ if (mpf_fits_slong_p(bn->b)) {
+ bi_dest->b = mpf_get_ui(bn->b);
+ }
+ else {
+ Parrot_ex_throw_from_c_args(interp, NULL, 1,
+ "bignum_get_bigint: Precision loss");
+ }
+ return bi_dest;
}
+# endif
static void
bignum_add_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_add(bi_dest->b, bi_self->b, bi_value->b);
+ BIGNUM *bn_self, *bn_value, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_add(bn_dest->b, bn_self->b, bn_value->b);
}
static void
bignum_add_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
if (value < 0)
- mpf_sub_ui(bi_dest->b, bi_self->b, (unsigned long int)-value);
+ mpf_sub_ui(bn_dest->b, bn_self->b, (unsigned long int)-value);
else
- mpf_add_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
+ mpf_add_ui(bn_dest->b, bn_self->b, (unsigned long int)value);
+}
+
+static void
+bignum_add_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ BIGNUM *bn, *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_set_d(bn->b, value);
+ mpf_add(bn_dest->b, bn_self->b, bn->b);
}
static void
bignum_sub_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_sub(bi_dest->b, bi_self->b, bi_value->b);
+ BIGNUM *bn_self, *bn_value, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_sub(bn_dest->b, bn_self->b, bn_value->b);
}
static void
bignum_sub_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
if (value < 0)
- mpf_add_ui(bi_dest->b, bi_self->b, (unsigned long int)-value);
+ mpf_add_ui(bn_dest->b, bn_self->b, (unsigned long int)-value);
else
- mpf_sub_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
+ mpf_sub_ui(bn_dest->b, bn_self->b, (unsigned long int)value);
+}
+
+static void
+bignum_sub_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ BIGNUM *bn, *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_set_d(bn->b, value);
+ mpf_sub(bn_dest->b, bn_self->b, bn->b);
}
static void
bignum_mul_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_mul(bi_dest->b, bi_self->b, bi_value->b);
+ BIGNUM *bn_self, *bn_value, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_mul(bn_dest->b, bn_self->b, bn_value->b);
}
static void
bignum_mul_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_mul_si(bi_dest->b, bi_self->b, value);
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_mul_ui(bn_dest->b, bn_self->b, (unsigned long)value);
+}
+
+static void
+bignum_mul_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ BIGNUM *bn, *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_set_d(bn->b, value);
+ mpf_mul(bn_dest->b, bn_self->b, bn->b);
}
static void
bignum_pow_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_pow_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_pow_ui(bn_dest->b, bn_self->b, (unsigned long int)value);
}
static void
@@ -225,150 +360,136 @@
static void
bignum_check_divide_zero(PARROT_INTERP, PMC *value) {
/* Throw an exception if we are dividing by zero. */
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, value, bi);
- if (mpf_cmp_si(bi->b, 0) == 0)
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, value, bn);
+ if (mpf_cmp_si(bn->b, 0) == 0)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_DIV_BY_ZERO,
"Divide by zero");
}
static void
bignum_div_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
+ BIGNUM *bn_self, *bn_value, *bn_dest;
bignum_check_divide_zero(interp, value);
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- /* this is mpf_fdiv_q */
- mpf_div(bi_dest->b, bi_self->b, bi_value->b);
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_div(bn_dest->b, bn_self->b, bn_value->b);
}
static void
bignum_div_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
int_check_divide_zero(interp, value);
- /* this is mpf_fdiv_q */
+ /* this is mpz_fdiv_q */
if (value < 0) {
- mpf_div_ui(bi_dest->b, bi_self->b, (unsigned long int)-value);
- mpf_neg(bi_dest->b, bi_dest->b);
+ mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)-value);
+ mpf_neg(bn_dest->b, bn_dest->b);
}
else
- mpf_div_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
-}
-
-static void
-bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- bignum_check_divide_zero(interp, value);
- mpf_fdiv_q(bi_dest->b, bi_self->b, bi_value->b);
+ mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)value);
}
static void
-bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ BIGNUM *bn, *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
int_check_divide_zero(interp, value);
if (value < 0) {
- mpf_fdiv_q_ui(bi_dest->b, bi_self->b, (unsigned long int)-value);
- mpf_neg(bi_dest->b, bi_dest->b);
+ mpf_set_d(bn->b, -value);
+ mpf_div(bn_dest->b, bn_self->b, bn->b);
+ mpf_neg(bn_dest->b, bn_dest->b);
}
else
- mpf_fdiv_q_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
+ mpf_div(bn_dest->b, bn_self->b, bn->b);
}
+/* There's no such mpf_fdiv, only mpz_fdiv and mpf_div */
static void
-bignum_mod_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- BIGNUM *bi_self, *bi_value, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
+ BIGNUM *bn_self, *bn_value, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
bignum_check_divide_zero(interp, value);
- mpf_mod(bi_dest->b, bi_self->b, bi_value->b);
+ mpf_div(bn_dest->b, bn_self->b, bn_value->b);
}
static void
-bignum_mod_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
+bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
+ BIGNUM *bn_self, *bn_dest;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
int_check_divide_zero(interp, value);
if (value < 0) {
- mpf_mod_ui(bi_dest->b, bi_self->b, (unsigned long int)-value);
+ mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)-value);
+ mpf_neg(bn_dest->b, bn_dest->b);
}
else
- mpf_mod_ui(bi_dest->b, bi_self->b, (unsigned long int)value);
+ mpf_div_ui(bn_dest->b, bn_self->b, (unsigned long int)value);
}
static INTVAL
bignum_cmp(PARROT_INTERP, PMC *self, PMC *value) {
- BIGNUM *bi_self, *bi_value;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, value, bi_value);
- return mpf_cmp(bi_self->b, bi_value->b);
+ BIGNUM *bn_self, *bn_value;
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, value, bn_value);
+ return mpf_cmp(bn_self->b, bn_value->b);
+}
+
+static INTVAL
+bignum_cmp_double(PARROT_INTERP, PMC *self, double value) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return mpf_cmp_d(bn->b, value);
}
static INTVAL
bignum_cmp_int(PARROT_INTERP, PMC *self, INTVAL value) {
- BIGNUM *bi;
- GETATTR_BigNum_bi(interp, self, bi);
- return mpf_cmp_si(bi->b, value);
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return mpf_cmp_si(bn->b, value);
+}
+
+static INTVAL
+bignum_cmp_ulong(PARROT_INTERP, PMC *self, unsigned long value) {
+ BIGNUM *bn;
+ GETATTR_BigNum_bn(interp, self, bn);
+ return mpf_cmp_ui(bn->b, value);
}
static void
bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
+ BIGNUM *bn_self, *bn_dest;
pmc_reuse(interp, dest, enum_class_BigNum, 0);
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_abs(bi_dest->b, bi_self->b);
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_abs(bn_dest->b, bn_self->b);
}
static void
bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) {
- BIGNUM *bi_self, *bi_dest;
+ BIGNUM *bn_self, *bn_dest;
pmc_reuse(interp, dest, enum_class_BigNum, 0);
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- mpf_neg(bi_dest->b, bi_self->b);
+ GETATTR_BigNum_bn(interp, self, bn_self);
+ GETATTR_BigNum_bn(interp, dest, bn_dest);
+ mpf_neg(bn_dest->b, bn_self->b);
}
-static void
-bignum_bitwise_shl_bignum_int(PARROT_INTERP, PMC *self,
- INTVAL value, PMC *dest)
-{
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- /* The third args to mpf_mul_2exp and mpf_tdiv_q_2exp are unsigned, so we
- need to do something sensible with negative values. */
- if (value >= 0)
- mpf_mul_2exp(bi_dest->b, bi_self->b, (unsigned long int)value);
- else
- mpf_tdiv_q_2exp(bi_dest->b, bi_self->b, (unsigned long int)-value);
+static INTVAL
+bignum_get_default_prec(PARROT_INTERP, PMC *self) {
+ return mpf_get_default_prec();
}
static void
-bignum_bitwise_shr_bignum_int(PARROT_INTERP, PMC *self,
- INTVAL value, PMC *dest)
-{
- BIGNUM *bi_self, *bi_dest;
- GETATTR_BigNum_bi(interp, self, bi_self);
- GETATTR_BigNum_bi(interp, dest, bi_dest);
- /* The third args to mpf_mul_2exp and mpf_tdiv_q_2exp are unsigned, so we
- need to do something sensible with negative values. */
- if (value >= 0)
- mpf_tdiv_q_2exp(bi_dest->b, bi_self->b, (unsigned long int)value);
- else
- mpf_mul_2exp(bi_dest->b, bi_self->b, (unsigned long int)-value);
+bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) {
+ mpf_set_default_prec(prec);
}
#else /* ifdef PARROT_HAS_GMP */
@@ -377,212 +498,207 @@
FLOATVAL b; /* bogus definition for users without libgmp*/
} BIGNUM;
+# define THROW_NYI Parrot_ex_throw_from_c_args(interp, NULL, \
+ EXCEPTION_LIBRARY_ERROR, "no bignum lib loaded")
+
# if 0
static void
bignum_init(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_clear(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
# endif
static void
-bignum_set_long(PARROT_INTERP, PMC *self, long value) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_set(PARROT_INTERP, PMC *dest, PMC *src) {
+ THROW_NYI;
}
static void
-bignum_set(PARROT_INTERP, PMC *dest, PMC *src) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_set_si(PARROT_INTERP, PMC *self, long value) {
+ THROW_NYI;
}
static void
bignum_set_double(PARROT_INTERP, PMC *self, double value) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_set_str(PARROT_INTERP, PMC *self, char *value, int base) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_set_self(PARROT_INTERP, PMC *self, BIGNUM *value) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static BIGNUM*
bignum_get_self(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static char *
bignum_get_string(PARROT_INTERP, PMC *self, int base) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static char *
+bignum_get_string_size(PARROT_INTERP, PMC *self, int base, int digits) {
+ THROW_NYI;
+}
+
+static unsigned long
+bignum_get_ui(PARROT_INTERP, PMC *self) {
+ THROW_NYI;
}
static long
-bignum_get_long(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_get_si(PARROT_INTERP, PMC *self) {
+ THROW_NYI;
}
static long
bignum_get_bool(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static double
bignum_get_double(PARROT_INTERP, PMC *self) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_add_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_add_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static void
+bignum_add_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
bignum_sub_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_sub_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static void
+bignum_sub_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
bignum_mul_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_mul_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static void
+bignum_mul_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
bignum_pow_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static void
+bignum_pow_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
bignum_div_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_div_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
-bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_div_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
-bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_fdiv_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
+ THROW_NYI;
}
static void
-bignum_mod_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_fdiv_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
+ THROW_NYI;
}
static void
-bignum_mod_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_fdiv_bignum_float(PARROT_INTERP, PMC *self, FLOATVAL value, PMC *dest) {
+ THROW_NYI;
}
static INTVAL
bignum_cmp(PARROT_INTERP, PMC *self, PMC *value) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static INTVAL
bignum_cmp_int(PARROT_INTERP, PMC *self, INTVAL value) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
+}
+
+static INTVAL
+bignum_cmp_float(PARROT_INTERP, PMC *self, FLOATVAL value) {
+ THROW_NYI;
}
static void
bignum_abs(PARROT_INTERP, PMC *self, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
static void
bignum_neg(PARROT_INTERP, PMC *self, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+ THROW_NYI;
}
-static void
-bignum_bitwise_shl_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+static INTVAL
+bignum_get_default_prec(PARROT_INTERP, PMC *self) {
+ THROW_NYI;
}
static void
-bignum_bitwise_shl_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest)
-{
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
+bignum_set_default_prec(PARROT_INTERP, PMC *self, INTVAL prec) {
+ THROW_NYI;
}
-static void
-bignum_bitwise_shr_bignum(PARROT_INTERP, PMC *self, PMC *value, PMC *dest) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
-}
-
-static void
-bignum_bitwise_shr_bignum_int(PARROT_INTERP, PMC *self, INTVAL value, PMC *dest)
-{
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
- "no bignum lib loaded");
-}
+# undef THROW_NYI
#endif /* ifdef PARROT_HAS_GMP */
pmclass BigNum {
- ATTR struct BIGNUM * bi; /*bignum val*/
+ ATTR struct BIGNUM * bn; /*bignum val*/
/*
@@ -621,10 +737,7 @@
*/
VTABLE PMC *instantiate(PMC *sig) {
- return PMCNULL;
-
- /* TODO -- actually build this thing */
-#if 0
+#ifdef PARROT_HAS_GMP
int argcP = REG_INT(interp, 3);
int base;
PMC *res;
@@ -640,6 +753,8 @@
num = VTABLE_get_string(INTERP, REG_PMC(interp, 5));
VTABLE_set_string_keyed_int(INTERP, res, base, num);
return res;
+#else
+ return PMCNULL;
#endif
}
@@ -655,14 +770,14 @@
}
VTABLE void destroy() {
- BIGNUM *bi;
+ BIGNUM *bn;
Parrot_BigNum_attributes *attrs;
bignum_clear(INTERP, SELF);
attrs = (Parrot_BigNum_attributes*)PMC_data(SELF);
#ifdef PARROT_HAS_GMP
- mem_sys_free(attrs->bi);
+ mem_sys_free(attrs->bn);
#endif
mem_sys_free(attrs);
}
@@ -676,14 +791,14 @@
*/
VTABLE void set_integer_native(INTVAL value) {
- bignum_set_long(INTERP, SELF, (long)value);
+ bignum_set_si(INTERP, SELF, (long)value);
}
/*
=item C<void set_number_native(FLOATVAL value)>
-Sets the value of the bignum to C<value>.
+Sets the value of the BigNum to C<value>.
=cut
@@ -697,7 +812,7 @@
=item C<void set_string_native(STRING *value)>
-Sets the value of the integer to the result of converting C<*value> to a
+Sets the value of the BigNum to the result of converting C<*value> to a
number.
=item C<void set_string_keyed_int(INTVAL base, STRING *value)>
@@ -723,7 +838,7 @@
=item C<void set_pmc(PMC *value)>
-Sets the value of the integer to the integer value of C<*value>.
+Sets the value of the BigNum to the BigNum value of C<*value>.
=cut
@@ -737,7 +852,7 @@
=item C<FLOATVAL get_number()>
-Returns the value of the integer as a floating point number.
+Down-converts the precise BigNum to an imprecise double.
=cut
@@ -751,21 +866,35 @@
=item C<INTVAL get_integer()>
-Returns the value of the integer.
+Returns the integer conversion of the BigNum.
=cut
*/
VTABLE INTVAL get_integer() {
- return bignum_get_long(INTERP, SELF);
+ return bignum_get_si(INTERP, SELF);
+ }
+
+/*
+
+=item C<INTVAL get_ulong()>
+
+Returns the unsigned long conversion of the BigNum.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_ulong() {
+ return bignum_get_ui(INTERP, SELF);
}
/*
=item C<PMC *get_bignum()>
-Returns SELF
+Returns SELF, keeping floating point precision.
=cut
@@ -777,9 +906,28 @@
/*
+=item C<FLOATVAL get_bigint()>
+
+Trunc the BigNum to an BigInt.
+
+=cut
+
+*/
+
+ VTABLE BIGINT get_bigint() {
+#if PARROT_BIGNUM_CAN_BIGINT
+ return bignum_get_bigint(INTERP, SELF);
+#else
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_LIBRARY_ERROR,
+ "no bigint support in bigint");
+#endif
+ }
+
+/*
+
=item C<INTVAL get_bool()>
-Returns the boolean value of the integer.
+Returns the boolean value of the BigNum.
=cut
@@ -793,15 +941,20 @@
=item C<STRING *get_string()>
-Returns the string representation of the integer.
+Returns the string representation of the BigNum.
=item C<STRING *get_string_keyed_int(INTVAL base)>
-Returns the string representation of the integer in base C<base>.
+Returns the string representation of the BigNum in base C<base>.
+
+=item C<STRING *get_string_keyed_int_int(INTVAL base, INTVAL digits)>
+
+Returns the string representation of the BigNum in base C<base> with
+C<digits> digits.
=item C<STRING *get_repr()>
-Returns the string representation of the integer with the letter 'L'
+Returns the string representation of the BigNum with the letter 'N'
appended.
=cut
@@ -822,15 +975,22 @@
return ps;
}
+ VTABLE STRING *get_string_keyed_int_int(INTVAL base, INTVAL digits) {
+ char *s = bignum_get_string_size(INTERP, SELF, base, digits);
+ STRING *ps = Parrot_str_new(INTERP, s, 0);
+ mem_sys_free(s);
+ return ps;
+ }
+
VTABLE STRING *get_repr() {
STRING *s = SELF.get_string();
- return Parrot_str_append(INTERP, s, Parrot_str_new(interp, "L", 1));
+ return Parrot_str_append(INTERP, s, Parrot_str_new(interp, "N", 1));
}
/*
=item C<void increment()>
-Increments the integer.
+Increment the BigNum by 1.0.
=cut
@@ -844,7 +1004,7 @@
=item C<void decrement()>
-Decrements the integer.
+Decrement the BigNum by 1.0.
=cut
@@ -854,6 +1014,14 @@
bignum_sub_bignum_int(INTERP, SELF, 1, SELF);
}
+/*
+
+=item C<void add()>
+
+=cut
+
+*/
+
MULTI PMC *add(BigNum value, PMC *dest) {
dest = pmc_new(INTERP, SELF->vtable->base_type);
@@ -886,8 +1054,8 @@
bignum_add_bignum(INTERP, SELF, value, SELF);
}
- MULTI void i_add(Integer value) {
- bignum_add_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF);
+ MULTI void i_add(FLOATVAL value) {
+ bignum_add_bignum_float(INTERP, SELF, value, SELF);
}
MULTI void i_add(DEFAULT value) {
@@ -907,6 +1075,13 @@
"BigNum: no multiple dispatch variant 'i_add_float' for FLOATVAL");
}
+/*
+
+=item C<void substract()>
+
+=cut
+
+*/
MULTI PMC *subtract(BigNum value, PMC *dest) {
if (dest)
@@ -949,8 +1124,8 @@
bignum_sub_bignum(INTERP, SELF, value, SELF);
}
- MULTI void i_subtract(Integer value) {
- bignum_sub_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF);
+ MULTI void i_subtract(FLOATVAL value) {
+ bignum_sub_bignum_float(INTERP, SELF, value, SELF);
}
MULTI void i_subtract(DEFAULT value) {
@@ -970,6 +1145,13 @@
"BigNum: no multiple dispatch variant 'i_subtract_float' for FLOATVAL");
}
+/*
+
+=item C<void multiply()>
+
+=cut
+
+*/
MULTI PMC *multiply(BigNum value, PMC *dest) {
dest = pmc_new(INTERP, SELF->vtable->base_type);
@@ -1002,9 +1184,15 @@
MULTI void i_multiply(BigNum value) {
bignum_mul_bignum(INTERP, SELF, value, SELF);
}
+
+ MULTI void i_multiply(FLOATVAL value) {
+ bignum_mul_bignum_float(INTERP, SELF, value, SELF);
+ }
+
MULTI void i_multiply(Integer value) {
bignum_mul_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF);
}
+
MULTI void i_multiply(DEFAULT value) {
Parrot_ex_throw_from_c_args(INTERP, NULL,
EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
@@ -1022,6 +1210,14 @@
"BigNum: no multiple dispatch variant 'i_multiply_float' for FLOATVAL");
}
+/*
+
+=item C<void pow()>
+
+=cut
+
+*/
+
VTABLE PMC *pow_int(INTVAL value, PMC *dest) {
if (dest)
pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
@@ -1033,7 +1229,7 @@
}
MULTI PMC *pow(PMC *value, PMC *dest) {
- /* XXX only Integer RHS currently */
+ /* only Integer RHS currently. TODO: check number and bignum types */
INTVAL r = VTABLE_get_integer(INTERP, value);
dest = pmc_new(INTERP, SELF->vtable->base_type);
@@ -1041,8 +1237,16 @@
return dest;
}
+/*
+
+=item C<void divide()>
+
+=cut
+
+*/
+
MULTI PMC *divide(BigNum value, PMC *dest) {
- BIGNUM *bi;
+ BIGNUM *bn;
if (dest)
pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
else
@@ -1051,9 +1255,9 @@
bignum_div_bignum(INTERP, SELF, value, dest);
#if 0
/* to downgrade or not that's the question */
- GETATTR_BigNum_bi(interp, dest, bi);
- if (mpf_fits_slong_p(bi->b)) {
- long iresult = mpf_get_si(bi->b);
+ GETATTR_BigNum_bn(interp, dest, bn);
+ if (mpf_fits_slong_p(bn->b)) {
+ long iresult = mpf_get_si(bn->b);
VTABLE_morph(interp, dest, enum_class_Integer);
VTABLE_set_integer_native(interp, dest, iresult);
}
@@ -1105,6 +1309,14 @@
bignum_div_bignum_int(INTERP, SELF, value, SELF);
}
+/*
+
+=item C<void floor_divide()>
+
+=cut
+
+*/
+
MULTI PMC *floor_divide(BigNum value, PMC *dest) {
dest = pmc_new(INTERP, SELF->vtable->base_type);
@@ -1155,45 +1367,13 @@
bignum_fdiv_bignum_int(INTERP, SELF, value, SELF);
}
- MULTI PMC *modulus(BigNum value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_mod_bignum(INTERP, SELF, value, dest);
- return dest;
- }
-
- MULTI PMC *modulus(Integer value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
+/*
- bignum_mod_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), dest);
- return dest;
- }
+=item C<void cmp()>
- MULTI PMC *modulus(DEFAULT value, PMC *dest) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'modulus' for %Ss",
- VTABLE_name(interp, value));
- }
+=cut
- MULTI void i_modulus(BigNum value) {
- bignum_mod_bignum(INTERP, SELF, value, SELF);
- }
- MULTI void i_modulus(Integer value) {
- bignum_mod_bignum_int(INTERP, SELF, VTABLE_get_integer(interp, value), SELF);
- }
- MULTI void i_modulus(DEFAULT value) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'i_modulus' for %Ss",
- VTABLE_name(interp, value));
- }
+*/
MULTI INTVAL cmp(BigNum value) {
return bignum_cmp(INTERP, SELF, value);
@@ -1210,6 +1390,14 @@
VTABLE_name(interp, value));
}
+/*
+
+=item C<void is_equal()>
+
+=cut
+
+*/
+
MULTI INTVAL is_equal(BigNum value) {
return bignum_cmp(INTERP, SELF, value) == 0;
}
@@ -1272,166 +1460,6 @@
bignum_neg(INTERP, SELF, SELF);
}
-/*
-
-=item C<PMC *bitwise_shl(PMC *value, PMC *dest)>
-
-=item C<PMC *bitwise_shl_int(INTVAL value, PMC *dest)>
-
-Returns in C<*dest> the shift left of the BigNum by C<*value>.
-
-=item C<void i_bitwise_shl(PMC *value)>
-
-=item C<void i_bitwise_shl_int(INTVAL value)>
-
-Inplace shift left.
-
-=cut
-
-*/
-
- MULTI PMC *bitwise_shl(BigNum value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shl_bignum_int(INTERP, SELF,
- VTABLE_get_integer(INTERP, value),
- dest);
- return dest;
- }
-
- MULTI PMC *bitwise_shl(Integer value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shl_bignum_int(INTERP, SELF,
- VTABLE_get_integer(interp, value), dest);
- return dest;
- }
- MULTI PMC *bitwise_shl(DEFAULT value, PMC *dest) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'bitwise_shl' for %Ss",
- VTABLE_name(interp, value));
- }
-
- VTABLE PMC *bitwise_shl_int(INTVAL value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shl_bignum_int(INTERP, SELF, value, dest);
- return dest;
- }
-
-
- MULTI void i_bitwise_shl(BigNum value) {
- bignum_bitwise_shl_bignum_int(INTERP, SELF,
- VTABLE_get_integer(INTERP, value),
- SELF);
- }
-
- MULTI void i_bitwise_shl(Integer value) {
- bignum_bitwise_shl_bignum_int(INTERP, SELF,
- VTABLE_get_integer(interp, value), SELF);
- }
-
- MULTI void i_bitwise_shl(DEFAULT value) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'i_bitwise_shl' for %Ss",
- VTABLE_name(interp, value));
- }
-
- VTABLE void i_bitwise_shl_int(INTVAL value) {
- bignum_bitwise_shl_bignum_int(INTERP, SELF, value, SELF);
- }
-
-/*
-
-=item C<PMC *bitwise_shr(PMC *value, PMC *dest)>
-
-=item C<PMC *bitwise_shr_int(INTVAL value, PMC *dest)>
-
-Returns in C<*dest> the shift right of the BigNum by C<*value>.
-
-=item C<void i_bitwise_shr(PMC *value)>
-
-=item C<void i_bitwise_shr_int(INTVAL value)>
-
-Inplace shift left.
-
-=cut
-
-*/
-
- MULTI PMC *bitwise_shr(BigNum value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shr_bignum_int(INTERP, SELF,
- VTABLE_get_integer(INTERP, value),
- dest);
- return dest;
- }
-
- MULTI PMC *bitwise_shr(Integer value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shr_bignum_int(INTERP, SELF,
- VTABLE_get_integer(interp, value), dest);
- return dest;
- }
-
- MULTI PMC *bitwise_shr(DEFAULT value, PMC *dest) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'bitwise_shr' for %Ss",
- VTABLE_name(interp, value));
- }
-
- VTABLE PMC *bitwise_shr_int(INTVAL value, PMC *dest) {
- if (dest)
- pmc_reuse(interp, dest, SELF->vtable->base_type, 0);
- else
- dest = pmc_new(INTERP, SELF->vtable->base_type);
-
- bignum_bitwise_shr_bignum_int(INTERP, SELF, value, dest);
- return dest;
- }
-
-
- MULTI void i_bitwise_shr(BigNum value) {
- bignum_bitwise_shr_bignum_int(INTERP, SELF,
- VTABLE_get_integer(INTERP, value),
- SELF);
- }
-
- MULTI void i_bitwise_shr(Integer value) {
- bignum_bitwise_shr_bignum_int(INTERP, SELF,
- VTABLE_get_integer(interp, value), SELF);
- }
-
- MULTI void i_bitwise_shr(DEFAULT value) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INTERNAL_NOT_IMPLEMENTED,
- "BigNum: no multiple dispatch variant 'i_bitwise_shr' for %Ss",
- VTABLE_name(interp, value));
- }
-
- VTABLE void i_bitwise_shr_int(INTVAL value) {
- bignum_bitwise_shr_bignum_int(INTERP, SELF, value, SELF);
- }
}
/*
Added: trunk/t/pmc/bignum.t
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/t/pmc/bignum.t Sun Feb 15 16:56:01 2009 (r36765)
@@ -0,0 +1,651 @@
+#! perl
+# Copyright (C) 2009, The Perl Foundation.
+# $Id$
+
+use strict;
+use warnings;
+use lib qw( . lib ../lib ../../lib );
+
+use Test::More;
+use Parrot::Test;
+use Parrot::Config;
+
+=head1 NAME
+
+t/pmc/bignum.t - BigNum PMC
+
+=head1 SYNOPSIS
+
+ % prove t/pmc/bignum.t
+
+=head1 DESCRIPTION
+
+Tests the BigNum PMC.
+
+=cut
+
+if ( $PConfig{gmp} ) {
+ plan tests => 30;
+}
+else {
+ plan skip_all => "No BigNum PMC enabled";
+}
+
+my $vers_check = <<'EOP';
+.sub main :main
+ .local pmc b, ar
+ .local string v
+ .local int ma, mi, pa
+ b = new ['BigNum']
+ v = b.'version'()
+ ar = split '.', v
+ ma = ar[0]
+ mi = ar[1]
+ pa = ar[2]
+ if ma >= 4 goto ge_4
+warn:
+ print 'GMP version '
+ print v
+ say " is buggy with huge digit multiply - please upgrade"
+ end
+ge_4:
+ if mi >= 2 goto ok
+ if mi == 0 goto warn
+ # test 4.1.x
+ if pa >= 4 goto ok
+ goto warn
+ end
+ok:
+.end
+EOP
+
+if ( $PConfig{gmp} ) {
+
+ # argh
+ my $parrot = '.' . $PConfig{slash} . 'parrot' . $PConfig{exe};
+ my $test = 'temp_gmp_vers.pir';
+ open my $O, '>', "$test" or die "can't open $test: $!";
+ print $O $vers_check;
+ close $O;
+ my $warn = `$parrot $test`;
+ diag $warn if $warn;
+ unlink $test;
+}
+
+pasm_output_is( <<'CODE', <<'OUT', "create" );
+ new P0, ['BigNum']
+ say "ok"
+ end
+CODE
+ok
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "set/get int" );
+ new P0, ['BigNum']
+ set P0, 999999
+ set I1, P0
+ say I1
+ get_repr S0, P0
+ say S0
+ end
+CODE
+999999
+999999N
+OUT
+
+pasm_output_is( <<"CODE", <<'OUT', "set int, get double" );
+ .include 'include/fp_equality.pasm'
+ new P0, ['BigNum']
+ set P0, 999999
+ set N1, P0
+ .fp_eq_pasm(N1, 999999.0, OK1)
+ print "not "
+OK1: say "ok 1"
+
+ set P0, -999999
+ set N1, P0
+ .fp_eq_pasm(N1, -999999.0, OK2)
+ print "not "
+OK2: say "ok 2"
+
+ set P0, 2147483646
+ set N1, P0
+ .fp_eq_pasm(N1, 2.147483646e9, OK3)
+ print "not "
+OK3: say "ok 3"
+
+ set P0, -2147483646
+ set N1, P0
+ .fp_eq_pasm(N1, -2.147483646e9, OK4)
+ print "not "
+OK4: say "ok 4"
+ end
+CODE
+ok 1
+ok 2
+ok 3
+ok 4
+OUT
+
+my @todo_str = ( todo => "bignum strings");
+pasm_output_is( <<'CODE', <<'OUT', "set double, get str", @todo_str );
+ new P0, ['BigNum']
+ set P0, 1.23e12
+ say P0
+ set P0, "1230000000000.0000000000000000122"
+ say P0
+ end
+CODE
+1230000000000
+1230000000000.0000000000000000122
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "add", @todo_str);
+ new P0, ['BigNum']
+ set P0, 999999.5
+ new P1, ['BigNum']
+ set P1, 1000000.5
+ new P2, ['BigNum']
+ add P2, P0, P1
+ set S0, P2
+ say S0
+ set P0, "12345678987654321"
+ set P1, "10000000000000000"
+ add P2, P1, P0
+ set S0, P2
+ say S0
+ end
+CODE
+2000000
+22345678987654321
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "add_int", @todo_str );
+ new P0, ['BigNum']
+ set P0, 999999
+ new P2, ['BigNum']
+ add P2, P0, 1000000
+ set S0, P2
+ say S0
+ set P0, "100000000000000000000"
+ add P2, P0, 1000000
+ set S0, P2
+ say S0
+ end
+CODE
+1999999
+100000000000001000000
+OUT
+
+pasm_output_is( <<'CODE', <<'OUTPUT', "sub bignum" );
+ new P0, ['BigNum']
+ set P0, 12345678
+ new P1, ['BigNum']
+ set P1, 5678
+ new P2, ['BigNum']
+ sub P2, P0, P1
+ set I0, P2
+ eq I0, 12340000, OK1
+ print "not "
+OK1: say "ok 1"
+ set P0, "123456789012345678"
+ sub P2, P0, P1
+ new P3, ['BigNum']
+ set P3, "123456789012340000"
+ eq P2, P3, OK2
+ print "not "
+OK2: say "ok 2"
+ set P1, "223456789012345678"
+ sub P2, P0, P1
+ set P3, "-100000000000000000"
+ eq P2, P3, OK3
+ print "not "
+OK3: say "ok 3"
+ end
+CODE
+ok 1
+ok 2
+ok 3
+OUTPUT
+
+pasm_output_is( <<'CODE', <<'OUTPUT', "sub native int" );
+ new P0, ['BigNum']
+ set P0, 12345678
+ new P2, ['BigNum']
+ sub P2, P0, 5678
+ set I0, P2
+ eq I0, 12340000, OK1
+ print "not "
+OK1: say "ok 1"
+ set P0, "123456789012345678"
+ sub P2, P0, 5678
+ new P3, ['BigNum']
+ set P3, "123456789012340000"
+ eq P2, P3, OK2
+ print "not "
+OK2: say "ok 2"
+ end
+CODE
+ok 1
+ok 2
+OUTPUT
+
+pasm_output_is( <<'CODE', <<'OUTPUT', "sub other int" );
+ new P0, ['BigNum']
+ set P0, 12345678
+ new P1, ['Integer']
+ set P1, 5678
+ new P2, ['BigNum']
+ sub P2, P0, P1
+ set I0, P2
+ eq I0, 12340000, OK1
+ print "not "
+OK1: say "ok 1"
+ set P0, "123456789012345678"
+ sub P2, P0, P1
+ new P3, ['BigNum']
+ set P3, "123456789012340000"
+ eq P2, P3, OK2
+ print "not "
+OK2: say "ok 2"
+ set P0, 9876543
+ new P4, ['Integer']
+ set P4, 44
+ sub P2, P0, P4
+ set I0, P2
+ eq I0, 9876499, OK3
+ print "not "
+OK3: say "ok 3"
+ set P0, "9876543219876543"
+ sub P2, P0, P4
+ set P3, "9876543219876499"
+ eq P3, P2, OK4
+ print "not "
+OK4: say "ok 4"
+ end
+CODE
+ok 1
+ok 2
+ok 3
+ok 4
+OUTPUT
+
+pasm_output_is( <<'CODE', <<'OUT', "mul", @todo_str );
+ new P0, ['BigNum']
+ set P0, 999.999
+ new P1, ['BigNum']
+ set P1, 10.000005
+ new P2, ['BigNum']
+ mul P2, P0, P1
+ set S0, P2
+ say S0
+ end
+CODE
+9999.994999995
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "mul_float", @todo_str);
+ new P0, ['BigNum']
+ set P0, 999.999
+ mul P2, P0, 10.000005
+ say P2
+ end
+CODE
+9999.994999995
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "div bignum" );
+ new P0, ['BigNum']
+ set P0, "100000000000000000000"
+ new P1, ['BigNum']
+ set P1, "100000000000000000000"
+ new P2, ['BigNum']
+ div P2, P0, P1
+ set I0, P2
+ eq I0, 1, OK1
+ print "not "
+OK1: say "ok 1"
+
+ new P3, ['BigNum']
+ set P3, "10000000000000"
+ set P1, 10000000
+ div P2, P0, P1
+ eq P2, P3, OK2
+ print "not "
+OK2: say "ok 2"
+
+ set P1, 10
+ set P3, "10000000000000000000"
+ div P2, P0, P1
+ eq P2, P3, OK3
+ print "not "
+OK3: say "ok 3"
+
+ set P1, -1
+ set P3, "-100000000000000000000"
+ div P2, P0, P1
+ eq P2, P3, OK4
+ print "not "
+OK4: say "ok 4"
+ end
+CODE
+ok 1
+ok 2
+ok 3
+ok 4
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "div native int" );
+ new P0, ['BigNum']
+ set P0, "100000000000000000000"
+ new P1, ['BigNum']
+ div P1, P0, 10
+ new P2, ['BigNum']
+ set P2, "10000000000000000000"
+ eq P1, P2, OK1
+ print "not "
+OK1: say "ok 1"
+
+ set P0, "100000000000000"
+ div P1, P0, 10000000
+ set P2, 10000000
+ eq P1, P2, OK2
+ print "not "
+OK2: say "ok 2"
+ end
+CODE
+ok 1
+ok 2
+OUT
+
+pasm_output_is( <<'CODE', <<'OUT', "div other int" );
+ new P0, ['BigNum']
+ set P0, "100000000000000000000"
+ new P1, ['BigNum']
+ new P3, ['Integer']
+ set P3, 10
+ div P1, P0, P3
+ new P2, ['BigNum']
+ set P2, "10000000000000000000"
+ eq P1, P2, OK1
+ print "not "
+OK1: say "ok 1"
+
+ set P0, "100000000000000"
+ new P4, ['Integer']
+ set P4, 10000000
+ div P1, P0, P4
+ set P2, 10000000
+ eq P1, P2, OK2
+ print "not "
+OK2: say "ok 2"
+ end
+CODE
+ok 1
+ok 2
+OUT
+
+my @todo_ov = ( todo => "bignum overflow" );
+for my $op ( "/", "%" ) {
+ for my $type ( "BigNum", "Integer" ) {
+ pir_output_is( <<"CODE", <<OUTPUT, "bignum $op by zero $type", $op eq '/' ? () : @todo_str );
+.sub _main :main
+ \$P0 = new ['BigNum']
+ set \$P0, "1000000000000000000000"
+ \$P1 = new ['BigNum']
+ ## divide by a zero $type
+ \$P2 = new ['$type']
+ set \$P2, 0
+ push_eh OK
+ \$P1 = \$P0 $op \$P2
+ say "fail"
+ pop_eh
+OK:
+ get_results '0', \$P0
+ \$S0 = \$P0
+ say "ok"
+ say \$S0
+.end
+CODE
+ok
+Divide by zero
+OUTPUT
+ }
+}
+
+{
+ my ( $a, $b, $c, $d, $e );
+ if ( $PConfig{intvalsize} == 8 ) {
+ $a = '9223372036854775806'; # 2**63-2
+ $b = '1';
+ $c = '9223372036854775807'; # still Integer
+ $d = '9223372036854775808'; # no more Integer
+ $e = '9223372036854775809'; # still no more Integer
+ }
+ elsif ( $PConfig{intvalsize} == 4 ) {
+ $a = '2147483646'; # 2**31-2
+ $b = '1';
+ $c = '2147483647'; # still Integer
+ $d = '2147483648'; # no more PerlInt
+ $e = '2147483649'; # still no more PerlInt
+ }
+ else {
+ die "\$PConfig{intvalsize} == $PConfig{intvalsize}?\n";
+ }
+
+ pasm_output_is( <<CODE, <<OUT, "add overflow Integer", @todo_ov );
+ new P0, ['Integer']
+ set P0, $a
+ new P1, ['Integer']
+ set P1, $b
+ new P2, ['Integer']
+ new P3, ['BigNum']
+ set I3, 3
+lp:
+ add P2, P0, P1
+ set S0, P2
+ print S0
+ print " "
+ typeof S1, P2
+ say S1
+ add P1, $b
+ dec I3
+ if I3, lp
+ say "ok"
+ex:
+ end
+CODE
+$c Integer
+$d BigNum
+$e BigNum
+ok
+OUT
+
+ pasm_output_is( <<CODE, <<OUT, "add overflow Integer", @todo_ov );
+ new P0, ['Integer']
+ set P0, $a
+ new P1, ['Integer']
+ set P1, $b
+ new P2, ['Integer']
+ new P3, ['BigNum']
+ set I3, 3
+lp:
+ add P2, P0, P1
+ set S0, P2
+ print S0
+ print " "
+ typeof S1, P2
+ say S1
+ add P1, $b
+ dec I3
+ if I3, lp
+ say "ok"
+ex:
+ end
+CODE
+$c Integer
+$d BigNum
+$e BigNum
+ok
+OUT
+}
+
+pasm_output_is( <<'CODE', <<'OUT', "abs", @todo_str );
+ new P0, ['BigNum']
+ set P0, "-1230000000000"
+ new P1, ['Undef']
+ abs P1, P0
+ say P1
+ say P0
+ abs P0
+ say P0
+ end
+CODE
+1230000000000
+-1230000000000
+1230000000000
+OUT
+
+pir_output_is( << 'CODE', << 'OUTPUT', "check whether interface is done" );
+
+.sub _main
+ .local pmc pmc1
+ pmc1 = new ['BigNum']
+ .local int bool1
+ does bool1, pmc1, "scalar"
+ say bool1
+ does bool1, pmc1, "no_interface"
+ say bool1
+ end
+.end
+CODE
+1
+0
+OUTPUT
+
+pasm_output_is( <<"CODE", <<'OUTPUT', "Truth" );
+ new P0, ['BigNum']
+ set P0, "123456789123456789"
+ if P0, OK1
+ print "not "
+OK1: say "ok 1"
+ set P0, 0
+ unless P0, OK2
+ print "not "
+OK2: say "ok 2"
+ end
+CODE
+ok 1
+ok 2
+OUTPUT
+
+pasm_output_is( <<"CODE", <<'OUTPUT', "neg" );
+ new P0, ['BigNum']
+ new P1, ['BigNum']
+ set P0, "123456789123456789"
+ neg P0
+ set P1, "-123456789123456789"
+ eq P0, P1, OK1
+ print "not "
+OK1: say "ok 1"
+ end
+CODE
+ok 1
+OUTPUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 gt" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b > 4 goto ok
+ say "never"
+ end
+ok:
+ say "ok"
+.end
+CODE
+ok
+OUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 ge" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b >= 4 goto ok
+ say "never"
+ end
+ok:
+ say "ok"
+.end
+CODE
+ok
+OUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 ne" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b != 4 goto ok
+ say "never"
+ end
+ok:
+ say "ok"
+.end
+CODE
+ok
+OUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 eq" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b == 4 goto nok
+ say "ok"
+ end
+nok:
+ say "nok"
+.end
+CODE
+ok
+OUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 le" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b <= 4 goto nok
+ say "ok"
+ end
+nok:
+ say "nok"
+.end
+CODE
+ok
+OUT
+
+pir_output_is( <<'CODE', <<'OUT', "BUG #34949 lt" );
+.sub main :main
+ .local pmc b
+ b = new ['BigNum']
+ b = 1e10
+ if b < 4 goto nok
+ say "ok"
+ end
+nok:
+ say "nok"
+.end
+CODE
+ok
+OUT
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:
More information about the parrot-commits
mailing list