Re: FYI compiling PIR function calls

2006-09-28 Thread chromatic
On Thursday 28 September 2006 17:57, Matt Diephouse wrote:

> Why not handle this like we handle subroutines? That is, why don't we
> have a find_method opcode that returns a bound method? That simplifies
> parsing for IMCC and makes PIR a little simpler.
>     obj.'abc'() # call 'abc' method of obj
>     obj.abc()  # same as above
>     $P0 = find_method obj, abc # get bound method indicated by abc symbol
>     $P0() # actually call it

Does that make emitting PASM a lot more difficult?  All of a sudden, invoking 
$P0 means that $P0 has to know that it stores something in the appropriate 
invocant PMC register.

I suppose that means creating a CurriedInvocantMethodCall PMC that does all of 
this magic in invoke().  That's not awful, but

-- c


Re: Re: FYI compiling PIR function calls

2006-09-28 Thread Matt Diephouse

Allison Randal <[EMAIL PROTECTED]> wrote:


> .local string abc
>
> obj.'abc'()  # call 'abc' method of obj
> obj.abc()# always the same as above
> obj.{abc}()  # call method indicated by abc symbol
> obj.{S0}()   # call method indicated by S0
> obj.$S0()# call method indicated by $S0
>
> Having obj.abc() always mean obj.'abc'() seems to me like it's
> most in line with what PIR-authors expect.

Yup.



Why not handle this like we handle subroutines? That is, why don't we
have a find_method opcode that returns a bound method? That simplifies
parsing for IMCC and makes PIR a little simpler.
   obj.'abc'() # call 'abc' method of obj
   obj.abc()  # same as above
   $P0 = find_method obj, abc # get bound method indicated by abc symbol
   $P0() # actually call it

--
Matt Diephouse
http://matt.diephouse.com


Re: FYI compiling PIR function calls

2006-09-28 Thread Leopold Toetsch
Am Donnerstag, 28. September 2006 22:53 schrieb Allison Randal:
> Leopold Toetsch wrote:
> > Am Donnerstag, 28. September 2006 21:42 schrieb Patrick R. Michaud:
> >> obj.'abc'()  # call 'abc' method of obj
> >> obj.abc()# always the same as above
> >> obj.{abc}()  # call method indicated by abc symbol
> >
> > This makes a lot of sense, and there are simple rules for the syntax:
> >
> > * use {symbol}, if the thing isa symbol
> > * use 'name',  if the 'name' contains non-identifier characters
> >   (of if unsure, of if you are a compiler ;-)
> > * else you also might use bare word syntax
>
> The latter two are the same rules as the rules for declaring
> methods/subs, which makes for nice consistency.

Yep.

> > That should be it to deal with all that:
> >
> >   obj.S0() # emit warning but call 'S0' method
> >
> > Rational: if bare  isa identifier here, then C too.
>
> I can see the value of this warning for the transition, but long-term we
> really don't want the code to be littered with warnings for deprecated
> features. It'd be pretty simple to write a script that combs the .pir
> files in the repository for any instance of a method name that looks
> like a register name.

Indeed. I'm pretty sure that there isn't one test nor other .pir in the tree 
using this syntax. The rules are clear enough: C is parsed as IDentifier 
in that case, which means:

  obj.S0()  :=  obj.'S0'()

That is: no warning needed at all.

> >   obj.$S0()# illegal
>
> Is '$' a valid identifier character? 

No. Just a PIR temp variable signature, which makes the thingy a variable or 
synmbol.

> If so, then it's legal, but just 
> treated as part of the string name of the method. If not (which seems
> more likely), then it's illegal anyway, so no special case is needed.

I wanted just to stress the illegality of it as it was differently used in a 
previous mail.

> Allison

leo


Re: FYI compiling PIR function calls

2006-09-28 Thread Allison Randal

Leopold Toetsch wrote:

Am Donnerstag, 28. September 2006 21:42 schrieb Patrick R. Michaud:


obj.'abc'()  # call 'abc' method of obj
obj.abc()# always the same as above
obj.{abc}()  # call method indicated by abc symbol


This makes a lot of sense, and there are simple rules for the syntax:

* use {symbol}, if the thing isa symbol
* use 'name',  if the 'name' contains non-identifier characters
  (of if unsure, of if you are a compiler ;-)
* else you also might use bare word syntax


The latter two are the same rules as the rules for declaring 
methods/subs, which makes for nice consistency.



That should be it to deal with all that:

  obj.S0() # emit warning but call 'S0' method

