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”.