Small Breve-a-like in Io

Filed under: breve io 

[Update: made a few improvements to the code]

I'm trying to understand the mechanisms for creating internal DSLs (embedded languages) in Io. Here's my first attempt at a Breve-like template language:

Tag := Object clone do (
    output := nil
    stack := nil

    init := method (
        output = List clone
        stack = List clone
    )

    squareBrackets := method (
        attrs := stack pop map ( pair,
            k := pair at ( 0 ) asString slice ( 1, -1 )
            v := pair at ( 1 )
            "#{k}=#{v}" interpolate
        ) join ( " " )
        name := stack pop

        output append ( "<#{name} #{attrs}>" interpolate )
        output append (
            call evalArgs select (
                result, result isKindOf ( List ) not
            ) join ( "\n" )
        )
        output append ( "</#{name}>" interpolate )
    )

    forward := method (
        stack push ( call message name )
        stack push ( call message arguments map ( v, v arguments ) )
        self
    )
)

Tag clone do (

    html [
        head [
            title [ "the title" ]
        ]

        body [
            div ( class="foo", id="bar" ) [
                "hello, world",
                "this is a test"
            ]
        ]
    ]

) output join println

Note that it's not very Breve-like except in general appearance (it's not a directed graph of objects that can be traversed). It's also not feature-complete (although many Breve features would be redundant in Io). Still, it's a nice proof-of-concept and not bad for a couple hours of floundering around by a complete Io novice.

In any case, Breve's syntax was largely bound by Python's and I'm thinking that I'll be ditching this syntax in favor of something even better.



0 comments Leave a comment