Makevisitors: Pass 3
Generate the Java abstract
class
es
For each complex Haskell data type, we need to generate an abstract class in
Java. This class should declare an abstract method accept
, for visitors.
Repeating our example from the previous passes, here is a Haskell data type and its corresponding abstract syntax.
-- concrete Haskell declaration
data Expr = Value {value :: Integer}
| BinOp {operator :: Op, leftOperand :: Expr, rightOperand :: Expr}
-- abstract syntax (an instance of TyDefs)
[Datatype "Expr" [ Record "Value" [ ("value", Base "Integer") ]
, Record "BinOp" [ ("operator", Base "Op")
, ("leftOperand", Base "Expr")
, ("rightOperand", Base "Expr") ]]
Here is the corresponding translation to an abstract Java Expr
class:
// Java declaration
public abstract class Expr {
public abstract void accept(ExprVisitor visitor);
}
-- abstract syntax (an instance of JDeclaration)
ClassDef [Public,Abstract] "Expr" Nothing []
[MethodDef [Public,Abstract] (Typename "void") "accept" [(Typename "ExprVisitor","visitor")] NoBody]
Your task: In Translate.hs
, complete the implementation of the third pass.
We recommend that you write some helper functions!
After you complete this pass, you should be able to generate abstract base classes for any complex data type. The Java code likely won’t compile because you haven’t yet implemented the part that generates concrete classes for that type.
Testing. It is largely on you to test your code. We suggest:
- In
makevisitors.hs
, comment out the calls for the unimplemented passes (just make sure to uncomment them as you implement them):genConcreteSubclasses
- Write a sample file and check that the generated abstract class matches your expectations.
- Run
make test
, which will generate code for lots of different examples. Check that the abstract classes are generated as you expected. You can compare your code against the code generated by the reference implementation, specifically:exprTest/Expr.java
jsonTest/JValue.java
lambdaTest/Expr.java
lambdaTest/Value.java
randomTest/Foble.java
randomTest/Widget.java
stack/StackInstr.java
These files should match yours. (The other files were generated by a complete implementation, whereas you currently have a partial implementation.)