Boost logo

Boost-Build :

From: David Abrahams (gclbb-jamboost_at_[hidden])
Date: 2003-05-10 12:05:48


David Abrahams <gclbb-jamboost_at_[hidden]> writes:

> Hmm, a hybrid approach might be:
>
> rule [ class x : y z ] ( init-params )
> {
> ... init code ...
> rule method1 ( whatever ) { ... }
> }
>
> This one could work in similar ways, installing a rule-definition
> hook; Although the previous approach has lots of appeal, I think
> this one might be the most expedient.

I did a little bit more experimenting with the grammar and came up
with a few interesting syntax ideas. They all revolve around
extending what can be passed as the grammar's <arg> nonterminal, which
appears where an actual argument is expected in a rule invocation.

That would allow syntaxes like:

class x ... ;

to do the whole job, with ... having a rule block in it.

The new potential rules for <arg> are:

<ARG> `(` <lol> `)` <rule>

That's a rule name, a required argument list, and something that can
serve as a rule body (usually a brace-delimited block) -- yes,
Perforce's choice of names for terminals and nonterminals is
confusing. For example, the following could be "passed" as an argument
to class:

myclass ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
}

followed by a semicolon, this would cause the myclass rule to be
declared in the local module, and the name "myclass" to be passed to
the "class" rule. The downside of this is, well, where do you put
the base classes?

# ICK!
class myclass ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
} : base1 base2 ;

# Not what we're used to
class base1 base2 : myclass ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
} ;

# Overwrites __init__ in the local module; do we care?
class myclass : base1 base2
__init__ ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
} ;

As long as we're in the neighborhood, the following two syntax rules
would allow us to implement lambda expressions:

`local` `(` <lol> `)` <rule>
`bind` <arglist_opt> <rule>

These are essentially equivalent except in the 2nd case the argument
list is optional. In case you were wondering, we can't use `rule` as
the introductory symbol because of reduce/reduce conflicts in the
parser. That could be used to achieve:

class myclass : base1 base2
bind ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
} ;

But I don't think that's a particularly compelling case for anonymous
functions; they'd be more useful in constructs like:

# filter out elements of $(y) which aren't instances of my-class
x = [ sequence.filter $(y) : bind ( elt ) is-instance $(elt) my-class ] ;

In all, for class definition I prefer either of the following two
syntaxes:

# Overwrites __init__ in the local module; do we care?
class myclass : base1 base2
__init__ ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
} ;

# No lambdas if we go this route; more syntax involved
rule [ class myclass : base1 base2 ] ( param1 param2 )
{
base.__init__( param1 )
rule foo_method ( bar ) { }
}

I think the 2nd one is easier to implement, and overall I view this as
a low-priority issue.

Thoughts?

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com
 

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk