I'm creating a DSL for an extensible card game engine I'm working on, with boo.
I have a card macro that creates a class for a new type of card, and initializes some properties in the constructor. That macro has a few submacros for setting other things. Basically I want it to turn something like this:
card 'A new card':
type TypeA
ability EffectA:
// effect definition
into this:
class ANewCard (Card):
def constructor():
Name = "A new card"
Type = Types.TypeA
AddEffect(EffectA())
class EffectA (Effect):
// effectdefintion
The effect definitely needs to be a class, because it will be passed around (it's a Strategy pattern).
So far, I have this simple skeleton:
macro card:
yield [|
class $(ReferenceExpression(card.Arguments[0])) (Card):
def constructor():
Name = $(card.Arguments[0])
|]
Now, I don't know what should I do with card.Body to make the ability macro add code to the constructor while also generating a nested class. Any thoughts? Can this be done with current language capabilities?
It can be done. Here's how:
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 goes to Cedric Vivier for helping me out in the boo Google group.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With