Twitter icon.
Random notes on software, programming and languages.
By Adrian Kuhn

Roman Numerals, in your Java


Today’s hack is based on Lukas’s recent work on DSLs. Imagine you could compile and run a Java program that uses Roman numerals.

public class Example {
    public static void main(String[] args) {
        System.out.println(
            MCMLXXVII + XXIV
        );
    }
}

It can be done—put this 7.5 kb jar in your compiler’s classpath!

% javac -cp roman.jar Example.java
Note: 2 roman numerals processed.
% java Example
2001
%

Obviously, this jar extends the syntax of Java … close, but not quite. The source code that contains the Roman numerals is already valid Java syntax. It is valid Java with undeclared variables! If you compile it without our small jar, the compiler will tell you that the Roman numerals are undeclared variable names. Thus, our small jar hooks into the compiler, bending JSR 269 beyond its limits, and replaces all roman variables names with integer literals.

Caveat, requires Java 6.

Below the rewrite rule: class Transform extends TreeTranslator, an internal class of the Java compiler. Transform visits all statements in the source code, and replaces each variable whose name matches a Roman numeral with an int literal of the same numeric value.

public class Transform extends TreeTranslator {
    @Override
    public void visitIdent(JCIdent tree) {
        String name = tree.getName().toString();
        if (isRoman(name)) {
            result = make.Literal(numberize(name));
            result.pos = tree.pos;
        } else {
            super.visitIdent(tree);
        }
    }
}

Our small jar implements an internal DSL, but an unusual one. We reuse the host language’s original syntax in a creative way that allows us to express new semantics. Lukas refers to this kind of language extension as “pidgin”, since human pidgin languages play in a similar way with natural language.

For the technically inclined, the complete source code is available on SCG subversion.

 

You may also like

9 Responses to “Roman Numerals, in your Java”

  1. Walter Harley Says:

    “bending JSR 269 beyond its limits” is accurate… one of the core precepts of JSR 269 is that it disallows modifying existing classes. Your code is bound to the implementation details of Sun’s javac, and will not work on other compilers (such as Eclipse’s).

    Nothing wrong with that, just thought I’d point out that this isn’t a JSR 269 hack, it’s a Sun javac hack. But a fun one!

  2. raveman Says:

    is there any way to make it work in eclipse?

  3. rogersm.net » Blog Archive » You can hook code to the Java compiler Says:

    [...] had no idea you can plug into javac to do nifty things like adding roman numerals to your java [...]

  4. Stephane Grenier Says:

    Interesting idea. Of course I don’t know that you’d program this way, but it sure brings up some interesting points on how to create your own custom pre-processor.

    And I for sure didn’t realize how simple it is to implement if you know how to do it! Thanks.

  5. akuhn Says:

    @raveman the hack uses internal classes of Sun’s java compiler (see also Walter Harley’s comment). By default eclipse uses its own compiler, you have to change that in the project settings (or use an ant script to compile the code, as I do).

  6. Java math with roman numbers… « GHads mind Says:

    [...] just found this page: For.example [...]

  7. Jewelry With Meaning: Roman Numeral Jewelry - Jewelry Says:

    [...] For.example » Blog Archive » Roman Numerals, in your Java [...]

  8. McDowell Says:

    If you want to get your hooks into the Eclipse compiler via its annotation processor, start by creating a new plugin.

    -Contribute to the “org.eclipse.jdt.apt.core.annotationProcessorFactory” extension point.

    -In the “javax.annotations.processor.Processor” implementation, cast the ProcessingEnvironment to “org.eclipse.jdt.apt.pluggable.core.dispatch.IdeBuildProcessingEnvImpl”

    -After that, you’re on your own!

  9. miau Says:

    this is awesome. although I wish we could get rid of the backward compatibility of having to still support roman numbers.

For.example is Digg proof thanks to caching by WP Super Cache!