Overview

JFuncMachine is a library providing an intermediate language for code generation, with the idea that it could be used as a back-end for a compiler. Although it was designed with functional languages in mind, it should support imperative ones, although it currently lacks some features like a looping construct that might be more suitable for imperative languages.

Method Definitions

JFuncMachine produces Java classes, which is the only way to generate code for the Java Virtual Machine. Any code you generate will be in the form of a method.

The basic things that define a method are its name, its parameter names and types, its return type, and the expression that is to be executed when the method is called.

While it may sound limiting to only execute one expression, this is not unusual for functional languages. It is possible to execute several expressions using a Block expression, which executes a list of expressions discarding the return values of all but the last one, which is the return value of the Block expression.

A method definition for a method named getNum that takes no parameters and returns the integer 5 could be defined this way:

MethodDef method = new MethodDef("getNum", Access.PUBLIC,
    new Field[]{}, SimpleTypes.INT, new IntConstant(-5));

Constructor Definition

You can define constructors like you define methods, only using the ConstructorDef class, which does not require a method name. If you just want to generate a default constructor that invokes its superclass constructor, the ConstructorDef class contains a generateWith method that just takes a parameter list and generates a constructor that calls its superclass with the same parameters it is passed. For a default constructor with no arguments, you can use ConstructorDef.generateWith(new Field[0]).

Field Definitions

You can define a class field using a ClassField instance. You provide the field name, type, access flags, and an optional default value. For example, this is a definition of a String field named “aField” with a default value of “foo”:

ClassField field = new ClassField("aField", SimpleTypes.STRING,
        Access.PUBLIC + Access.STATIC, "foo");

Class Definition

Once you have some method definitions and/or field definitions, you can create a class definition with the ClassDef class. You typically supply a package name, or null if there is no package, and can optionally specify a super class. You must also supply any access flags for the class such as Access.PUBLIC, and then give the methods, fields, and any interface names implemented by the class.

Combining the items defined above, here is an example class definition:

MethodDef method = new MethodDef("getNum", Access.PUBLIC,
    new Field[]{}, SimpleTypes.INT, new IntConstant(-5));

ConstructorDef constructor = ConstructorDef.generateWith(
    new Field[0]);

ClassField field = new ClassField("aField", SimpleTypes.STRING,
        Access.PUBLIC + Access.STATIC, "foo");

ClassDef exampleClass = new ClassDef("org.jfuncmachine.example",
    "ExampleClass", Access.PUBLIC,
    new MethodDef[] { constructor, method},
    new ClassField[] { field },
    new String[0]);

Generating the Class

Once you have a ClassDef you can use the ClassGenerator to generate a class:

ClassGenerator generator = new ClassGenerator();
try {
    generator.generate(exampleClass, "out");
} catch (IOException e) {
    throw new RuntimeException(e);
}

This will write out ExampleClass.class to a directory named “out”. The full pathname of the file would be “out/org/jfuncmachine/example/ExampleClass.class”.