Сложный бу синтаксический макрос - PullRequest
5 голосов
/ 15 июля 2009

Я создаю DSL для расширяемого движка карточных игр, над которым я работаю, с boo.

У меня есть макрос для карты, который создает класс для нового типа карт и инициализирует некоторые свойствав конструкторе.Этот макрос имеет несколько вложенных макросов для настройки других вещей.По сути, я хочу, чтобы он превратил что-то вроде этого:

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

в это:

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

    class EffectA (Effect):
        // effectdefintion

Эффект определенно должен быть классом, потому что он будет передан (это стратегияшаблон).

Пока у меня есть этот простой скелет:

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

Теперь я не знаю, что мне делать с карточкой. Чтобы сделать макрос способности добавить код вконструктор, в то же время создавая вложенный класс.Какие-нибудь мысли?Можно ли это сделать с помощью текущих языковых возможностей?

1 Ответ

6 голосов
/ 17 июля 2009

Это можно сделать. Вот как это сделать:

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

Благодарим Седрика Вивье за ​​помощь в бу группе Google .

...