2009-07-15 8 views
5

Sto creando una DSL per un motore di gioco di carte estensibile su cui sto lavorando, con boo.Difficile boo sintattica macro

Ho una macro di scheda che crea una classe per un nuovo tipo di scheda e inizializza alcune proprietà nel costruttore. Quella macro ha alcuni submacro per impostare altre cose. Fondamentalmente voglio che diventi qualcosa di simile:

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

in questo:

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

    class EffectA (Effect): 
     // effectdefintion 

L'effetto sicuramente deve essere una classe, perché sarà passato in giro (si tratta di un modello di strategia).

Finora, ho questo semplice scheletro:

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

Ora, non so cosa devo fare con card.Body per rendere il codice aggiuntivo macro capacità di costruttore, mentre anche la generazione di un nidificato classe. qualche idea? Questo può essere fatto con le attuali competenze linguistiche?

risposta

6

Può essere fatto. Ecco come:

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)()) |] 

merito va a Cedric Vivier per avermi aiutato nel boo Google group.