2009-07-15 5 views
5

Ich erstelle ein DSL für eine erweiterbare Kartenspielmaschine, an der ich arbeite, mit boo.Schwieriger boo syntaktischer Makro

Ich habe ein Kartenmakro, das eine Klasse für einen neuen Kartentyp erstellt und einige Eigenschaften im Konstruktor initialisiert. Dieses Makro hat ein paar Submacros zum Setzen anderer Dinge. Grundsätzlich mag ich es so etwas drehen:

card 'A new card': 
    type TypeA 
    ability EffectA: 
     // effect definition 

in dieser:

class ANewCard (Card): 
    def constructor(): 
     Name = "A new card" 
     Type = Types.TypeA 
     AddEffect(EffectA()) 

    class EffectA (Effect): 
     // effectdefintion 

Der Effekt muss auf jeden Fall eine Klasse sein, weil sie herumgereicht werden (es ist ein Strategie-Muster).

Bisher habe ich diese einfache Skelett:

macro card: 
    yield [| 
     class $(ReferenceExpression(card.Arguments[0])) (Card): 
      def constructor(): 
       Name = $(card.Arguments[0]) 
    |] 

Nun, ich weiß nicht, was soll ich mit card.Body tun, um die Fähigkeit Makro Add-Code an den Konstruktor zu machen, während auch eine verschachtelte Erzeugung Klasse. Irgendwelche Gedanken? Kann dies mit den aktuellen Sprachfähigkeiten geschehen?

Antwort

6

Es kann getan werden. Hier ist, wie:

import Boo.Lang.Compiler.Ast 
import Boo.Lang.PatternMatching 

macro card(name as string): 
    klass = [| 
     class $(ReferenceExpression(name)): 
      def constructor(): 
       Name = $name 
    |] 
    klass.Members.Add(card["effect"]) 
    klass.GetConstructor(0).Body.Add(card["effect-ctor"] as Expression) 
    yield klass 

macro effect(eff as ReferenceExpression): 
    card["effect"] = [| 
     class $eff (Effect): 
      pass 
    |] 
    card["effect-ctor"] = [| Effects.Add($(eff)()) |] 

Credit Cedric Vivier geht mir zu helfen, in der boo Google group aus.

Verwandte Themen