Rational: if bare  isa identifier here, then C too.


I can see the value of this warning for the transition, but long-term we 
really don't want the code to be littered with warnings for deprecated 
features. It'd be pretty simple to write a script that combs the .pir 
files in the repository for any instance of a method name that looks 
like a register name.



  obj.$S0()# illegal


Is '$' a valid identifier character? If so, then it's legal, but just 
treated as part of the string name of the method. If not (which seems 
more likely), then it's illegal anyway, so no special case is needed.


Allison


Re: FYI compiling PIR function calls

2006-09-28 Thread Allison Randal

Patrick R. Michaud wrote:

On Thu, Sep 28, 2006 at 11:59:52AM -0700, chromatic wrote:

On Thursday 28 September 2006 11:25, Allison Randal wrote:

 obj.{bar}()  # a string method name
 obj.{$S1}()


I'm not sure what's meant by "a string method name" above, but
I'd look at it as:



You got it, I meant "a method name stored in a string variable/register".



.local string abc

obj.'abc'()  # call 'abc' method of obj
obj.abc()# always the same as above
obj.{abc}()  # call method indicated by abc symbol
obj.{S0}()   # call method indicated by S0
obj.$S0()# call method indicated by $S0

Having obj.abc() always mean obj.'abc'() seems to me like it's
most in line with what PIR-authors expect.


Yup.

Allison


Re: FYI compiling PIR function calls

2006-09-28 Thread Leopold Toetsch
Am Donnerstag, 28. September 2006 21:42 schrieb Patrick R. Michaud:

I'm just quoting the relevant pieces here and add some comments below:

>     obj.'abc'()              # call 'abc' method of obj
>     obj.abc()                # always the same as above
>     obj.{abc}()              # call method indicated by abc symbol

This makes a lot of sense, and there are simple rules for the syntax:

* use {symbol}, if the thing isa symbol
* use 'name',  if the 'name' contains non-identifier characters
  (of if unsure, of if you are a compiler ;-)
* else you also might use bare word syntax

That should be it to deal with all that:

  obj.S0() # emit warning but call 'S0' method

Rational: if bare  isa identifier here, then C too.

  obj.$S0()# illegal

leo


Re: FYI compiling PIR function calls

2006-09-28 Thread chromatic
On Thursday 28 September 2006 12:42, Patrick R. Michaud wrote:

> > To push a little more the other direction, is it possible for the
> > compiler to detect symbol and method name conflicts?  
> > It's only the collision that makes a case ambiguous, right?

> I don't think that the compiler always knows at compile time
> what method names are available for any given object, so detecting
> "collisions" could be problematic.  

Oh no, of course not.

> However, it could certainly detect when a bareword symbol has
> been used as a method name and warn about it, requiring the use of an
> explicit obj.{symbol}() or obj.'symbol'() form to disambiguate it.

Yes, that is what I meant.  If there's a symbol in the current compilation 
unit with the same name as a bareword method call, require disambiguation.  
Otherwise, assume it's a bareword method call.

-- c


Re: FYI compiling PIR function calls

2006-09-28 Thread Patrick R. Michaud
On Thu, Sep 28, 2006 at 11:59:52AM -0700, chromatic wrote:
> On Thursday 28 September 2006 11:25, Allison Randal wrote:
> >  obj.{bar}()  # a string method name
> >  obj.{$S1}()

I'm not sure what's meant by "a string method name" above, but
I'd look at it as:

.local string abc

obj.'abc'()  # call 'abc' method of obj
obj.abc()# always the same as above
obj.{abc}()  # call method indicated by abc symbol
obj.{S0}()   # call method indicated by S0
obj.$S0()# call method indicated by $S0

Having obj.abc() always mean obj.'abc'() seems to me like it's
most in line with what PIR-authors expect.

As noted in the last instance, I don't know that we need a
separate obj.{$S0}() case since the dollar sign is sufficient
to distinguish exactly what was meant.  But there's also an
argument in favor of the consistency of {...} always meaning
"evaluate this" as opposed to "treat this as literal" given
by the bareword and 'abc' forms.

> To push a little more the other direction, is it possible for the 
> compiler to detect symbol and method name conflicts?  
> It's only the collision that makes a case ambiguous, right?

I don't think that the compiler always knows at compile time
what method names are available for any given object, so detecting
"collisions" could be problematic.  

However, it could certainly detect when a bareword symbol has 
been used as a method name and warn about it, requiring the use of an
explicit obj.{symbol}() or obj.'symbol'() form to disambiguate it.

