Seven Languages in Seven Weeks: Day 6

Last day of Io and what do we have? A small snippet that adds [1, 2, 3] style array literals to the language. Kind of neat that you can do it... also the kind of thing that can almost certainly get you in trouble.

squareBrackets := method(
    lst := List clone
    call evalArgs foreach(arg,
        lst append(arg)
    )
    return lst
)

... and here's a Builder that lets you create XML documents by dynamically translating messages into XML elements.

Builder := Object clone
Builder forward := method(
    node := Element new(call message name)
    call message arguments foreach(arg,
        content := self doMessage(arg)
        if(content type == "Sequence",
            node addChild(TextNode new(content)),
            node addChild(content)
        )
    )
    return node
)

Node := Object clone
Node indent := method(depth,
    return "\t" repeated(depth)
)

TextNode := Node clone
TextNode new := method(text,
    node := TextNode clone
    node text := text
    return node
)

TextNode render := method(depth,
    writeln(self indent(depth), self text)
)

Element := Node clone
Element new := method(name,
    other := self clone
    other attrs := Map clone
    other name := name
    other children := List clone
    return other
)

Element addChild := method(child,
    self children append(child)
)

Element attr := method(k, v,
    self attrs atPut(k, v)
    return self
)

Element fmtAttrs := method(
    if(self attrs isEmpty,
        return "",
        return " " with(self attrs map(k, v,
            k with("=\"", v, "\"")
        ) join(" "))
    )
)

Element render := method(depth,
    writeln(indent(depth), "<", self name, self fmtAttrs, ">")
    self children foreach(child,
        child render(depth + 1)
    )
    writeln(indent(depth), "</", self name, ">")
)

... and a Builder document ends up looking like this:

Builder ul(
    li("some text") attr("class", "first"),
    li("some more text"),
    li("even more text") attr("class", "last")
) attr("class", "fancy") attr("id", "menu") render(0)