Toy ST implementation

This example is a toy implementation of the StringTemplate template engine. It uses a bytecode interpreter and disassembler pulled directly from:

Discussion

I'm in the process of rebuilding ST from the ground up. The previous version works well, but it's hard for me to maintain because it uses a tree-based interpreter. Further, it uses v2 ANTLR not v3. In order to remove the dependencies in ST and in v3 itself on ANTLR v2, I'm rebuilding both (though only the front end of ANTLR). The functionality will be effectively the same, with some slight differences in syntax. Lots of little things cleaned up and so on.

Along they way, I've created a very simple bytecode compiler and interpreter that handles the canonical operations:

  1. attribute reference: <name>, <user.id>
  2. template inclusion: <searchbox(args)>
  3. map template to attribute(s): <names:bold:italics>
  4. conditional inclusion: <if(error)>foo<elseif(thumbs up)>bar<else>ick<endif>

It seems to work and the code (1900 lines) seems pretty doggone clean to me. It's only when you start dealing with separators and auto indentation and anchoring output values, that the code becomes difficult to understand.

Differences from ST v3

  • <names:bold> not <names:bold()>
  • ST not StringTemplate
  • STGroup not StringTemplateGroup
  • ST.add() not setAttribute()
  • render() not toString() used to render templates to text

Source

You can download the Toy ST tarball.

Testing

File TestCoreBasics.java has tests for the interpreter like this:

    @Test public void testAttr() throws Exception {
        String template = "hi <name>!";
        ST st = new ST(template);
        st.add("name", "Ter");
        String expected = "hi Ter!";
        String result = st.render();
        assertEquals(expected, result);
    }

TestCompiler.java has tests for the compiler:

    @Test public void testAttr() throws Exception {
        String template = "hi <name>";
        CompiledST code = new Compiler().compile(template);
        String asmExpected =
            "load_str 0, " +
            "write, " +
            "load_attr 1, " +
            "write";
        String asmResult = code.instrs();
        assertEquals(asmExpected, asmResult);
        String stringsExpected = "[hi , name]";
        String stringsResult = Arrays.toString(code.strings);
        assertEquals(stringsExpected, stringsResult);
    }