This makes PerlUndef somewhat functional by adding logical, arithmetic, and repeat methods.
Index: global_setup.c =================================================================== RCS file: /home/perlcvs/parrot/global_setup.c,v retrieving revision 1.12 diff -u -r1.12 global_setup.c --- global_setup.c 1 Jan 2002 03:46:40 -0000 1.12 +++ global_setup.c 4 Jan 2002 18:59:12 -0000 @@ -25,6 +25,7 @@ string_init(); /* Set up the string subsystem */ /* Call base vtable class constructor methods! */ + Parrot_PerlUndef_class_init(); Parrot_PerlInt_class_init(); Parrot_PerlNum_class_init(); Parrot_PerlString_class_init(); Index: classes/perlundef.pmc =================================================================== RCS file: /home/perlcvs/parrot/classes/perlundef.pmc,v retrieving revision 1.2 diff -u -r1.2 perlundef.pmc --- classes/perlundef.pmc 18 Dec 2001 07:05:00 -0000 1.2 +++ classes/perlundef.pmc 4 Jan 2002 18:59:12 -0000 @@ -59,7 +59,7 @@ } STRING* get_string () { - return NULL; + return string_make(INTERP,NULL,0,NULL,0,NULL); } STRING* get_string_index (INTVAL index) { @@ -154,75 +154,139 @@ } void add (PMC * value, PMC* dest) { + if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) { + dest->vtable->set_integer_native(INTERP, dest, 0); + } + else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) { + dest->vtable->set_integer(INTERP, dest, value); + } + else { + dest->vtable->set_number(INTERP, dest, value); + } } void add_int (INTVAL value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, value); } void add_bigint (BIGINT value, PMC* dest) { } void add_float (FLOATVAL value, PMC* dest) { + dest->vtable->set_number_native(INTERP, dest, value); } void add_bigfloat (BIGFLOAT value, PMC* dest) { } void add_same (PMC * value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void subtract (PMC * value, PMC* dest) { + if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) { + dest->vtable->set_integer_native(INTERP, dest, 0); + } + else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) { + dest->vtable->set_integer_native(INTERP, dest, + -value->vtable->get_integer(INTERP, value)); + } + else { + dest->vtable->set_number_native(INTERP, dest, + -value->vtable->get_number(INTERP, value)); + } } void subtract_int (INTVAL value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, -value); } void subtract_bigint (BIGINT value, PMC* dest) { } void subtract_float (FLOATVAL value, PMC* dest) { + dest->vtable->set_number_native(INTERP, dest, -value); } void subtract_bigfloat (BIGFLOAT value, PMC* dest) { } void subtract_same (PMC * value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply (PMC * value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply_int (INTVAL value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply_bigint (BIGINT value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply_float (FLOATVAL value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply_bigfloat (BIGFLOAT value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void multiply_same (PMC * value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide (PMC * value, PMC* dest) { + if(value->vtable == &Parrot_base_vtables[enum_class_PerlUndef]) { + fprintf(stderr, "division by zero!\n"); + exit(1); + } + else if(value->vtable == &Parrot_base_vtables[enum_class_PerlInt]) { + if(value->vtable->get_integer(INTERP, value) == 0) { + fprintf(stderr, "division by zero!\n"); + exit(1); + } + } + else if(value->vtable->get_number(INTERP, value) == 0) { + fprintf(stderr, "division by zero!\n"); + exit(1); + } + + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide_int (INTVAL value, PMC* dest) { + if(value == 0) { + fprintf(stderr, "division by zero!\n"); + exit(1); + } + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide_bigint (BIGINT value, PMC* dest) { + /* need test for value == 0 */ + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide_float (FLOATVAL value, PMC* dest) { + if(value == 0) { + fprintf(stderr, "division by zero!\n"); + exit(1); + } + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide_bigfloat (BIGFLOAT value, PMC* dest) { + /* need test for value == 0 */ + dest->vtable->set_integer_native(INTERP, dest, 0); } void divide_same (PMC * value, PMC* dest) { + fprintf(stderr, "division by zero!\n"); + exit(1); } void modulus (PMC * value, PMC* dest) { @@ -262,12 +326,16 @@ } void logical_or (PMC* value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, + value->vtable->get_bool(INTERP, value)); } void logical_and (PMC* value, PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 0); } - void logical_not (PMC* value) { + void logical_not (PMC* dest) { + dest->vtable->set_integer_native(INTERP, dest, 1); } void match (PMC * value, REGEX* re) { @@ -286,18 +354,28 @@ } void repeat (PMC * value, PMC* dest) { + dest->vtable = &Parrot_base_vtables[enum_class_PerlString]; + dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL); } void repeat_native (STRING * value, PMC* dest) { + dest->vtable = &Parrot_base_vtables[enum_class_PerlString]; + dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL); } void repeat_unicode (STRING * value, PMC* dest) { + dest->vtable = &Parrot_base_vtables[enum_class_PerlString]; + dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL); } void repeat_other (STRING * value, PMC* dest) { + dest->vtable = &Parrot_base_vtables[enum_class_PerlString]; + dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL); } void repeat_same (PMC * value, PMC* dest) { + dest->vtable = &Parrot_base_vtables[enum_class_PerlString]; + dest->cache.struct_val = string_make(INTERP, NULL,0,NULL,0, NULL); } } Index: t/op/pmc.t =================================================================== RCS file: /home/perlcvs/parrot/t/op/pmc.t,v retrieving revision 1.16 diff -u -r1.16 pmc.t --- t/op/pmc.t 27 Dec 2001 18:50:28 -0000 1.16 +++ t/op/pmc.t 4 Jan 2002 18:59:12 -0000 @@ -1,6 +1,6 @@ #! perl -w -use Parrot::Test tests => 47; +use Parrot::Test tests => 52; my $fp_equality_macro = <<'ENDOFMACRO'; fp_eq macro J,K,L @@ -947,6 +947,173 @@ ok 7 ok 8 ok 9 +OUTPUT + +output_is(<<"CODE", <<'OUTPUT', "undef-logical"); + new P0, PerlUndef + new P1, PerlUndef + new P2, PerlInt + +# undef or undef = 0 + or P0, P1, P1 + print P0 + +# undef and undef = 0 + and P0, P1, P1 + print P0 + +# undef or 1 = 1 + set P2, 349 + or P0, P1, P2 + print P0 + +# undef and 1 = 0 + and P0, P1, P2 + print P0 + +# not undef = 1 + not P0, P1 + print "x" + print P1 + print "y" + print P0 + print "z" + print "\\n" + end +CODE +0010xy1z +OUTPUT + +output_is(<<"CODE", <<'OUTPUT', "undef-add"); +@{[ $fp_equality_macro ]} + new P1, PerlUndef + +# undef + perlundef + new P0, PerlUndef + add P0, P1, P1 + print P0 + print "\\n" + +# undef + perlint + + new P0, PerlUndef + new P2, PerlInt + set P2, 947 + add P0, P1, P2 + print P0 + print "\\n" + +# undef + perlnum + + new P0, PerlUndef + new P2, PerlNum + set P2, 385.623 + add P0, P1, P2 + fp_eq P0, 385.623, OK + + print "not" +OK: print "ok" + print "\\n" + + end +CODE +0 +947 +ok +OUTPUT + +output_is(<<"CODE", <<'OUTPUT', "undef-subtract"); +@{[ $fp_equality_macro ]} + new P0, PerlUndef + new P1, PerlUndef + +# undef - undef + sub P0, P1, P1 + print P0 + print "\\n" + +# undef - perlint + new P2, PerlInt + set P2, 947 + sub P0, P1, P2 + print P0 + print "\\n" + +# undef - perlnum + + new P2, PerlNum + set P2, 385.623 + sub P0, P1, P2 + fp_eq P0, -385.623, OK2 + + print "not" +OK2: print "ok" + print "\\n" + + + end +CODE +0 +-947 +ok +OUTPUT + +output_is(<<"CODE", <<'OUTPUT', "undef-multiply"); +@{[ $fp_equality_macro ]} + + new P0, PerlUndef + new P1, PerlUndef + new P2, PerlInt + +# Undef * Undef + mul P0, P1, P1 + print P0 + print "\\n" + +# Undef * PerlInt + set P2, 983 + mul P0, P1, P2 + print P0 + print "\\n" + +# Undef * PerlNum + new P2, PerlNum + set P2, 983.3 + mul P0, P1, P2 + print P0 + print "\\n" + + end +CODE +0 +0 +0 +OUTPUT + +output_is(<<"CODE", <<'OUTPUT', "undef-divide"); +@{[ $fp_equality_macro ]} + + new P0, PerlUndef + new P1, PerlUndef + new P2, PerlInt + +# Undef / PerlInt + set P2, 19 + div P0, P1, P2 + print P0 + print "\\n" + +# Undef / PerlNum + new P2, PerlNum + set P2, 343.8 + div P0, P1, P2 + print P0 + print "\\n" + + end +CODE +0 +0 OUTPUT 1;