The Premon applet is a mid-sized (and I'm afraid rather underdocumented) piece of software: there's approx 11k lines of Java, of which approx. 8k lines are code.
The index of source code files and the class heirachy are available, but since there's 175 class files, this may be a bit daunting!
The program is broken down into phases, each of which has associated classes:
This was the first Java program I ever wrote (beyond "Hello World") and if I were to do it again, I would do it differently (eg I'd now use AWT1.1) but such is life.
The main user interface classes are:
AppletPremon, which takes an expression, the free variables, and the primitives as arguments, constructs a PremonEnvironment object containing the parsed ASTs, the semantics, and the graph for the expression, then draws the result to a CanvasDrawer object. A mouse click on the graph causes a PremonPanel source code editor to pop up in a separate frame.
AppletPremonEditor, which is an applet containing a PremonPanel source code editor.
The parser is written in v0.8 of the JavaCC Java Compiler Compiler, using the JJTree tools.
PremonJJTParser is an LL(1) grammar for the Premon language, including syntax sugar.
The PremonJJTParser parser
generates abstract syntax trees. Each AST class is a subclass of
PremonJJTNode. Each subclass includes a
desugar method which returns a typechecked AST with all
syntax sugar removed.
PremonJJTCat is a class for categories.
PremonJJTCon is a class for contexts.
PremonJJTDec is a class for declarations.
PremonJJTExp is a class for expressions.
PremonJJTId is a class for identifiers.
PremonJJTPat is a class for patterns.
PremonJJTType is a class for types.
desugar method returns a type-annotated abstract
syntax tree, where all the syntax sugar has been removed. Each AST
class has a method
semantics which returns the semantics
as an object (in the case of types or contexts) or a morphism (in the
case of expressions or declarations).
PremonCat is a class for categories.
PremonCon is a class for contexts.
PremonDec is a class for declarations.
PremonExp is a class for expressions.
PremonPat is a class for patterns.
PremonType is a class for types.
PremonVar is a class for variables.
The categorical semantics is given as a partially traced, closed
premonoidal category with a given monoidal centre and cartesian focus.
Each class has methods representing the categorical structure, such as
curry etc. The
Mor class has methods
graph1 to produce graphs.
Mor is the class of morphisms.
Obj is the class of objects.
The graph representation consists of a set of constraints, plus a
draw which draws the graph once the constraints
have been solved. There is also a dynamic programming algorithm to
solve the constraints (which isn't optimal, but it's good enough).
Graph0 is the class of graphs with no
control lines. It consists of a Constraints
object and a
draw(Drawer) method which draws the
graph once the constraints have been solved.
Graph1 is the class of graphs with one control lines, similar to the Graph0 class.
Constraints is a class containing a constraint set. This is a collection of variables v1...vn together with a collection of constraints of the form vi + d <= vj. A constraint set can be solved, producing a Solution object.
Solution is a class containing a solution
to a constraints set. It provides a lookup function
value(i) is the value of variable
vi. The solution is implemented using a 2-pass
dynamic programming algorithm, which first minimizes the values (with
minimum 0), finds the resulting bounding box, then maximizes them
(with maximum given by the bounding box), and finally returns the
average of the minimum and maximum values. This is by no means an
optimal solution, but it's good enough.
Drawer is the class of `places which can be drawn to'. It is constructed from a low-level Grapher graphics class, and a Solution to the constraints.
Grapher is a low-level graphics class, implemented either using an AWT graphics context, or a PostScript back end (this was all written in the days before the AWT 1.1 PrintJob class existed).