Session 21

Implementing a Little Language Test-First


810:188
Agile Software Development


Introduction

In Chapter 2 of The Pragmatic Programmer, we read about the value of creating and implementing domain languages to help us build software. The idea of domain-specific languages has entered the mainstream in the last few years and grown increasingly popular. Google on "domain specific language", and you'll get about 19.900 hits. Check out the link to domain-specific language tools in Visual Studio 2005 to see how seriously Microsoft takes it.

But what the Pragmatic Programmers are talking about is something simpler and, well, more pragmatic. Everyday programmers often find themselves combing through a big data file by hand, looking for patterns or values or some other nugget. Or they find themselves wanting to write code that describes how their problem domain works, only to be stymied by the vagaries of their programming language. (Curse Java! Curse C!) The solution is often to create a little language that lets them say what they want, and then a parser or interpreter for processing expressions or programs written in the language.

Today's exercise gives you the chance to implement a little language processor. As usual, it also lets you exercise your test-driven development, refactoring and pair programming skills.


Procedure

You may implement in your language of choice, so long as you use JUnit or one of its brethren. But don't try to learn a new tool in class; that would take too long! [JUnit footnote]

Remember to practice the disciplines we have been discussing: Identify a single "story" or task to work on. Each task will usually require more than one test to ensure that the program behaves as specified.

  1. Write a test.
  2. Write the simplest code possible to pass the test.
  3. Refactor your program to pull out its design.
  4. Go to Step 1.

Continue until you are done, or time expires, whichever comes first. If you get done first, come talk to me!

Pair program with someone you've never programmed with before!


Exercise

Start with this template test class to build a program that aims toward this long-term goal:

Make it easy to control a simple turtle graphics system.

To this end, we have designed a little language. The syntax is simple. Programs consist of a sequence of commands. Each command is a single letter. Some commands take one argument, a number. A command line may contain an optional comment, which is all text that follows a '#' character.

You can use this typical program to drive your development:

P 5  # select pen 5
D    # put pen to surface
W 12 # draw west 12 units
N  5 # then north 5 units
U    # raise pen
P  3 # select pen 3
D
E 12 # then east 12
S 5  # finally south 5

Notice that white space is allowed. We might even allow for no white space in a command, say, "P5#select pen 5", because we know that commands are single letters and all arguments are numbers. (For now... The specification could change!)

At the highest level, processing a language involves two steps:

  1. parsing a language expression to recognize its meaning
  2. executing the expression

For now, let's have the behavior of each statement be to print itself onto standard output. But write your program so that we can change that behavior easily later (say, to generate Java or C, or to call the turtle graphics program itself).

If you are running on a Linux box, you can run a demo executable of this behavior. Download either the executable or a tarred, gzippedexecutable. This program reads statements from standard input.


Footnote on Using JUnit

In case you've forgotten the command and haven't already added junit.jar to your path:

Then again, why haven't you added these to your classpath by now?????


Wrap Up


Eugene Wallingford ==== wallingf@cs.uni.edu ==== November 11, 2004