EPP 1.0 についてくる plug-in の説明です。
説明のあと、「plug-in ソース」「使用例」「変換結果」のリンクがあります。
各クラスの内容は、もともとのファイルでの位置と同じ行に出力されます。 例えば、 File.java に public なクラス A, C と friendly なクラス B が あったとすると、 eppout の下には File.java、 A.java 、 C.java が 作られ、それぞれの中身は以下のようになります。
File.java eppout/File.java eppout/A.java eppout/C.java +--------------+ +--------------+ +--------------+ +--------------+ |public class A| | | |public class A| | | +--------------+ +--------------+ +--------------+ +--------------+ |class B | => |class B | | | | | +--------------+ +--------------+ +--------------+ +--------------+ |public class C| | | | | |public class C| +--------------+ +--------------+ +--------------+ +--------------+展開後の Java プログラムを javac してエラーが出ても、 クラス名と行番号から、もともとの場所を容易に特定できます。
defmacro max(a, b) (a > b ? a : b) defmacro swap(t, a, b) {t tmp; tmp = a; a = b; b = tmp;}マクロ展開のパターンは、"(" か "{" で始まらなければなりません。 "(" で始まる場合は式として、 "{" ではじまる場合はブロックとして その先がパーズされます cpp と違って、変換はトークン単位ではなく、構文解析後の tree に 対して行なわれます。 (したがって、この defmacro では、 Java の文法の変更はできません。)
マクロは関数呼び出しのスタイルに限られます。 #define と違って、次のようなマクロは定義できません。
defmacro SIZE 1024 /* これはだめです。 */cpp の #define の場合は次のように展開後の引数の内側をかっこでくくる 必要がありますが、この defmacro ではその必要はありません。
#define max(a, b) ((a) > (b) ? (a) : (b))
epp -plug-in EmbedCopyright *.javaのようにしてこの plug-in を指定すれば、 Copyright.txt の中身が すべてのクラスの static field の初期値の形で埋め込まれます。
a (+) b a.plus(b) a (-) b a.minus(b) a (*) b a.times(b) a (/) b a.divide(b) a (%) b a.modulus(b) a (<<) b a.leftShift(b) a (>>) b a.rightShift(b) a (>>>) b a.unsignedRightShift(b) a (==) b a.equals(b) a (!=) b !a.equals(b) a (<) b a.lessThan(b) a (>) b a.greaterThan(b) a (<=) b !a.greaterThan(b) a (>=) b !a.lessThan(b) a (&) b a.and(b) a (|) b a.or(b) a (^) b a.not(b)この plug-in は、 EPP の lexical analyzar を拡張する例でもあります。
epp -plug-in noassert File1.java File2.java ...noassert plug-in を追加することで、 assert plug-in の機能を override します。
なお、現在の実装では & をつけられるのは int 型の変数のみです。
現在のバージョンの EPP は型情報をいっさい扱っていないためです。
plug-in ソース /
使用例 /
変換結果
if (0 <= x && x < max) ...;と書く代わりに、
if (0 <= x < max) ...;というふうに、数学的な記法そのままで書けます。
他の plug-in は Java の機能を「拡張」するものですが、 この plug-in は、オリジナルの Java の文法の一部を「置き換える」例に なっています。 (ソースコードの先頭の方で、 標準の Java パーザ部品を取り除いています。)
なお、この plug-in も、比較の対象は int 型だと仮定しています。
plug-in ソース /
使用例 /
変換結果
Tree fname = tree.args()[0]; return `(invokeLong (name (id java) (id lang) (id Math)) ,fname (argumentList ,@args));
defineNonTerminal(NonTerminalName, DefaultValue); defineBinaryOperator(SystemMixinNAME, Token, PRECEDENCE);