Java からスクリプトのコンパイル

pnuts.compiler.CompilerPnutsImplを使うとOn-the-flyコンパイラを使った実行ができますが、実行を伴わずにコンパイルするには、pnuts.compiler.Compilerクラスを利用します。

pnuts.compiler.Compiler

public Compiler()
public Compiler(String className)
public Compiler(String className, boolean automatic)
public Compiler(String className, boolean automatic, boolean useDynamicProxy)

コンストラクタには、三つのパラメータを渡すことができます。classNameはコンパイル後コードのクラス名です。automatictrue(デフォルト)の場合は、コンパイルされたコードは自動的に読み込まれて実行されます。useDynamicProxytrue(デフォルト)の場合、メソッド呼び出しが最適化されます。ただし、コンパイルされたコードはpnuts.compilerパッケージに依存するようになります。

import pnuts.lang.*;

public void compile(PnutsFunction function, Context context)
public Pnuts compile(String expr, Context context)
public Pnuts compile(Pnuts pnuts, Context context)

pnuts.compiler.Compiler クラスは、関数、式、構文解析済みスクリプトをそれぞれコンパイルする三つの公開メソッドを提供しています。コンパイルに失敗するとjava.lang.ClassFormatError を送出します。

例:
import pnuts.lang.*;
import pnuts.compiler.*;

class CompileTest {
  public Object compileAndRun(InputStream in, Context context) throws ParseException {
    Compiler compiler = new Compiler();
    Pnuts pn = null;
    try {
      pn = Pnuts.parse(in);
      pn = compiler.compile(pn, context);
      return pn.run(context);
    } catch (ParseException pe){
      throw pe;
    } catch (ClassFormatError cfe){
      return pn.accept(new PnutsInterpreter(), context);
    }
  }
  ...
}
import pnuts.lang.*;

public Object compile(PnutsFunction function, ClassFileHandler handler)
public Object compile(String expr, ClassFileHandler handler)
public Object compile(Pnuts pnuts, ClassFileHandler handler)

また、このクラスには生成されたクラスファイルをどのように処理するかを定義するためのメソッドがあります。pnuts.compiler.ClassFileHandler はコンパイル結果を取り出すための抽象インタフェースです。

このインタフェースの実装クラスが2つ用意されています。pnuts.compiler.FileWriterHandlerpnuts.compiler.ZipWriterHandlerです。次の例は、式 1+2 をコンパイルして、"e:\tmp\test.class" に保存します。

例:
String expression = "1 + 2";
Compiler compiler = new Compiler("test");
try {
    compiler.compile(Pnuts.parse(expression), new FileWriterHandler(new File("e:\\tmp")));
} catch (ParseException pe){
} catch (ClassFormatError cfe){
    ...
}

コンパイル結果のクラスを読み込むには、2つの方法があります。

  1. 起動時のプロパティpnuts.compiled.script.prefixに生成されたクラスのパッケージ名を指定して load() を呼び出す
    load("test")
    
  2. 生成されたクラスのインスタンスに対して、Executable.run(Context) を呼び出す。
    test().run(getContext())
    

"コマンドラインからコンパイル"を参照。