Question
Je crée une connexion DSL pour un moteur de jeu de cartes extensible je travaille, avec boo.
J'ai une macro de carte qui crée une classe pour un nouveau type de carte, et initialise des propriétés dans le constructeur. Cette macro a quelques submacros pour régler d'autres choses. Fondamentalement, je veux tourner quelque chose comme ceci:
card 'A new card':
type TypeA
ability EffectA:
// effect definition
dans ceci:
class ANewCard (Card):
def constructor():
Name = "A new card"
Type = Types.TypeA
AddEffect(EffectA())
class EffectA (Effect):
// effectdefintion
L'effet doit certainement être une classe, car il sera passé autour (il est un modèle de stratégie).
Jusqu'à présent, j'ai ce squelette simple:
macro card:
yield [|
class $(ReferenceExpression(card.Arguments[0])) (Card):
def constructor():
Name = $(card.Arguments[0])
|]
Maintenant, je ne sais pas ce que dois-je faire avec card.Body pour rendre le code macro ajouter la capacité du constructeur tout en générant une classe imbriquée. Des pensées? Cela peut-il être fait avec des capacités linguistiques actuelles?
La solution
Il peut être fait. Voici comment:
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)()) |]
Le crédit va à Cedric Vivier pour me aider dans la groupe Google boo .