A recent discussion with Sam has shown that the current calling conventions for overloaded operators don't match Python semantics (nor Perl6 when I interpret S06 and S13 correctly).

The difference is that Parrot is passing in the destination argument while these languages are returning the operator result.

E.g.

def myadd(self, r):
    return self - r

class I(int):
    __add__ = myadd

i = I(44)
print i, i + 2

Parrot is expecting and calling a subroutine like:

  .sub __add
    .param left
    .param right
    .param dest
   ...
  .end

and it's run in void context. This calling convention matches the "add" opcode, where the destination argument has to exist. But it's not suited for HLLs as the HLL compiler can't track the subroutine usage back to overloading and adjust the emitted code.

A short-term solution would be to evaluate the return result (if the function returns something) and assign that value to the "dest" argument.

Parrot would call

  .sub __add
     .param left
     .param right
     .param dest       # HLL can use it or create a temp
     ...
     .return(temp)     # or .return (dest) if HLL knows about dest
   .end

while this is still a bit sub-optimal because of the additional temp, the HLL might create, it would at least match the semantics.

A more radical change would be to just adapt these opcodes to create an appropriate PMC with the result.

Comments?
leo



Reply via email to