Pregunta

Estoy creando una conexión DSL para un motor de juego de cartas extensible que estoy trabajando, con Boo.

Tengo una macro tarjeta que crea una clase para un nuevo tipo de tarjeta, e inicializa algunas propiedades en el constructor. Macro que tiene unos submacros para configurar otras cosas. Básicamente quiero que se convierta algo como esto:

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

en esto:

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

    class EffectA (Effect):
        // effectdefintion

El efecto definitivamente tiene que ser una clase, ya que se pasa alrededor (que es un patrón de estrategia).

Hasta el momento, no tengo este simple esqueleto:

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

Ahora, yo no sé lo que debo hacer con card.Body para hacer la macro capacidad de añadir código al constructor y al mismo tiempo generar una clase anidada. ¿Alguna idea? ¿Es posible hacerlo con capacidades de idioma actual?

¿Fue útil?

Solución

Se puede hacer. He aquí cómo:

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

El crédito va a Cedric Vivier por ayudarme en el Boo grupo Google .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top