Stratego J

Stratego -- Strategies for Program Transformation

Stratego/J: A Stratego Core Format Engine

Stratego/J is an execution engine for the Stratego language, implemented in Java. It allows the execution of the full Stratego language on the Java virtual machine.

It may be easiest to think of Stratego/J as the implementation of an abstract Stratego machine. The Stratego compiler can, using the -F option, output a compiled Stratego program in a high-level Stratego-specific format which Stratego/J can execute. It is currently not possible to interactively evaluate Stratego source code on Stratego/J -- for that, use Stratego Shell.

For more details, see http://www.spoofax.org/strategoj.html

Embedding the Stratego runtime

Adding the Stratego interpreter to your Java project is pretty straightforward.

First, add the Stratego/J runtime jar files in your classpath.

Second, compile your Stratego program using strc -F to obtain a program in the Stratego Core Format.

Third, initialize and call the interpreter along these lines:

 
String strategyName = ...
IStrategoTerm initialTerm = ...
InputStream program = ...
Interpreter interp = new Interpreter();
try {
  interp.load(program);
  interp.setCurrent(initialTerm);
  boolean success = interp.invoke(strategyName);
} catch(Exception e) {
  e.printStackTrace();
}

The initialTerm is the current term to be used when the interpreter starts executing. Default is (). The program is an InputStream to the .ctree file of your Stratego program. The strategyName is in Core Format form, e.g. main_0_0.

The interpreter will return false if the invoked strategy fails. Exceptions are reserved for exceptional circumstances and internal errors; in practice, they should only arise when calling prim() functions.

Factories

The interpreter represents both the program and the data as terms. By default, this factory is the same, and knows how to read ATerms in textual form. If you need other ATerm formats, consider invoking the interpreter with the WrappedATermFactory, after you remeber to add both the ATerm library and the ATerm wrapper library to your classpath:

new Interpreter(new WrappedATermFactory())

It is possible to have separate factories for the program and the data:

new Interpreter(new BasicTermFactory(), new WrappedATermFactory())

The first argument is for the program factory, the second for the data.

POM adapters

By using the POM adapter technique, you can rewrite any object graph for which you have an adapter. All you need is to supplying an instance of the factory for the adapter.

Adding native functions

The interpreter supports the notion of operator registries. These are basically sets of prim() strategies that may be added to the interpreter when you instantiate it, e.g.:

interp.addOperatorRegistry(ECJLibrary.REGISTRY_NAME, new ECJLibrary());
interp.addOperatorRegistry(EFILibrary.REGISTRY_NAME, new EFILibrary());

Here, the Eclipse Compiler for Java registry is added, followed by the Eclipse foreign functions. The first allows Stratego scripts to invoke methods on some of the objects of the Eclipse Java Compiler. The second allows scripts to call Eclipse file and UI functions, to open windows and load resources. (These registries are available as separate jars).

-- KarlTrygveKalleberg - 06 Jun 2008