Introduction
In this project you're going to add syntax and semantics to a small Java-like language so that it understands anonymous code blocks called closures. The only hard part will be that closures can see local variables and parameters from surrounding scopes. These variables, which are normally stored on the Java stack, will have to be held in objects on the heap. Then, any references to those variables will have to become object field accesses.
To keep things simple, we will only allow programs to be lists of statements and declarations. We will not have classes, for example.
You will build a source to source translator that accepts a Java+closures file and translates it to a straight Java version in the same directory:
$ java ClosureTrans t1
The ClosureTrans program reads in t1 and writes pure Java into t1.java.
Besides Java classes, your translator must also accept a simple series of statements in lieu of the usual Java main() method within a class.
To get started, download the support code and grammar skeletons.
Translation rules
As we discussed in class, you must first come up with a series of manual transformations so that you can identify precisely what subphrase maps to what output subphrase. Here is a set of transformations to help guide you in your project. Notice that when a closure is detected within a function, all of the locals and arguments must go into the heap via some temporary classes.
| SL | Java |
|---|---|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
Details
You have a number of goals in this project:
- Add [...] list literal notation
- Add {args_ | _code} closure notation (like a lambda function); you must allow multiple arguments, though closures applied to a list only have one argument.
- Add ':' map operator that applies a closure (right operand) to a collection (left operand). As a special case, allow Strings as left operands, which turn into a stream of char. If the left operand is not Iterable or a Map or a String, simply apply the closure to the object as a single value.
- Implement the map() method in the Closure class.
- Update SL.g to use ClosureSymbol upon entering a closure scope.
- Update ClosureTrans so that it writes output to x.java from x input file (currently it writes to stdout).
- You'll have to add symbol table management to SL.g and tweak Rewrite.g so it uses the information.
- Figure out how to translate local variables and argument references when we have a closure in a function.
- How to move functions out of the main() function you generate.
- If imaginary nodes don't have the start..stop token indexes you need to do the rewrite, you might use CommonTree.setUnknownTokenBoundaries() at the root level before running the tree through Rewrite tree walker.
Closure looks like:
I have decided to make SL language simpler. Please remove classes and method calls (not regular function calls) and constructors from the language SL.g file and Rewrite.g tree grammar. Makes symbol table management easier.
Testing
Leon Su has created an awesome grammar unit testing tool called gUnit. It can test both parsers and parser+tree walker combos. For example:
gunit Rewrite walks SL;
prog walks prog:
t1 -> t1.java // file t1 should yield t1.java
"print 32;" -> <<
import java.util.*;
public class t1 {
public static void main(String[] args) {
System.out.println(32);
}
}
>>
For example, you could use gUnit to compare the above input / output pairs. You can also use Shaoting's new GUI for gunit.
Submission
You will create a jar file called closures.jar containing grammars, source, and *.class files and place in your lib directory:
https://www/svn/userid/cs652/proj6/trunk/lib
You can use the svn account for development of the software to if you would like, but I will only be looking at your closures.jar file in the lib directory.
Please bring a printout of SL.g, Rewrite.g, your gUnit tests, and Closure.java (which has the map() method) as well as the output code generated from all examples shown in the table of transformations above.
Grading
Make sure your jar has the ClosureTrans class in the default package with a main method so that I can test your code. I will run a number of examples that you have not seen through your project.
1 Comment
comments.show.hideFeb 18, 2010
Anonymous
I've recently read a very interesting discussion I found by http://rapid4me.com SE concerning update on Closures coming to Java7. can make just one question: when will people realize that the majority of Java programmers aren't nearly as dissatisfied with the language as functional programmers seem to think? Give me NIO2, properties, a better date & time API, multi catch, the "elvis operator", USB & Serial ports on all OS's, and Java EE 6 instead. Hopefully once Oracle takes over Sun they will have the money and manpower to increase the pace of enhancement to the Java language. Since JDK7's release date has been pushed way out, maybe they can finally include these kinds of useful features.