Index

Plug-in 開発の手順

1998-07-01


はじめに
--------
 このドキュメントは、 plug-in 開発の手順を大まかに説明するものです。
 また、最後の章では、 EPP のソースを bootstrap する方法を
説明しています。



開発環境
--------
 開発環境としては、現在以下の2つのみをサポートしています。
(まだ sh/bash 用の shell script しか用意してません。)

	Solaris/Linux, JDK1.1.5 以降
	Windows NT, gnu-win32 の bash, JDK1.1.5 以降

 ただし、JDK 以外の JavaVM、 Java コンパイラ(fastjavac, jvc, jview など)も、
shell script を編集すれば使えると思います。



設計
-----
・ plug-in を開発するには、まず plug-in の機能を設計するところから
始めます。

・作りたい plug-in の名前を決めます。
このドキュメントでは、以下 plug-in の名前を Foo とします。

・拡張機能の文法を決めます。
文法を決める場合は、既存の Java 文法や他の plug-in と衝突しないこと、
エディタを混乱させないこと、などに気をつけます。
できれば文法は拡張しない方がベストです。
普通の Java クラスライブラリとして実装できないか、
あるいは InvokeStyleMacro で実装できないかを検討して下さい。

・マクロ展開の方針を決めます。
具体的に展開前のコードと展開後のコードを書いて、
問題がないか検討します。



実装
----
・ファイル epp/Template/PlugIn.java は、
plug-in のソースのテンプレートです。
(ただし epp1.1.0beta3.1 までは、epp/sample/Sample/PlugIn.java 。)
まず、カレントディレクトリの下に、作りたい plug-in と同じ名前の
ディレクトリを作り、そこにテンプレートをコピーします。

	% mkdir Foo
	% cp epp/Template/PlugIn.java Foo

・ PlugIn.java の中身を編集します。

・まず文法拡張部分を実装します。
 例えば新しい statement を追加したい場合は、 statementTop という
メソッドを拡張します。

・マクロ展開関数を実装します。
そのために、まず、展開後のコードをS式に変換してみます。

	epp -tree -logfile Test.tree Test.java

そして、 Tree.tree からカットアンドペーストして、
PlugIn.java にバッククォートマクロで埋め込みます。
あとは、コンマでコードを適当に埋め込みます。

・一通り実装し終ったら、以下の点を確認します。
 package Foo; があるか。
 import epp.*; があるか。
 マクロ展開関数の登録を正しくしているか。

・ノードの名前は、既存のものと衝突しないように注意して下さい。
 SystemMixin の名前も、既存のものと衝突してはいけません。



テスト
------
・ plug-in のテストは、以下の5段階からなります。

	1.plug-in のソースを EPP に通して展開。
	2.展開された *.java ファイルを *.class にコンパイル。
	3.plug-in でテストプログラムを展開。
	4.展開されたテストプログラムを *.class にコンパイル。
	5.コンパイルされたテストプログラムを実行。

それぞれの段階ごとに適切なディレクトリ上で、
適切な CLASSPATH を指定して java か javac を実行する必要があります。

 tryplugin というコマンドは、これら一連の動作を、
適切に環境設定を行ないながら自動的に進めてくれます。
(現在のところ、 sh/bash script 版しかありません。)

 tryplugin の使い方を以下に述べます。


・まず、カレントディレクトリの下に、以下のファイルおよび
ディレクトリがあるものとします。

 Foo/PlugIn.java	// plug-in のソースファイル
 test/TestFoo.java	// テストプログラム。 #epp Foo が書いてあること。
 eppout/		// Foo/PlugIn.java の変換結果の出力先
 test/eppout/		// test/TestFoo.java の変換結果の出力先

 そして、次のようにすれば、tryplugin が5つの段階を自動的に進めます。

	% tryplugin Foo 

途中で何らかのエラーが起きたら、そこで停止します。
 それぞれの段階でのエラーへの対処法方を以下に説明します。


1. Foo/PlugIn.java を epp で展開する時のシンタックスエラー

 エラーメッセージに書かれている行番号を目安に、シンタックスエラーを修正します。


2. EPP で展開されたソースのコンパイル時のエラー

 エラーメッセージを見て、ソースファイルを修正します。
 SystemMixin plug-in を使っているせいで、わかりにくいエラーメッセージが
出る場合がありますが、 epp/doc/SystemMixin.txt 中の
「エラーメッセージ解説」の章を読めば
ある程度原因の推測がつくと思います。


