Pattern matching Erlang terms in Java™ using Tom and Jinterface

Tom version 2.3 has just been released. Tom is an excellent pattern matching compiler that generates Java™ code to match terms in the form of graphs of Java™ objects. Tom is free software, and released under the GPL.

This reminded me that about one year ago I wrote a Tom specification for Erlang/OTP‘s Jinterface library, to allow to match Erlang terms represented as Java™ objects that are instances of Jinterface’s classes. I wrote it to simplify a Java™ interface to IDX-Tsunami’s (now renamed Tsung) system performance monitor. For its first birthday, I have published this specification (jinterface.tom and its support classorg.erlang.PatternMatchingUtility), under the LGPL.

Update (2006-05-01): I forgot to include the code of the Java™ class (org.erlang.PatternMatchingUtility) which implements utility methods that are called by the pattern matching code generated when using jinterface.tom. Now, both files are ditributed in an autotooled tarball: jinterface.tom-0.1.tar.gz. Just run./configure ; make ; make install and files should (hopefully) compile and install in/usr/local/share/java/.

Here is an example of a Java™ class using this specification (the file should be named Test.t to reflect that the code is in Java™ extended with Tom syntax):

public class Test {

    /*
     * Include the JTom-Jinterface specification.
     */
    %include { jinterface.tom }

    /*
     * This is a normal Java method, which code uses Tom's
     * extensions to the Java language.
     */
    protected void matchMessage(OtpErlangObject message) {

        boolean matched;
        long operationIdentifier;
        String nodeName;

        /*
         * The message matches if it has the form:
         * OtpErlangObject message =
         *     new OtpErlangTuple(new OtpErlangObject[] {
         *         new OtpErlangAtom("get_reply"),
         *         new OtpErlangLong(operationIdentifier),
         *         new OtpErlangString(nodeName),
         *         new OtpErlangLong(value) or new OtpErlangDouble(value)
         *     });
         *
         * Match the message, using Tom's "match" syntax, similar to
         * Erlang's "case" construct:
         */
        %match(Term message) {
            tuple(atom("get_reply"),
                long_number(opId),
                string(nN),
                double_number(value)) -> {
                    matched = true;
                    operationIdentifier = opId;
                    nodeName = nN;
                    System.out.println("Matched double value: " + value);
                }
            tuple(atom("get_reply"),
                long_number(opId),
                string(nN),
                long_number(value)) -> {
                    matched = true;
                    operationIdentifier = opId;
                    nodeName = nN;
                    System.out.println("Matched long value: " + value);
                }
        }

        if (matched) {
            System.out.println("Node name: " + nodeName);
            System.out.println("Operation id: " + operationIdentifier);
        } else {
            System.out.println("Message did not match.");
        }
        
    }

}

This file must be compiled with Tom’s compiler, to generate the actual pattern matching source code in the Test.java file which can then be compiled as normal Java™ source code:

> tom --static --wall --verbose --pretty Test.t
> javac Test.java

If you installed the jinterface.tom file into /usr/local/share/java/ directory, you must pass an --import /usr/local/share/java/ option to the tom compiler. And add /usr/local/share/java/ to the CLASSPATH so that the Java™ compiler can find the org.erlang.PatternMatchingUtility class.

Some types of terms are still not yet supported by my Tom specification: binaries and new style references. And maybe I should switch to Ant as the build tool for the support class, instead of GNU Automake’s horrible support of Java™ (and of almost anything, by the way…). Any volunteers?