On Nov 3, 2004, at 8:09 AM, Dan Sugalski wrote:
At 11:04 AM -0500 11/3/04, Sam Ruby wrote:
A single pow_p_p_p op backed by a (non-MMD) vtable entry would make it easier to support code like the following:
def f(x): return x**3 print f(3), f(2.5)
Yeah, it would. I know I'm going to regret asking, but... any reason *not* to make it MMD? (Though I have no idea what happens if you square a matrix)
I feel like we have op-itis and vtable-itis. I would think that rather than a pow_p_p_p, you'd compile "x**y" as something like:
set N0, P0 set N1, P1 pow N2, N0, N1 new P2, .PythonNumber assign P2, N2
I.e., PMCs don't inherently exponentiate--numbers do, and you can exponentiate PMCs by numberizing them, exponentiating, and creating a PMC with the result.
Or, if we must have an op, implement it something like this (without needing a new vtable entry, or MMD):
inline op pow(out PMC, in PMC, in PMC) :base_core { $1 = pmc_new(interpreter, $2->vtable->type(interpreter, $2));
$1->vtable->set_number_native(interpreter, $1, pow( $2->vtable->get_number(interpreter, $2), $3->vtable->get_number(interpreter, $3)))
goto NEXT(); }
Those would probably JIT to about the same thing, given register mapping.
This is the viewpoint that pow() isn't a fundamental operation that makes sense for all types; it's a numeric operation, which can be extended in a straighforward manner to types which know how to represent themselves as numbers. (e.g., it's gibberish to raise a ManagedStruct to a ParrotIO power, except that you can stretch and interpret such a thing as just implicit num-ification of the arguments.)
JEff