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