Leopold Toetsch wrote:
There seems to be the impression that generating PIR calls from a compiler is
hard because it may look like:
$S0 = obj.'_meth'(arg1, arg2)
but this also works:
.pcc_begin
.arg "hello"
.arg "\n"
.invocant obj
.meth_call "_meth"
.result $S0
.pcc_end
There's a similar construct for return values.
The basic problem is inconsistency. For hand-written code the current
PIR method call syntactic sugar is mildly annoying. (It'd be nice to
safely get rid of the quotes around the method name.) For generated code
it's a completely different syntax tree node. Opcode syntax like so:
opcode $S0, obj, arg1, arg2
can be represented with a simple parent node with a sequence of child nodes.
The syntax tree for methods (whether you use the syntactic sugar or the
long form) is more like a parent node (a "method"), with one invocant
child and two composite children for the argument list and return list,
respectively. To generate the PIR, you need unroll the composite
children in a way that's contextually dependent on other nodes further
up the tree.
And when some common language constructs are opcodes and some are method
calls, the burden of deciding which kind of syntax a particular
construct should use falls to the compiler writer. There are various
ways to implement it: a lookup table, a chunk of hard-coded PIR, etc.
But they all boil down to added complexity.
This isn't to say that method calls are "bad", but they are more complex
to work with. You want more features to be implemented only as methods
and to eliminate the opcodes. But there is real value in keeping the
opcode syntax for the common cases.
Allison