[Mono-devel-list] Extension to mcs

Rodrigo B. de Oliveira rbo at acm.org
Thu Apr 22 20:06:01 EDT 2004


Inline...

----- Original Message ----- 
From: "Kamil Skalski" <nazgul at omega.pl>
To: <mono-devel-list at lists.ximian.com>
Sent: Thursday, April 22, 2004 5:29 PM
Subject: Re: [Mono-devel-list] Extension to mcs


> Thursday 22 of April 2004 21:26, Jürg Billeter wrote:
> > Hi
> >
> > I'd like to add support for "Design by Contract" [1] to the Mono C#
> > compiler using custom attributes - kind of what eXtensible C# [2] does.
>
> It's quite interesting, as we work on similar thing in Nemerle
> (http://nemerle.org). Our language introduces general compile-time macros.
We
> already have working meta-programming system transforming parse-trees just
> before typing procedures during compilation. We have also special system
of
> "code quotation" (derived from Template Haskell, Scheme, etc.) to build
and
> decompose parsetrees.
>
> Our macros are currently used like common functions
> def k = 5;
> print ("There are $k nodes");  // print is a macro which prints value of k
>
> (they transform syntax-trees passed to them by parameters and returns new
> syntax tree, which is inlined in the place where they occur)
>
> Next stage of our development with regard to macros is placing their
> invocation in custom attributes.
> [AddSerializeMethod]
> class Customer {
> ...
> public Foo ([NotNull] o : object) : void { .. }
> }
>
> so we can algorithmically transform classes and their bodies at
compile-time.

Very interesting! Amazing how a lot of different projects around the world
have got to similar ideas on language/compiler extensibility, my
soon-to-be-released
programming language boo implements very similar features:

<snip>
   class Foo(IDisposable):
      [getter(Disposed)]
      _disposed = false

      def Dispose():
         print('Disposed.')

   using f=Foo():
      print(f.Disposed)
   print(f.Disposed)
</snip>

The above code contains two examples of the language's extensibility
features:

    * getter is what I call an active attribute (for lack of a better name):
active for the attribute will be instantiated
    during the compilation phase and given a chance to modify the AST;

    * using is a macro; macros in boo are just like active attributes:
classes that will be instantiated during
    compilation and given a chance to process the AST;

The getter attribute would look something like the following:

<snip>
import Boo.Lang.Compiler
import Boo.Lang.Compiler.Ast

class GetterAttribute(AbstractAstAttribute):
    _name as ReferenceExpression

    def constructor([required] name as ReferenceExpression):
         _name = name

    override def Apply([required] node as Node):
         field as Field = node

         property = Property(_name.Name)
         property.Getter = Method("get")
         property.Getter.Body.Add(
                  ReturnStatement(
                           ReferenceExpression(field.Name)))

         field.DeclaringType.Members.Add(property)
</snip>

My hope is that it should be somewhat easy to see what's going on:

    * ReferenceExpression, Node, Property, Method and ReturnStatement are
all AST node classes;

    * the attribute's constructor defines exactly how the attribute should
be used syntax-wise, in this
case, the attribute must be used with a reference, [getter("Disposed")]
would be signaled as an error
by the compiler with an apropriate message;

    * the Apply method receives the node to which the attribute was attached
to and can do anything with it; yes,
that's kind of dangerous but I'd rather put the programmers in charge than
trying to protect them from themselves;

> So, any design decision you will make about macros in attributes would be
very
> interesting for me, as I will also implement them in near future.

I think the main thing is to have a clear and easy API for AST manipulation,
this should give
programmers a enough power.

I'd love to hear your thoughts.

BTW, there's one more extensibility mechanism in boo: custom compilation
pipelines but I'll leave
that for the language docs ;-)

Best regards,
Rodrigo





More information about the Mono-devel-list mailing list