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

Reply via email to