Wednesday, March 28, 2012

Seven Languages in Seven Weeks - Io Day 3 Self-Study

It's been some time now, still I'm keeping up reading Seven Languages in Seven Weeks. Here's the last self-study section about the Io programming language.

Enhance the XML program to add spaces to show the indentation structure.

Builder := Object clone
Builder numIndents := 0
Builder doIndents := method (for (i, 1, numIndents, write(" ")))
Builder openTag := method(name, doIndents; writeln("<", name, ">"))
Builder closeTag := method(name, doIndents; writeln("</", name, ">"))
Builder forward := method (
  openTag(call message name);
  numIndents = numIndents + 1;
  call message arguments foreach (
    arg,
    content := self doMessage(arg);
    if (content type == "Sequence", doIndents; writeln(content))
  );
  numIndents = numIndents - 1;
  closeTag(call message name)
)

Builder ul(
  li("Javascript"),
  li("Lua"),
  li("Javascript")
)

Create a list syntax that uses brackets

squareBrackets := method(call message arguments)

Enhance the XML program to handle attributes: if the first argument is a map (use the curly brackets syntax), add attributes to the XML program. For example: book({"author": "Tate"}...) would print <book author="Tate">.

OperatorTable addAssignOperator(":", "atPutNumber")
Map atPutNumber := method(
  self atPut(
    call evalArgAt(0) asMutable removePrefix("\"") removeSuffix("\""),
    call evalArgAt(1)
  )
)
curlyBrackets := method(
  map := Map clone;
  call message arguments foreach(arg, map doMessage(arg));
  map
)

Builder := Object clone
Builder numIndents := 0
Builder doIndents := method (for (i, 1, numIndents, write(" ")))
Builder doAttributes := method(map, map keys foreach(key, write(" ", key, "=\"", map at(key) ,"\"")))
Builder forward := method (
  doIndents; write("<", call message name);
  if(call message arguments size == 0, writeln(">"));
  numIndents = numIndents + 1;
  call message arguments foreach (i, arg,
    content := self doMessage(arg);
    if (i == 0, 
      if(content type == "Map", doAttributes(content));
      writeln(">")
    )
    if (content type == "Sequence", doIndents; writeln(content));
  );
  numIndents = numIndents - 1;
  doIndents; writeln("</", call message name, ">")
)