Two problems: - As things stand currently, there's no way to get to the cmp_num and cmp_string vtable methods from parrot assembly.
- The cmp() method/op is completely useless for Perl, since Perl comparison operators force their operands to be interpreted as either strings or numbers. As things stand now, the way to get the right kind of comparison between two PMC's is to stuff them into either string or num registers, then compare those. This patch adds {gt,lt,eq,ge,le}_{num,string} ops for two PMC operands. To make this work, it's also necessary to implement the corresponding vtable functions for the Perl scalar type(s). We should also remove the cmp() vtable function for Perl scalars, since it's wrong and misleading. Whether plain cmp (as a vtable function or an op on PMCs) should be kept at all is questionable -- there's no way to get at it syntactically from Perl or any other language that has separate numeric and string comparisons. It might be useful for languages with a single set of comparisons that "do the right thing". While presumably Perl 6 will have "object comparisons", they'll happen by overloading either the numeric or the stringific operators, and therefore should be handled in the type's cmp_{string,num} method. Suggestions? Comments? /s
Index: core.ops =================================================================== RCS file: /cvs/public/parrot/core.ops,v retrieving revision 1.187 diff -p -u -r1.187 core.ops --- core.ops 26 Jul 2002 19:15:56 -0000 1.187 +++ core.ops 28 Jul 2002 02:53:25 -0000 @@ -1284,6 +1284,186 @@ op ge(in PMC, in PMC, inconst INT) { ######################################## +=item B<eq_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is equal to $2 numerically-wise-speaking. + +=cut + +op eq_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) == 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<ne_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is not the equal of $2 in a numeric light. + +=cut + +op ne_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) != 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<lt_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is less than $2 numerically-wise-speaking. + +=cut + +op lt_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) < 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<le_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is less than or equal to $2 numerically-wise-speaking. + +=cut + +op le_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) <= 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<gt_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is greater than $2 numerically-wise-speaking. + +=cut + +op gt_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) > 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<ge_num>(in PMC, in PMC, inconst INT) + +Branch if $1 is greater than or equal to $2 numerically-wise-speaking. + +=cut + +op ge_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_num(interpreter, $1, $2) >= 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<eq_string>(in PMC, in PMC, inconst INT) + +Branch if $1 is equal to $2 as a string. + +=cut + +op eq_num(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) == 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<ne_string>(in PMC, in PMC, inconst INT) + +Branch if $1 as a string is not $2 as a string. + +=cut + +op ne_string(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) != 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<lt_string>(in PMC, in PMC, inconst INT) + +Branch if $1 is less than $2 as a string. + +=cut + +op lt_string(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) < 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<le_string>(in PMC, in PMC, inconst INT) + +Branch if $1 is less than or equal to $2 as a string. + +=cut + +op le_string(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) <= 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<gt_string>(in PMC, in PMC, inconst INT) + +Branch if $1 is greater than $2 as a string. + +=cut + +op gt_string(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) > 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + +=item B<ge_string>(in PMC, in PMC, inconst INT) + +Branch if $1 is greater than or equal to $2 as a string. + +=cut + +op ge_string(in PMC, in PMC, inconst INT) { + if ($1->vtable->cmp_string(interpreter, $1, $2) >= 0) { + goto OFFSET($3); + } + goto NEXT(); +} + +######################################## + =item B<if>(in INT, inconst INT) =item B<if>(in NUM, inconst INT)