2015-12-01:情報が古くなったので古い部分を修正しました。
なでしこ2でプラグインを作りたい人向けというニッチすぎるネタです。現在なでしこの時期バージョンなでしこ2が開発中です(えらい長いこと開発中です)が、構文の実装がある程度終わっているので、プラグインを開発することが出来ます。try catchの実装どうするかなーとか考えて進んでないですが、それはそれ。
なでしこ2はC#で組まれているので、プラグインもC#で組むことができます。
準備
~~まずは準備として、なでしこ2のソースをsvnでチェックアウトします。 URL~~
まずは準備として、なでしこ2のソースをGithubからクローンします。 ~~
$ git clone https://github.com/kujirahand/nadesiko2.git
~~SharpDevelopで開発中なので、SharpDevelopでソリューションを開きます。~~XamarinやVisualStudioで開発出来るので、そこらへんでソリューションを開きます。
cnakoをビルドする必要があるので、Nako2_CNakoソリューション(Nako2_CNako.sln)を開いて、cnako2プロジェクトをビルドしておきます。cnako2/bin/Debugフォルダにcnako2.exeが出来ます。これをなでしこ2のコード実行に使います。
プラグイン作成
プラグイン作成には今まで作成したプラグインがNakoPluginXXXというプロジェクト名であるので、それを参考にすれば良いわけですが、軽く説明しておきます。
プラグインのソースは下のようになります。
/*
* Created by SharpDevelop.
* User: shigepon
* Date: 2011/04/04
* Time: 9:42
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Libnako.JPNCompiler;
using NakoPlugin;
namespace NakoPluginSample{
public class NakoPluginSample : INakoPlugin {
string _description = "サンプルプラグイン";
double _version = 1.0;
//<del> プラグイン共通の部分 </del>
public double TargetNakoVersion { get { return 2.0; } }
public bool Used { get; set; }
public string Name { get { return this.GetType().FullName; } }
public double PluginVersion { get { return _version; } }
public string Description { get { return _description; } }
//<del> 関数の定義 </del>
public void DefineFunction(INakoPluginBank bank) {
bank.AddFunc({関数名}¸ {なでしこ形式の引数}¸ {戻り値の形式}¸ {実際の呼び出し先}¸{関数の説明}¸ {関数のよみかた});
}
// プラグインの初期化処理
public void PluginInit(INakoInterpreter runner) {
}
// プラグインの終了処理
public void PluginFin(INakoInterpreter runner) {
}
public Object {実際の処理}(INakoFuncCallInfo info){
...
}
}
}
実装時に大事なとこを説明します。
- まずプラグイン共通部分とPluginInit、PluginFinはコピペでもかまわないと思います。私もまだ初期処理、終了処理の必要なプラグインは作っていません。
- なでしこ上での関数呼び出し方法の定義はDefineFunctionで行います。bank.AddFuncメソッドで関数を追加できます。メソッド内の引数は下のように設定します。 ++ 関数名はなでしこで呼び出す名前になります。(例:文字検索)なでしこで使う助詞を使わないとか、他の命令の名称とかぶらないなどの制限があります。 ++ なでしこ形式の引数は「SでAを」のようになでしこで一般的に使う形式で指定します。引数を参照渡しにしたい場合は「{参照渡し}SでAを」のように指定します。助詞を複数指定したい場合は「SでAを|Sが」という形式で指定します。参照渡しを使う場合は実装が少々複雑になります。後日やり方を書こうと思います。 ++ 戻り値の形式はenum NakoVarTypeで指定します。(Void¸ Int¸ Double¸ String¸ Array) ++ 実際の呼び出し先はそのままメソッド名を指定します。(_hogeとか) ++ 関数の説明と関数のよみかたは分かりやすさの為に必要です。個人用なら適当でも良いと思います。(多分今後エディタとかそういうのにつかわれると思います)
- 実際の処理は必ずINakoFuncCallInfo型のインスタンスを引数に取ります。なでしこで渡された引数はこのインスタンスから取得します。取得方法は以下
long l = info.StackPopAsInt();
double d = info.StackPopAsDouble();
String s = info.StackPopAsString();
Object o = info.StackPop();//配列の場合はこれを使う
~~StackPopメソッドで得られる値はNakoVariable型なので、ちょっと扱いが難しくなります。実際の処理の実装方法はまた今度~~
簡単なプラグイン
例として「なでしこ」という文字があったら、「なでしこ2最高!」と変換するだけの命令として「アピール」という命令を作ってみます。仕様は次のようにしてみます。
- 引数は文字列として助詞は「を」を使う
- 引数は1つ
- プラグイン名はNakoPluginAppealとする
- 実装用のメソッドは_appealとする
Xamarinでの作成手順は次のようになります(多分VisualStudioでも似たようなもん)
- Nako2_Pluginsソリューション(Nako2_Plugins.slnを開く)で新しいプロジェクトとしてNakoPluginAppealという名前のC#のライブラリを作ります。(ソリューションで歯車アイコンクリック(又は右クリック))→追加→新しいプロジェクトを追加→ダイアログでC#をクリック→ライブラリを選択→名前をNakoPluginAppealとする→OK)
- 参照にNakoPluginを追加する(NakoPluginAppealの参照で歯車アイコンクリック(又は右クリック)→参照アセンブリの編集→ダイアログで.NETアセンブリタブを選択→NakoPlugin.dllをチェック、又は閲覧ボタンからNakoPlugin.dllを選ぶ→OK)
- NakoPluginAppeal.csを編集する
# NakoPluginAppeal.cs
using System;
using System.Text;
using Libnako.JPNCompiler;
using NakoPlugin;
namespace NakoPluginAppeal{
public class NakoPluginAppeal : INakoPlugin {
string _description = "サンプルプラグイン";
double _version = 1.0;
//<del> プラグイン共通の部分 </del>
public double TargetNakoVersion { get { return 2.0; } }
public bool Used { get; set; }
public string Name { get { return this.GetType().FullName; } }
public double PluginVersion { get { return _version; } }
public string Description { get { return _description; } }
//<del> 関数の定義 </del>
public void DefineFunction(INakoPluginBank bank) {
bank.AddFunc("アピール", "Aを", NakoVarType.String, _appeal, "なでしこ2をアピールする", "あぴーる");
}
// プラグインの初期化処理
public void PluginInit(INakoInterpreter runner) {
}
// プラグインの終了処理
public void PluginFin(INakoInterpreter runner) {
}
public string _appeal(INakoFuncCallInfo info){
string fr = info.StackPopAsString();
return fr.Replace("なでしこ", "なでしこ2最高!");
}
}
}
- ビルドする
- NakoPluginAppeal/bin/Debug/NakoPluginAppeal.dllをcnako2/bin/Debug/にコピー
実行するなでしこ2のコードは次のようになります。
A = 「なでしこ」をアピール
Aを表示
- これをcnako2/bin/Debug/test.nakoに保存
あとは下のコマンドを実行すれば結果が表示されます
$ cd cnako2/bin/Debug/
$ mono cnako2.exe test.nako
なでしこ最高!