cvsuser 04/12/09 15:22:46
Modified: dynclasses pycomplex.pmc pylong.pmc
Log:
Take advantage of MMD inheritance. Still much more todo, but this
continues to passes the tests which I have gotten to passed to date.
Revision Changes Path
1.3 +13 -790 parrot/dynclasses/pycomplex.pmc
Index: pycomplex.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pycomplex.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- pycomplex.pmc 7 Dec 2004 19:48:49 -0000 1.2
+++ pycomplex.pmc 9 Dec 2004 23:22:46 -0000 1.3
@@ -1,6 +1,6 @@
/*
Copyright: 2004 The Perl Foundation. All Rights Reserved.
-$Id: pycomplex.pmc,v 1.2 2004/12/07 19:48:49 rubys Exp $
+$Id: pycomplex.pmc,v 1.3 2004/12/09 23:22:46 rubys Exp $
=head1 NAME
@@ -22,823 +22,46 @@
#include "parrot/parrot.h"
-#define RE(obj) (((FLOATVAL*)PMC_struct_val(obj))[0])
-#define IM(obj) (((FLOATVAL*)PMC_struct_val(obj))[1])
-
-/* cache of classes referenced */
-static INTVAL dynclass_PyComplex;
-
-/*
-
-=item C<static void
-complex_parse_string (Parrot_Interp interp,
- FLOATVAL *re, FLOATVAL *im, STRING *value)>
-
-Parses the string in C<value> to produce a complex number, represented
-by the real (C<*re>) and imaginary (C<*im>) parts. Raises an exception
-if it cannot understand the string. The string should be of the form
-C<a+bi> with optional spaces around C<+> and before C<i>. You can also
-use C<j> instead of C<i>.
-
-=cut
-
-*/
-
-static void
-complex_parse_string (Parrot_Interp interp,
- FLOATVAL *re, FLOATVAL *im, STRING *value) {
- char *str;
- INTVAL first_num_length, second_num_length;
- INTVAL first_num_minus, second_num_minus, i;
- char *first_num_offset, *second_num_offset = NULL, *t;
- STRING *S;
-
- t = str = string_to_cstring(interp, value);
- i = 0;
- first_num_offset = str;
- first_num_minus = second_num_minus = 0;
-
- /* walk the string and identify the real and imaginary parts */
-
- if(*t == '-') {
- /* first number is negative */
- t++;
- first_num_minus = 1;
- if(*t == ' ') t++; /* allow for an optional space */
- first_num_offset = t;
- }
- while(*t >= '0' && *t <= '9') t++; /* skip digits */
- if(*t == '.') {
- /* this number has a decimal point */
- t++;
- while(*t >= '0' && *t <= '9') t++; /* skip digits */
- }
- /* save the length of the real part */
- first_num_length = t - first_num_offset;
-
- if(*t == 0) {
- /* end of string; we only have a real part */
- second_num_length = 0;
- }
- else if( (*t == 'i' || *t == 'j') && *(t+1) == 0 ) {
- /* there is only an imaginary part, so the first number was
- actually the imaginary part */
- second_num_length = first_num_length;
- first_num_length = 0;
- second_num_offset = first_num_offset;
- second_num_minus = first_num_minus;
- /* this is useful if there is no number for
- the imaginary part, like in "-i" */
- i = 1;
- }
- else {
- if(*t == ' ') t++; /* skip an optional space */
- /* expect "+" or "-" and the imaginary part */
- if(*t == '+' || *t == '-') {
- second_num_minus = (*t == '-'); /* save the sign */
- t++;
- if(*t == ' ') t++; /* skip another optional space */
-
- /* save the beginning of the imaginary part */
- second_num_offset = t;
- while(*t >= '0' && *t <= '9') t++; /* skip digits */
- if(*t == '.') {
- /* this number has a decimal point */
- t++;
- while(*t >= '0' && *t <= '9') t++; /* skip digits */
- }
- /* save the length of the imaginary part */
- second_num_length = t - second_num_offset;
-
- if(*t == ' ') t++; /* allow for one more optional space */
-
- /* verify that the string ends properly */
- if( (*t != 'i' && *t != 'j') || (*(t+1) != 0) ) {
- /* imaginary part does not end in 'i' or 'j' */
- internal_exception(INVALID_STRING_REPRESENTATION,
- "Complex: malformed string\n");
- first_num_length = second_num_length = 0;
- }
- /* this is useful if there is no number for the
- imaginary part, like in "2+i" */
- i = 1;
-
- /* all is OK, save the number */
- }
- else {
- /* "+" or "-" not found: error */
- internal_exception(INVALID_STRING_REPRESENTATION,
- "Complex: malformed string\n");
- first_num_length = second_num_length = 0;
- }
- }
-
- /* now we have the offsets and the lengths;
- we turn them into float values */
-
- if(first_num_length) {
- /* there is a real part, interpret it */
- S = string_from_cstring(interp,
- first_num_offset, first_num_length);
- *re = string_to_num(interp, S);
- }
- else {
- /* consider the real part 0.0 */
- *re = 0.0;
- }
-
- if(second_num_length) {
- /* there is an imaginary part, interpret it */
- S = string_from_cstring(interp,
- second_num_offset, second_num_length);
- *im = string_to_num(interp, S);
- }
- else {
- /* consider the imaginary part 0.0 */
- if(i) /* the string was something like "1+i" */
- *im = 1.0;
- else
- *im = 0.0;
- }
- if(first_num_minus) *re = - *re;
- if(second_num_minus) *im = - *im;
-
- string_cstring_free(str);
-}
-
-/*
-
-=item C<static FLOATVAL*
-complex_locate_keyed_num(Parrot_Interp interp, PMC* self, STRING *key)>
-
-Interpret the string C<key>; valid keys are C<real> and C<imag>,
-representing the real and imaginary parts of the complex number.
-
-=cut
-
-*/
-
-static FLOATVAL*
-complex_locate_keyed_num(Parrot_Interp interp, PMC* self, STRING *key) {
- /* do imag first since real can be read much faster anyway */
- STRING *imag = string_from_cstring(interp, "imag", 4);
- STRING *real;
-
- if(0 == string_equal(interp, key, imag))
- return &IM(self);
- real = string_from_cstring(interp, "real", 4);
- if(0 == string_equal(interp, key, real))
- return &RE(self);
- internal_exception(KEY_NOT_FOUND,
- "Complex: key is neither 'real' or 'imag'\n");
- return NULL;
-}
-
-pmclass PyComplex extends PyObject dynpmc group python_group {
+pmclass PyComplex extends Complex dynpmc group python_group {
/*
-=item C<void class_init()>
-
-Class initialization. Caches the type id of various PMCs because
-they will be used frequently here.
-
-=cut
-
-*/
-
- void class_init() {
- if (pass) {
- dynclass_PyComplex = Parrot_PMC_typenum(INTERP, "PyComplex");
- }
- }
-
-
-/*
-
-=item C<PMC* new_extended()>
-
-Create a new complex PMC with passed arguments according to pdd03.
-
-=cut
-
-*/
-
- PMC* new_extended() {
- PMC *res = pmc_new(interpreter, dynclass_PyComplex);
- FLOATVAL re = 0.0, im = 0.0;
- int argcI = REG_INT(1);
- int argcS = REG_INT(2);
- int argcP = REG_INT(3);
- int argcN = REG_INT(4);
- /*
- * we can only allow 0..2 arguments of one kind. For
- * mixed (e.g. N,P) args the order of arguments isn't fixed
- */
- if (argcP) {
- re = VTABLE_get_number(INTERP, REG_PMC(5));
- if (argcP == 2)
- im = VTABLE_get_number(INTERP, REG_PMC(6));
- /*
- * TODO throw exception if argument mismatch
- */
- }
- else if (argcN) {
- re = REG_NUM(5);
- if (argcN == 2)
- im = REG_NUM(6);
- }
- else if (argcI) {
- re = REG_INT(5);
- if (argcI == 2)
- im = REG_INT(6);
- }
- else if (argcS == 1) {
- complex_parse_string(INTERP, &RE(res), &IM(res), REG_STR(5));
- return res;
- }
- RE(res) = re;
- IM(res) = im;
- return res;
- }
-
-/*
-
-=item C<void* invoke(void* next)>
-
-Pythonic object constructor. SELF is a Complex Class object. Return a new
-C<complex> object according to 2.1. Built-in Functions.
-
-=cut
-
-*/
- void* invoke(void* next) {
- int argcP = REG_INT(3);
- PMC *res = pmc_new(interpreter, dynclass_PyComplex);
- if (argcP == 1) {
- PMC *arg = REG_PMC(5);
- if (arg->vtable->base_type == enum_class_PerlString) {
- VTABLE_set_string_native(INTERP, res, PMC_str_val(arg));
- }
- else
- RE(res) = VTABLE_get_number(interpreter, arg);
- }
- else if (argcP == 2) {
- RE(res) = VTABLE_get_number(interpreter, REG_PMC(5));
- IM(res) = VTABLE_get_number(interpreter, REG_PMC(6));
- }
- REG_PMC(5) = res;
- return next;
- }
-
-/*
-
-=back
-
-=head2 Methods
-
-=over 4
-
-=item C<void init()>
-
-Initializes the complex number with the value 0+0i.
-
-=item C<void init_pmc (PMC* initializer)>
-
-Initializes the complex number with the specified values.
-(not implemented)
-
-=item C<void destroy ()>
-
-Cleans up.
-
-=item C<PMC* clone ()>
-
-Creates an identical copy of the complex number.
-
-=cut
-
-*/
-
- void init () {
- /* XXX should check if mem_sys_allocate failed */
- FLOATVAL* data = (FLOATVAL*)mem_sys_allocate(2 * sizeof(FLOATVAL));
- PMC_struct_val(SELF) = data;
- PObj_active_destroy_SET(SELF);
- RE(SELF) = IM(SELF) = 0.0;
- }
-
- void init_pmc (PMC* initializer) {
- /* XXX not implemented */
- DYNSELF.init();
- }
-
- void destroy () {
- mem_sys_free(PMC_struct_val(SELF));
- PMC_struct_val(SELF) = NULL;
- }
-
- void morph (INTVAL type) {
- if (SELF->vtable->base_type == type)
- return;
- SUPER(type);
- }
-
- PMC* clone () {
- PMC* dest = pmc_new_noinit(INTERP, SELF->vtable->base_type);
- FLOATVAL* data = (FLOATVAL*)mem_sys_allocate(2 * sizeof(FLOATVAL));
- PMC_struct_val(dest) = data;
- PObj_active_destroy_SET(dest);
- RE(dest) = RE(SELF);
- IM(dest) = IM(SELF);
- return dest;
- }
-
-/*
-
-=item C<INTVAL get_integer ()>
-
-Returns the modulus of the complex number as an integer.
-
-=item C<FLOATVAL get_number ()>
-
-Returns the modulus of the complex number.
-
=item C<STRING* get_string ()>
Returns the complex number as a string in the form C<a+bi>.
-=item C<INTVAL get_bool ()>
-
-Returns true if the complex number is non-zero.
-
=cut
*/
- INTVAL get_integer () {
- return (INTVAL)(DYNSELF.get_number());
- }
-
- FLOATVAL get_number () {
- return sqrt(RE(SELF)*RE(SELF) + IM(SELF)*IM(SELF));
- }
-
STRING* get_string () {
STRING *s;
- if (RE(SELF) == 0) {
- s = Parrot_sprintf_c(INTERP, "%.12vgj", IM(SELF));
+ FLOATVAL real = VTABLE_get_number_keyed_int(INTERP, SELF, 0);
+ FLOATVAL imag = VTABLE_get_number_keyed_int(INTERP, SELF, 1);
+ if (real == 0.0) {
+ s = Parrot_sprintf_c(INTERP, "%.12vgj", imag);
}
- else if (IM(SELF) >= 0)
+ else if (imag >= 0.0)
s = Parrot_sprintf_c(INTERP,
- "(%.12vg+%.12vgj)", RE(SELF), IM(SELF));
+ "(%.12vg+%.12vgj)", real, imag);
else
s = Parrot_sprintf_c(INTERP,
- "(%.12vg-%.12vgj)", RE(SELF), -IM(SELF));
+ "(%.12vg-%.12vgj)", real, -imag);
return s;
}
- INTVAL get_bool () {
- return (INTVAL)(RE(SELF) != 0.0 || IM(SELF) != 0.0);
- }
-
-/*
-
-=item C<INTVAL get_integer_keyed (PMC* key)>
-
-=item C<INTVAL get_integer_keyed_str (STRING* key)>
-
-=item C<FLOATVAL get_number_keyed (PMC* key)>
-
-=item C<FLOATVAL get_number_keyed_str (STRING* key)>
-
-=item C<PMC* get_pmc_keyed (PMC* key)>
-
-=item C<PMC* get_pmc_keyed_str (STRING* key)>
-
-Returns the requested number (real part for C<real> and imaginary for
C<imag>).
-
-=cut
-
-*/
-
- INTVAL get_integer_keyed (PMC* key) {
- STRING* s = VTABLE_get_string(INTERP, key);
- return DYNSELF.get_integer_keyed_str(s);
- }
-
- INTVAL get_integer_keyed_str (STRING* key) {
- return (INTVAL)(DYNSELF.get_number_keyed_str(key));
- }
-
- FLOATVAL get_number_keyed (PMC* key) {
- STRING* s = VTABLE_get_string(INTERP, key);
- return DYNSELF.get_number_keyed_str(s);
- }
-
- FLOATVAL get_number_keyed_str (STRING* key) {
- FLOATVAL *num = complex_locate_keyed_num(INTERP, SELF, key);
- if(num)
- return *num;
- return 0.0;
- }
-
- PMC* get_pmc_keyed (PMC* key) {
- STRING* s = VTABLE_get_string(INTERP, key);
- return DYNSELF.get_pmc_keyed_str(s);
- }
-
- PMC* get_pmc_keyed_str (STRING* key) {
- PMC *ret;
- FLOATVAL val;
-
- ret = pmc_new(INTERP, enum_class_Float);
- val = DYNSELF.get_number_keyed_str(key);
- VTABLE_set_number_native(INTERP, ret, val);
- return ret;
- }
-
-/*
-
-=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
-
-Quick hack to emulate get_real() and get_imag():
-
- key = 0 ... get real part
- key = 1 ... get imag part
-
-=item C<void set_number_keyed_int(INTVAL key, FLOATVAL v)>
-
-Set real or imag dependig on key
-
-*/
-
- FLOATVAL get_number_keyed_int(INTVAL key) {
- switch (key) {
- case 0:
- return RE(SELF);
- case 1:
- return IM(SELF);
- default:
- internal_exception(1, "Complex: key must be 0 or 1");
- }
- return 0.0;
- }
-
- void set_number_keyed_int(INTVAL key, FLOATVAL v) {
- switch (key) {
- case 0:
- RE(SELF) = v;
- break;
- case 1:
- IM(SELF) = v;
- break;
- default:
- internal_exception(1, "Complex: key must be 0 or 1");
- }
- }
-/*
-
-=item C<void set_string_native (STRING* value)>
-
-Parses the string C<value> into a complex number; raises an exception on
failure.
-
-=item C<void set_pmc (PMC* value)>
-
-if C<value> is a Complex PMC then the complex number is set to its value;
otherwise
-C<value>'s string representation is parsed with C<set_string_native()>.
-
-=item C<void set_integer_native (INTVAL value)>
-
-=item C<void set_number_native (FLOATVAL value)>
-
-Sets the real part of the complex number to C<value> and the imaginary
-part to C<0.0>
-
-=cut
-
-*/
-
- void set_string_native (STRING* value) {
- complex_parse_string(INTERP, &RE(SELF), &IM(SELF), value);
- }
-
- void set_pmc (PMC* value) {
- if(value->vtable->base_type == dynclass_PyComplex) {
- RE(SELF) = RE(value);
- IM(SELF) = IM(value);
- }
- else {
- DYNSELF.set_string_native(VTABLE_get_string(INTERP, value));
- }
- }
-
- void set_integer_native (INTVAL value) {
- DYNSELF.set_number_native(value);
- }
-
- void set_number_native (FLOATVAL value) {
- RE(SELF) = value;
- IM(SELF) = 0.0;
- }
-
/*
-=item C<void set_integer_keyed (PMC* key, INTVAL value)>
-
-=item C<void set_integer_keyed_str (STRING* key, INTVAL value)>
-
-=item C<void set_number_keyed (PMC* key, FLOATVAL value)>
-
-=item C<void set_number_keyed_str (STRING* key, FLOATVAL value)>
+=item C<STRING *get_repr()>
-=item C<void set_pmc_keyed (PMC* key, PMC* value)>
-
-=item C<void set_pmc_keyed_str (STRING* key, PMC* value)>
-
-Sets the requested number (real part for C<real> and imaginary for C<imag>)
-to C<value>.
+Returns the string representation of the integer.
=cut
*/
- void set_integer_keyed (PMC* key, INTVAL value) {
- DYNSELF.set_number_keyed(key, value);
- }
-
- void set_integer_keyed_str (STRING* key, INTVAL value) {
- DYNSELF.set_number_keyed_str(key, value);
- }
-
- void set_number_keyed (PMC* key, FLOATVAL value) {
- STRING* s = VTABLE_get_string(INTERP, key);
- DYNSELF.set_number_keyed_str(s, value);
- }
-
- void set_number_keyed_str (STRING* key, FLOATVAL value) {
- FLOATVAL *num = complex_locate_keyed_num(INTERP, SELF, key);
- if(num)
- *num = value;
- }
-
- void set_pmc_keyed (PMC* key, PMC* value) {
- FLOATVAL f = VTABLE_get_number(INTERP, value);
- DYNSELF.set_number_keyed(key, f);
- }
-
- void set_pmc_keyed_str (STRING* key, PMC* value) {
- FLOATVAL f = VTABLE_get_number(INTERP, value);
- DYNSELF.set_number_keyed_str(key, f);
- }
-
-/*
-
-=item C<void add (PMC* value, PMC* dest)>
-
-=item C<void add_int (INTVAL value, PMC* dest)>
-
-=item C<void add_float (FLOATVAL value, PMC* dest)>
-
-Adds C<value> to the complex number, placing the result in C<dest>.
-
-=cut
-
-*/
-
- void add (PMC* value, PMC* dest) {
-MMD_PyComplex: {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) + RE(value);
- IM(dest) = IM(SELF) + IM(value);
- }
-MMD_DEFAULT: {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) + VTABLE_get_number(INTERP, value);
- IM(dest) = IM(SELF);
- }
- }
-
- void add_int (INTVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) + value;
- IM(dest) = IM(SELF);
- }
-
- void add_float (FLOATVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) + value;
- IM(dest) = IM(SELF);
- }
-
-/*
-
-=item C<void subtract (PMC* value, PMC* dest)>
-
-=item C<void subtract_int (INTVAL value, PMC* dest)>
-
-=item C<void subtract_float (FLOATVAL value, PMC* dest)>
-
-Subtracts C<value> from the complex number, placing the result in C<dest>.
-
-=cut
-
-*/
-
- void subtract (PMC* value, PMC* dest) {
-MMD_PyComplex: {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) - RE(value);
- IM(dest) = IM(SELF) - IM(value);
- }
-MMD_DEFAULT: {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) - VTABLE_get_number(INTERP, value);
- IM(dest) = IM(SELF);
- }
- }
-
- void subtract_int (INTVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) - value;
- IM(dest) = IM(SELF);
- }
-
- void subtract_float (FLOATVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) - value;
- IM(dest) = IM(SELF);
- }
-
-/*
-
-=item C<void multiply (PMC* value, PMC* dest)>
-
-=item C<void multiply_int (INTVAL value, PMC* dest)>
-
-=item C<void multiply_float (FLOATVAL value, PMC* dest)>
-
-Multiplies the complex number with C<value>, placing the result in C<dest>.
-
-=cut
-
-*/
-
-/*
-
- TODO for better precision:
-
- (a+ib)(c+id)=(ac-bd)+i((a+b)(c+d)-ac-bd).
-
-*/
- void multiply (PMC* value, PMC* dest) {
-MMD_PyInt: {
- FLOATVAL re = RE(SELF) * PMC_int_val(value);
- FLOATVAL im = IM(SELF) * PMC_int_val(value);
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = re;
- IM(dest) = im;
- }
-MMD_PyComplex: {
- FLOATVAL re = RE(SELF) * RE(value) - IM(SELF) * IM(value);
- FLOATVAL im = IM(SELF) * RE(value) + RE(SELF) * IM(value);
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = re;
- IM(dest) = im;
- }
-MMD_DEFAULT: {
- FLOATVAL re = RE(SELF) * VTABLE_get_number(INTERP, value);
- FLOATVAL im = IM(SELF) * VTABLE_get_number(INTERP, value);
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = re;
- IM(dest) = im;
- }
- }
-
- void multiply_int (INTVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) * value;
- IM(dest) = IM(SELF) * value;
- }
-
- void multiply_float (FLOATVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) * value;
- IM(dest) = IM(SELF) * value;
- }
-
-/*
-
-=item C<void divide (PMC* value, PMC* dest)>
-
-=item C<void divide_int (INTVAL value, PMC* dest)>
-
-=item C<void divide_float (FLOATVAL value, PMC* dest)>
-
-Divide the complex number by C<value>, placing the result in C<dest>.
-
-=cut
-
-*/
-
- void divide (PMC* value, PMC* dest) {
-MMD_PyComplex: {
- FLOATVAL mod, re, im;
-
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- /* a little speed optimisation: cache an intermediate number;
- i'm not sure the compiler does this */
- mod = (RE(value) * RE(value) + IM(value) * IM(value));
-
- re = (RE(SELF) * RE(value) + IM(SELF) * IM(value)) / mod;
-
- im = (IM(SELF) * RE(value) - RE(SELF) * IM(value)) / mod;
-
- RE(dest) = re;
- IM(dest) = im;
- }
-MMD_DEFAULT: {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) / VTABLE_get_number(INTERP, value);
- IM(dest) = IM(SELF) / VTABLE_get_number(INTERP, value);
- }
- }
-
- void divide_int (INTVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) / value;
- IM(dest) = IM(SELF) / value;
- }
-
- void divide_float (FLOATVAL value, PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = RE(SELF) / value;
- IM(dest) = IM(SELF) / value;
- }
-
-
-/*
-
-=item C<void neg(PMC *dest)>
-
-Set C<dest> to the negated value of C<SELF>.
-
-=cut
-
-*/
-
- void neg (PMC* dest) {
- VTABLE_morph(INTERP, dest, dynclass_PyComplex);
- RE(dest) = - RE(SELF);
- IM(dest) = - IM(SELF);
- }
-
-/*
-
-=item C<INTVAL is_equal (PMC* value)>
-
-Compares the complex number with C<value> and returs true if they are equal.
-
-=cut
-
-*/
-
- INTVAL is_equal (PMC* value) {
- if(value->vtable->base_type == dynclass_PyComplex)
- return (INTVAL)(
- RE(SELF) == RE(value) &&
- IM(SELF) == IM(value)
- );
- if(IM(SELF) != 0.0)
- return (INTVAL)0;
- return (RE(SELF) == VTABLE_get_number(INTERP, value));
- }
-
-/*
-
-=item C<void absolute()>
-
-Sets C<dest> to the absolute value of SELF that is the distance from (0.0).
-
-=cut
-
-*/
-
-/*
-
- TODO for better precision: hinted by vaxman according to "Numerival Recipes
- in Fortran 77", 2nd edition, Press, Vetterling, Teukolsky, Flannery,
- Cambridge University Press, 2001, pp. 171ff:
-
-
-|a+ib|=|a|*sqrt(1+(b/a)**2), if |a|>=|b|,
- |b|*sqrt(1+(a/b)**2) else.
-
-*/
-
- void absolute(PMC *dest) {
- FLOATVAL d = sqrt(RE(SELF)*RE(SELF) + IM(SELF)*IM(SELF));
- VTABLE_set_number_native(INTERP, dest, d);
+ STRING* get_repr () {
+ return VTABLE_get_string(INTERP, SELF);
}
/*
1.3 +4 -652 parrot/dynclasses/pylong.pmc
Index: pylong.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pylong.pmc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- pylong.pmc 7 Dec 2004 19:48:49 -0000 1.2
+++ pylong.pmc 9 Dec 2004 23:22:46 -0000 1.3
@@ -1,6 +1,6 @@
/*
Copyright: 2004 The Perl Foundation. All Rights Reserved.
-$Id: pylong.pmc,v 1.2 2004/12/07 19:48:49 rubys Exp $
+$Id: pylong.pmc,v 1.3 2004/12/09 23:22:46 rubys Exp $
=head1 NAME
@@ -24,487 +24,7 @@
#include "parrot/parrot.h"
-/*
- * TODO split that out into a separate file
- */
-
-/* cache of classes referenced */
-static INTVAL dynclass_PyLong;
-
-#ifdef PARROT_HAS_GMP
-#include <gmp.h>
-typedef struct {
- mpz_t b;
-} BIGINT;
-
-#define BN(x) ((BIGINT*)PMC_struct_val(x))->b
-
-static void
-bigint_init(Interp *interpreter, PMC *self) {
- PMC_struct_val(self) = malloc(sizeof(BIGINT));
- mpz_init(BN(self));
-}
-
-static void
-bigint_set_long(Interp *interpreter, PMC *self, long value) {
- mpz_set_si(BN(self), value);
-}
-
-static void
-bigint_set_double(Interp *interpreter, PMC *self, double value) {
- mpz_set_d(BN(self), value);
-}
-
-static void
-bigint_set_str(Interp *interpreter, PMC *self, char* value, int base) {
- mpz_set_str(BN(self), value, base);
-}
-
-static BIGNUM*
-bigint_get_self(Interp *interpreter, PMC *self) {
- return PMC_struct_val(self);
-}
-
-static void
-bigint_set_self(Interp *interpreter, PMC *self, BIGNUM *value) {
- mpz_set(BN(self), value);
-}
-
-static long
-bigint_get_long(Interp *interpreter, PMC *self) {
- if (mpz_fits_slong_p(BN(self)))
- return mpz_get_si(BN(self));
- real_exception(interpreter, NULL, 1, "bigint_get_long: number too big");
- return 0;
-}
-
-static int
-bigint_get_bool(Interp *interpreter, PMC *self) {
- if (mpz_fits_slong_p(BN(self)))
- return mpz_get_si(BN(self)) != 0;
- return 0;
-}
-static char *
-bigint_get_string(Interp *interpreter, PMC *self, int base) {
- return mpz_get_str(NULL, base, BN(self));
-}
-
-static double
-bigint_get_double(Interp *interpreter, PMC *self) {
- return mpz_get_d( BN(self));
-}
-
-static void
-bigint_add_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_add(BN(dest), BN(self), BN(value));
-}
-
-static void
-bigint_add_bigint_int(Interp *interpreter, PMC* self, INTVAL value,
- PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_add_ui(BN(dest), BN(self), (long)value);
-}
-static void
-bigint_mul_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_mul(BN(dest), BN(self), BN(value));
-}
-
-static void
-bigint_mul_bigint_int(Interp *interpreter, PMC* self, INTVAL value,
- PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_mul_ui(BN(dest), BN(self), value);
-}
-
-static void
-bigint_div_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- /* this is mpz_fdiv_q */
- mpz_div(BN(dest), BN(self), BN(value));
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(interpreter, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(interpreter, dest,
- mpz_get_si(BN(dest)));
- }
-}
-static void
-bigint_div_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC
*dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- /* this is mpz_fdiv_q */
- mpz_div_ui(BN(dest), BN(self), value);
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(interpreter, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(interpreter, dest,
- mpz_get_si(BN(dest)));
- }
-}
-static void
-bigint_fdiv_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- /* this is mpz_fdiv_q */
- mpz_fdiv_q(BN(dest), BN(self), BN(value));
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(interpreter, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(interpreter, dest,
- mpz_get_si(BN(dest)));
- }
-}
-static void
-bigint_fdiv_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC
*dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- /* this is mpz_fdiv_q */
- mpz_fdiv_q_ui(BN(dest), BN(self), value);
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(interpreter, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(interpreter, dest,
- mpz_get_si(BN(dest)));
- }
-}
-static void
-bigint_mod_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_mod(BN(dest), BN(self), BN(value));
- if (mpz_fits_slong_p(BN(dest))) {
- VTABLE_morph(interpreter, dest, enum_class_PerlInt);
- VTABLE_set_integer_native(interpreter, dest,
- mpz_get_si(BN(dest)));
- }
-}
-
-static INTVAL
-bigint_cmp(Interp *interpreter, PMC* self, PMC *value)
-{
- return mpz_cmp(BN(self), BN(value));
-}
-
-static INTVAL
-bigint_cmp_int(Interp *interpreter, PMC* self, INTVAL value)
-{
- return mpz_cmp_ui(BN(self), value);
-}
-
-static void
-bigint_abs(Interp *interpreter, PMC* self, PMC *dest)
-{
- VTABLE_morph(interpreter, dest, dynclass_PyLong);
- mpz_abs(BN(dest), BN(self));
-}
-#else
-
-static void
-bigint_init(Interp *interpreter, PMC *self) {
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_set_long(Interp *interpreter, PMC *self, long value) {
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_set_double(Interp *interpreter, PMC *self, double value) {
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_set_str(Interp *interpreter, PMC *self, char* value, int base) {
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_set_self(Interp *interpreter, PMC *self, BIGNUM *value) {
- internal_exception(1, "no bigint lib loaded");
-}
-static BIGNUM*
-bigint_get_self(Interp *interpreter, PMC *self) {
- internal_exception(1, "no bigint lib loaded");
- return NULL;
-}
-
-static char *
-bigint_get_string(Interp *interpreter, PMC *self, int base) {
- internal_exception(1, "no bigint lib loaded");
- return NULL;
-}
-
-static long
-bigint_get_long(Interp *interpreter, PMC *self) {
- internal_exception(1, "no bigint lib loaded");
- return 0L;
-}
-static long
-bigint_get_bool(Interp *interpreter, PMC *self) {
- internal_exception(1, "no bigint lib loaded");
- return 0L;
-}
-static double
-bigint_get_double(Interp *interpreter, PMC *self) {
- internal_exception(1, "no bigint lib loaded");
- return 0.0;
-}
-static void
-bigint_add_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_add_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC
*dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_mul_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_mul_bigint_int(Interp *interpreter, PMC* self, INTVAL value,
- PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_div_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_div_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC
*dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_fdiv_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_fdiv_bigint_int(Interp *interpreter, PMC* self, INTVAL value, PMC
*dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static void
-bigint_mod_bigint(Interp *interpreter, PMC* self, PMC *value, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-static INTVAL
-bigint_cmp(Interp *interpreter, PMC* self, PMC *value)
-{
- internal_exception(1, "no bigint lib loaded");
- return 0;
-}
-static INTVAL
-bigint_cmp_int(Interp *interpreter, PMC* self, INTVAL value)
-{
- internal_exception(1, "no bigint lib loaded");
- return 0;
-}
-static void
-bigint_abs(Interp *interpreter, PMC* self, PMC *dest)
-{
- internal_exception(1, "no bigint lib loaded");
-}
-#endif
-
-pmclass PyLong extends PyObject dynpmc group python_group {
-
-/*
-
-=item C<void class_init()>
-
-Class initialization. Caches the type id of various PMCs because
-they will be used frequently here.
-
-=cut
-
-*/
-
- void class_init() {
- if (pass) {
- dynclass_PyLong = Parrot_PMC_typenum(INTERP, "PyLong");
- }
- }
-
-/*
-
-=item C<void* invoke(void* next)>
-
-Pythonic object constructor. SELF is a BigInt Class object. Return a new
-C<long> object according to 2.1. Built-in Functions.
-
-=cut
-
-*/
- void* invoke(void* next) {
- int argcP = REG_INT(3);
- int base;
- PMC *res;
- STRING *num;
-
- if (!argcP) {
- REG_PMC(5) = pmc_new(INTERP, dynclass_PyLong);
- return next;
- }
- base = 10;
- if (argcP == 2)
- base = VTABLE_get_integer(INTERP, REG_PMC(6));
- res = pmc_new(interpreter, dynclass_PyLong);
- num = VTABLE_get_string(interpreter, REG_PMC(5));
- VTABLE_set_string_keyed_int(interpreter, res, base, num);
- REG_PMC(5) = res;
- return next;
- }
-
- void class_init () {
- /* this should be autmatically done - probably */
- if (pass) {
- }
- }
-
-/*
-
-=back
-
-=head2 Methods
-
-=over 4
-
-*/
-
- void init () {
- bigint_init(INTERP, SELF);
- }
-
-/*
-
-=item C<void set_integer_native(INTVAL value)>
-
-=cut
-
-*/
-
- void set_integer_native(INTVAL value) {
- bigint_set_long(INTERP, SELF, (long)value);
- }
-
-/*
-
-=item C<void set_number_native(FLOATVAL value)>
-
-Sets the value of the bigint to C<value>.
-
-=cut
-
-*/
-
- void set_number_native(FLOATVAL value) {
- bigint_set_double(INTERP, SELF, (double)value);
- }
-
-/*
-
-=item C<void set_string_native(STRING* value)>
-
-Sets the value of the integer to the result of converting C<*value> to a
-number.
-
-=item C<void set_string_keyed_int(INTVAL base, STRING* value)>
-
-Same assume number base C<base>.
-
-=cut
-
-*/
-
- void set_string_native(STRING* value) {
- char *s = string_to_cstring(INTERP, value);
- bigint_set_str(INTERP, SELF, s, 10);
- string_cstring_free(s);
- }
-
- void set_string_keyed_int(INTVAL base, STRING* value) {
- char *s = string_to_cstring(INTERP, value);
- bigint_set_str(INTERP, SELF, s, base);
- string_cstring_free(s);
- }
-/*
-
-=item C<void set_pmc(PMC *value)>
-
-Sets the value of the integer to the integer value of C<*value>.
-
-=cut
-
-*/
-
- void set_pmc(PMC *value) {
- bigint_set_self(INTERP, SELF, bigint_get_self(INTERP, value));
- }
-
-/*
-
-=item C<FLOATVAL get_number()>
-
-Returns the value of the integer as a floating point number.
-
-=cut
-
-*/
-
- FLOATVAL get_number() {
- return bigint_get_double(INTERP, SELF);
- }
-
-/*
-
-=item C<INTVAL get_integer()>
-
-Returns the value of the integer.
-
-=cut
-
-*/
-
- INTVAL get_integer() {
- return bigint_get_long(INTERP, SELF);
- }
-
-/*
-
-=item C<BIGNUM* get_bignum()>
-
-Returns the BIGNUM.
-
-=cut
-
-*/
-
- BIGNUM* get_bignum() {
- return bigint_get_self(INTERP, SELF);
- }
-
-/*
-
-=item C<INTVAL get_bool()>
-
-Returns the boolean value of the integer.
-
-=cut
-
-*/
-
- INTVAL get_bool() {
- return bigint_get_bool(INTERP, SELF);
- }
+pmclass PyLong extends BigInt dynpmc group python_group {
/*
@@ -526,186 +46,18 @@
*/
STRING* get_string() {
- char *s = bigint_get_string(INTERP, SELF, 10);
- STRING *ps = string_from_cstring(INTERP, s, 0);
- free(s);
+ STRING *ps = SUPER();
return string_append(INTERP, ps, const_string(INTERP, "L"), 0);
}
STRING* get_string_keyed_int(INTVAL base) {
- char *s = bigint_get_string(INTERP, SELF, base);
- STRING *ps = string_from_cstring(INTERP, s, 0);
- free(s);
+ STRING *ps = SUPER(base);
return string_append(INTERP, ps, const_string(INTERP, "L"), 0);
}
STRING* get_repr() {
return SELF.get_string();
}
-/*
-
-=item C<void increment()>
-
-Increments the integer.
-
-=cut
-
-*/
-
- void increment() {
- internal_exception(1, "unimp inc");
- }
-
-/*
-
-=item C<void decrement()>
-
-Decrements the integer.
-
-=cut
-
-*/
-
- void decrement() {
- internal_exception(1, "unimp dec");
- }
-
- void add(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_add_bigint(INTERP, SELF, value, dest);
- }
-MMD_PyInt: {
- bigint_add_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_Integer: {
- bigint_add_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp add");
- }
- }
-
- void add_int(INTVAL value, PMC* dest) {
- bigint_add_bigint_int(INTERP, SELF, value, dest);
- }
-
- void multiply(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_mul_bigint(INTERP, SELF, value, dest);
- }
-MMD_PyInt: {
- bigint_mul_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
- }
-MMD_Integer: {
- bigint_mul_bigint_int(INTERP, SELF, PMC_int_val(value), dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp mul");
- }
- }
-
- void multiply_int(INTVAL value, PMC* dest) {
- bigint_mul_bigint_int(INTERP, SELF, value, dest);
- }
-
- void divide(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_div_bigint(INTERP, SELF, value, dest);
- }
-MMD_PyInt: {
- bigint_div_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_Integer: {
- bigint_div_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp fdiv");
- }
- }
-
- void divide_int(INTVAL value, PMC* dest) {
- bigint_div_bigint_int(INTERP, SELF, value, dest);
- }
- void floor_divide(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_fdiv_bigint(INTERP, SELF, value, dest);
- }
-MMD_PyInt: {
- bigint_fdiv_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_Integer: {
- bigint_fdiv_bigint_int(INTERP, SELF, PMC_int_val(value),
dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp fdiv");
- }
- }
- void floor_divide_int(INTVAL value, PMC* dest) {
- bigint_fdiv_bigint_int(INTERP, SELF, value, dest);
- }
-
- void modulus(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_mod_bigint(INTERP, SELF, value, dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp mod");
- }
- }
-
- void cmodulus(PMC* value, PMC* dest) {
-MMD_PyLong: {
- bigint_mod_bigint(INTERP, SELF, value, dest);
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp cmod");
- }
- }
-
-
- void divide_int(INTVAL value, PMC* dest) {
- bigint_div_bigint_int(INTERP, SELF, value, dest);
- }
-
- INTVAL cmp(PMC* value) {
-MMD_PyLong: {
- return bigint_cmp(INTERP, SELF, value);
- }
-MMD_PyInt: {
- return bigint_cmp_int(INTERP, SELF, PMC_int_val(value));
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp cmp");
- return 0;
- }
- }
-
- INTVAL is_equal(PMC* value) {
-MMD_PyLong: {
- return bigint_cmp(INTERP, SELF, value) == 0;
- }
-MMD_PyInt: {
- return bigint_cmp_int(INTERP, SELF, PMC_int_val(value)) == 0;
- }
-MMD_DEFAULT: {
- internal_exception(1, "unimp eq");
- return 0;
- }
- }
-
-/*
-
-=item C<void absolute()>
-
-Sets C<dest> to the absolute value of SELF.
-
-=cut
-
-*/
-
- void absolute(PMC *dest) {
- bigint_abs(INTERP, SELF, dest);
- }
/*