3.plug-in による展開テスト中のエラー。

 Foo/PlugIn.java のバグで NullPointerException などが出た場合は、
デバッガを起動してエラーの正確な場所を見つけます。
それにはカレントディレクトリで以下のように入力します。

	% jdbplugin TestFoo.java

ディレクトリを移動する必要はありません。
 デバッガが起動したら、単に run と入力下さい。
これでエラーが起きる場所がわかるはずです。


4. plug-in で展開されたテストプログラムのソースのコンパイル中のエラー

 テストプログラムにバグがある場合は、それを修正します。
 そうでなさそうな場合は、再び Foo/PlugIn.java に print 文を入れるなどして
がんばってデバッグします。


5. plug-in を使って展開されたテストプログラムの実行中エラー

 4.の場合と同様、テストプログラムを修正するか、 Foo/PlugIn.java を
デバッグします。


・エラーが出ないが動作がおかしい場合は、 tree.print() を入れたり、
-tree オプションを使って、おかしい場所をつきとめます。

	% testplugin -tree -logfile tree.log Foo

将来的には、 plug-in デバッグのサポートをより強力にしていくつもりです。



インストール
------------
・デバッグが終ると、 plug-in を他の場所からも使えるように
インストールする必要があります。

 それには、カレントディレクトリの下の eppout/Foo/*.class を、
 CLASSPATH のパスが通っている場所に置きます。
例えば  ‾/lib/epp が CLASSPATH に入っている場合は、次のようにします。

	% mkdir ‾/lib/epp/Foo
	cp eppout/Foo/*.class ‾/lib/epp/Foo

これで、 plug-in が使えるようになります。



サンプル plug-in
----------------
以下の plug-in は比較的簡単な実装なので、
読むと参考になると思います。

 epp/src/level0 の下の、
	Math/PlugIn.java
	enum/PlugIn.java
	assert/PlugIn.java
	defmacro/PlugIn.java
	UserOp/PlugIn.java




EPP のソースのコンパイルの仕方
------------------------------
 EPP のソース(それ自体も EPP plug-in を使って書かれています)を
コンパイルするには、以下のようにします。

 1.準備
 ------
 まず、配布パッケージの epp/src ディレクトリの下に eppout を作ります。

	% cd epp/src
	% mkdir eppout

(注:EPP のコンパイルでは細かいファイルが大量に作られます。
Unix 系 OS ではファイルの生成・削除が遅いので注意して下さい。
Solaris の場合、普通のファイルシステムの下に eppout を作らずに、
/tmp の下に作ると、コンパイルが劇的に速くなります。
そうしたい場合は、次のようにします。

	% mkdir /tmp/tmpeppout
	% cd epp/src
	% ln -s /tmp/tmpeppout eppout
)

 2.ソースの変換
 --------------
 つぎに、 EPP のソースを EPP で普通の Java に変換します。
 この時、  -plug-in-package-prefix jp.go.etl.epp オプションの指定が必要です。
 また、変換後の EPP のパッケージを変更したい時は、
-plug-in RenamePackage オプションを使って下さい。

	% epp -plug-in-package-prefix jp.go.etl.epp -r level0
	Process files under level0
	Process files under level0/epp
	Translating level0/epp/Symbol.java
	Translating level0/epp/CompUnit.java
	...
	37 Java files were translated.
	%

 3.変換されたソースのコンパイル
 ------------------------------
 変換されたソースをコンパイルします。
このとき、 CLASSPATH の設定は必要ありません。
javac のデフォルトの heap size では足りないので、オプションで増やします。
JavaWorkshop2.0 の fastjavac を使う場合は、オプションの必要はありません。

	% cd eppout/level0
	% javac -J-mx32m */*.java
	%

 4.コンパイルされた EPP の実行。
 ------------------------------
 コンパイルされた EPP をその場で試してみることができます。
ここでも、 CLASSPATH の設定は必要ありません。

	% mkdir eppout
	% java epp.Epp epp/Tree.java
	Translating epp/Tree.java
	1 Java files were translated.
	%

 展開されたファイルの先頭を見れば、どのバージョンの EPP で
作られたものかがわかります。

	% head -1 eppout/epp/Tree.java
	/* Generated by EPP 1.1.0 (by 1.1.0 (by 1.1.0 (by lisp-epp1.1.0))) */
	%
 



Index