Domanda

Sto creando un DSL per un motore estensibile gioco di carte su cui sto lavorando, con il fischio.

Ho una macro carta che crea una classe per un nuovo tipo di carta, e inizializza alcune proprietà nel costruttore. Questo macro ha un paio di submacros per l'impostazione altre cose. Fondamentalmente voglio che diventi qualcosa di simile:

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

in questo modo:

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

    class EffectA (Effect):
        // effectdefintion

L'effetto sicuramente bisogno di 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, io non so che cosa devo fare con card.Body per rendere la macro capacità aggiungere codice al costruttore, mentre anche generare una classe annidata. qualche idea? Questo può essere fatto con capacità linguistiche attuali?

È stato utile?

Soluzione

Si può fare. 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)()) |] 

Il credito va a Cedric Vivier per avermi aiutato nel boo gruppo Google .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top