コンポーネント利用

FunnyScript を自作アプリケーションのマクロ言語として組み込む方法について書きます。

Env クラスを使う

FunnyScript.Script モジュール内に次のような Env クラスが定義されています。 この Env クラスを使うことで簡単に FunnyScript のスクリプトを動かすことが出来ます。

module FunnyScript.Script

type Env private (data : AST.Env) =
  static member Default : Env = ...
  member this.LoadAssembly asm =...
  member this.LoadModule (name, m : list<string * Expr>) = ...
  member this.LoadModule (name, moduleScript) = ...
  member this.Add (name, obj : obj) = ...
  member this.AddFunc (name, f : Func<'a>) = ...
  member this.AddFunc (name, f : Func<'a, 'b>) = ...
  member this.AddFunc (name, f : Func<'a, 'b, 'c>) = ...
  member this.AddAction (name, f : Action) = ...
  member this.AddAction (name, f : Action<'a>) = ...
  member this.AddAction (name, f : Action<'a, 'b>) = ...
  member this.Eval expr = ...
  member this.Run (streamName, source, [<ParamArray>] args : (string * obj)[]) = ...
  member this.RunFile (path, [<ParamArray>] args) = ...

Env クラスを C# から利用するサンプルコードを示します。 まず下記のように Env オブジェクトを用意しておきます。

FunnyScript.Script.Env env =
   FunnyScript.Script.Env.Default
   .LoadAssembly(typeof(...).Assembly) // スクリプトから利用する
   .LoadAssembly(typeof(...).Assembly) // アセンブリをロード
   .Add("hoge", hoge); // スクリプトから参照するオブジェクトを追加

次に、env の Run メソッドでスクリプトを実行します。

string script = "...";
var result = env.Run("piyopiyo.fs", script);
var text = FunnyScript.Script.getResultString(result);

LoadAssembly でアセンブリをロードしておくと、そのアセンブリに定義されているクラスにスクリプトからアクセスできるようになります。

また、Add でオブジェクトを追加しておくと、そのオブジェクトにスクリプトからアクセスできるようになります。

WPF アプリケーションに FunnyScript を組み込む

  1. WPFアプリケーションプロジェクトの参照設定に FunnyScript.dll, FunnyScript.Gui.exe 等を加える。
  2. FunnyScript のコードエディタとして FunnyScript.Gui.FunnyEditor コントロールをアプリケーションに組み込む。
  3. FunnyScript から操作したいオブジェクトや、FunnyScript から呼び出したい関数などを設定する(詳細は後述)。
  4. FunnyEditorRun() メソッドでスクリプトを実行

上記3番目の設定方法について説明します。 まず、 FunnyEditor コントロールのシグネチャを下記に示します。

namespace FunnyScript.Gui
{
  public class FunnyEditor : UserControl
  {
    public static readonly DependencyProperty SourceFilePathProperty;
    public string SourceFilePath { get; set; }
    public void Load( string path );
    public void Save( string path );
    public void LoadAssembly( Assembly asm );
    public void SetVariable( string name, object obj );
    public void SetFunc<T, TResult>(string name, Func<T, TResult> f);
    public void SetFunc<T1, T2, TResult>(string name, Func<T1, T2, TResult> f);
    public void SetAction<T>(string name, Action<T> f);
    public void SetAction<T1, T2>(string name, Action<T1, T2> f);
    public void Parse();
    public Result<object, Script.Error> Run( params Tuple<string, object>[] args );
  }
}

LoadAssembly() メソッドにより、スクリプトから参照したいアセンブリを追加します。例えばスクリプトから操作したいアプリケーション固有のクラスなどが定義されたアセンブリをロードすることになるでしょう。

SetVariable() メソッドにより、スクリプトから操作したい変数(オブジェクト)を設定できます。アプリケーション固有のオブジェクトを設定すれば、それをスクリプトで操作することが可能になります。

SetFunc()SetAction() メソッドにより、スクリプトから利用できる関数(API)を設定できます。