Pm


Re: FYI compiling PIR function calls

2006-09-28 Thread chromatic
On Thursday 28 September 2006 11:25, Allison Randal wrote:

> Exactly, change the most common case (of a method call by bare name) to
> be the unmarked case, and use some additional marking on the less common
> case of calling a method by a string name or method object. I wouldn't
> use '$' to mark the string lookup because it's too confusing with the
> temporary register variables ($S0, etc). But some other syntactic sugar
> would work. This is clumsy, but then, it's also rare.
>
>  obj.{bar}()  # a string method name
>  obj.{$S1}()

That's not bad; it reminds me a bit of Perl and Tcl.

To push a little more the other direction, is it possible for the compiler to 
detect symbol and method name conflicts?  It's only the collision that makes 
a case ambiguous, right?

-- c


Re: FYI compiling PIR function calls

2006-09-28 Thread Allison Randal

Jonathan Scott Duff wrote:


To be on the safe side, method (and function) names *should* be quoted. I 
don't think that this is inconsistent.


Is there a reason that you would want to conflate method names and
variables used as a method name? If not, why not change the syntax
slightly so that method names in a variable are uniquely identified?
Here's a suggestion:

obj.foo()   # a methodname constant
.local string bar
bar = get_some_meth()
obj.$bar()  # a method variable



Exactly, change the most common case (of a method call by bare name) to 
be the unmarked case, and use some additional marking on the less common 
case of calling a method by a string name or method object. I wouldn't 
use '$' to mark the string lookup because it's too confusing with the 
temporary register variables ($S0, etc). But some other syntactic sugar 
would work. This is clumsy, but then, it's also rare.


obj.{bar}()  # a string method name
obj.{$S1}()

Allison


Re: FYI compiling PIR function calls

2006-09-27 Thread Jonathan Scott Duff
On Wed, Sep 27, 2006 at 11:38:10AM +0200, Leopold Toetsch wrote:
> Am Mittwoch, 27. September 2006 09:12 schrieb Allison Randal:
> 
> > 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.) 
> 
> Not easily:
> 
>   obj.'foo'()  # a methodname constant
>   .local string bar
>   bar = get_some_meth()   # or bar = 'get_some_meth'()
>   obj.bar()# a method variable
> 
> But:
> 
>   obj.foo()# still a methodname constant 
># unless there's a variable 'foo'
> 
> To be on the safe side, method (and function) names *should* be quoted. I 
> don't think that this is inconsistent.

Is there a reason that you would want to conflate method names and
variables used as a method name? If not, why not change the syntax
slightly so that method names in a variable are uniquely identified?
Here's a suggestion:

obj.foo()   # a methodname constant
.local string bar
bar = get_some_meth()
obj.$bar()  # a method variable

The same could be used for ordinary subroutines:

.local string mysub
mysub = "foo"
$mysub()# calls the foo subroutine

-Scott
-- 
Jonathan Scott Duff <[EMAIL PROTECTED]>


Re: FYI compiling PIR function calls

2006-09-27 Thread Leopold Toetsch
Am Mittwoch, 27. September 2006 09:12 schrieb Allison Randal:

> 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.) 

Not easily:

  obj.'foo'()  # a methodname constant
  .local string bar
  bar = get_some_meth()   # or bar = 'get_some_meth'()
  obj.bar()# a method variable

But:

  obj.foo()# still a methodname constant 
   # unless there's a variable 'foo'

To be on the safe side, method (and function) names *should* be quoted. I 
don't think that this is inconsistent.

> 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.

Well, when I write x86 or ppc JIT code, the burden of deciding, which syntax 
to use falls on the compiler write that is me. While we could provide an 
introspection API to available opcodes (and args) it still doesn't help much. 
The compiler (writer) has to know, what a particular opcode is doing.

When I write code which calls some library function, I've to lookup the docu 
and check the function name and the argument it takes. And I've to decide, if 
I have an opcode available and use it, or if I've to call a library function.

This is just the usual job when creating a compiler. Introspection would have 
little benefit IMHO:

  interp = getinterp
  info = interp.get_op_info()   # hypothetical
  $I0 = exists info['gcd']  # do we have a 'gcd' opcode

  cl = getclass 'Integer'
  $I0 = can cl, 'gcd'

While a compiler could use introspection or tables or whatever, these still 
wouldn't help to figure out the semantics of a particular operation.

> Allison

leo


Re: FYI compiling PIR function calls

2006-09-27 Thread Allison Randal

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