Project 8: Implementing the Em Family

The goal of this project is to understand how we can encode a complicated functional language in a smaller language. In this project you will implement the translations among the Em family of languages that we saw in class Monday and Wednesday.

1. Set up

The system for implementing these languages is called EmIly (for Em family). You can copy EmIly from

~tvandrun/Public/cs365/proj8.tar

This project, unlike the others, is written in Java. For each language (BoolEm, DeclEm, Em, and ListEM) there are three packages, abssyntree, astvisitor, and parser. The parser is generated by Antlr (version 3); the abstract syntax tree classes and visitor super classes are generated by a tool I wrote myself, being dissatisfied by the existing options at the time. The basic workings of it (operations on the program are implemented as visitors that walk ASTs) are the same as the earlier projects, but the big difference that Java brings is static typing. This means that the compiler (or Eclipse or whatever) will find statically many simple mistakes that you'd have to run the Python program to find; it also means that the code will be more verbose.

As in other projects that involve translating from one language to another, we could do that translation either by producing the text of the program in another language or by producing new abstract syntax trees (Java's static typing prohibits us from simply modifying the syntax trees). I have set this up for producing the text of the translated program.

For BoolEm we have an InterpreterVisitor, along with a handful of other helper visitors (all finished). For the other languages we have classes each called TranslatorVisitor, which you will need to finish.

You will also see a directory of sample test programs.

2. Your task

There are nine steps in this project, corresponding to the nine translations we have seen in class:

  1. In declem.astvisitor.TranslatorVisitor.visit(Let), translate let expressions into BoolEm, which does not have lets.
  2. In declem.astvisitor.TranslatorVisitor.visit(Application) translate applications with many actual parameters into BoolEm, where all functions have one parameter.
  3. Similarly, in declem.astvisitor.TranslatorVisitor.visit(Abstraction), translate applications with many formal parameters into BoolEm.
  4. In em.astvisitor.TranslatorVisitor(FunDeclaration), translate recursive functions declarations into DeclEm, which does not have (explicit) recursion.
  5. In listem.astvisitor.TranslatorVisitor(Cons), translate uses of the cons operator.
  6. In listem.astvisitor.TranslatorVisitor(Test), translate tests if a list is null.
  7. In listem.astvisitor.TranslatorVisitor(List), translate explicit lists (e.g., [true, false, false, true]).
  8. In listem.astvisitor.TranslatorVisitor(Car), translate uses of hd.
  9. In listem.astvisitor.TranslatorVisitor(Cdr), translate uses of tl.

3. Practical considerations and testing

To execute a program in any of these languages, use

java -cp .:antlr3.jar em.EmIly programname

(Note the need to include the Antlr jar file. Of course you also could simply add it to your CLASSPATH environment variable, and if you're using Eclipse you definitely want to add the jar file as a library. If you need help doing either of those things, just ask.)

The EmIly program will determine which language is being used by the extension (so, name all of your DeclEm tests something that ends in .declem). It will do the appropriate translations and then execute the final BoolEm program. For example,

java em.EmIly rec.em

will...

For debugging purposes, you may want to suppress execution of the program and only print the translation. This can be done by using the -p flag, which prints only the first translation of the program and then stops. Similarly, the -pp flag prints all translations, but does not run the program.

I have given you a few sample programs, but an important part of this project is to write your own tests. It is much better to write many small tests. In particular, you will have best results with tests whose values are a booleans (or very simple abstractions). Since BoolEm has no lists, any ListEm program whose result is a list will appear as a (very complicated) abstraction. Hence it is better to test

hd(tl(true::[true,false,false,true]));

than

true::[true,false,false,true]

Finally, make sure you start with the DeclEm part and progress up the family hierarchy and test as you go If you try to write all the translations first and then execute reverse.listem as your first test, you will almost certainly get unpleasant results.

4. To turn in

Turn in your files listem.astvisitor.TranslatorVisitor, declem.astvisitor.TranslatorVisitor, and em.astvisitor.TranslatorVisitor, to appropriate directories:

/cslab.all/ubuntu/cs365/turnin/xxxxxx/proj8/yyyyy

where "xxxxxx" is [elliot|payton|davidemmanuel|nathan|gill|brandon|sean|simon] and "yyyyy" is [declem|em|listem]. I will grade your project by running it against a collection of test files.

DUE: Wednesday, April 30, 5:00 pm.


Thomas VanDrunen
Last modified: Fri Apr 25 13:59:41 CDT 2014