かなり昔にInnerfuse Pascal Script 2と言うやつを使った事があったのでその流れをくむRemObjects社のPascal Scriptと、Delphi XE2からバンドルされているFastReport社のFastScriptをとりあえず試してみました。
前は単純なことしかできなかったけど、最近ではアプリで作ったクラスへのアクセスはもちろん、TFormとかにもアクセス出来るみたいです。とりあえず作ったクラスにアクセスして集計とかやるのがおもな目的になるのでTFormへのアクセスとかそこら辺のことはまったくやってません。
Pascal Script
Innerfuse Pascal Script と言われていたやつで、作者が RemObjects 社を作ってからは Pascal Script と言う名称になってます。無料です。
自前のクラスへのアクセスはちょっと面倒な感じがします。たぶん使うクラスを分離して付属のツール(PSUnitImporter.exe)でそのクラスの
※ここには載せてませんが、TestUnit.pas をインポーターにかけたら uPSI_TestUnit.pas が出来ます。リストの下にサンプルソースがあります。
FastScript かなり使いやすくて気に入ったんですが残念ながらトライアルです。実行するたびにダイアログボックスが開きます。また他の言語も使えます。
Pascal Script より 3-5 倍は早いです。またクラスへのアクセスは RTTI を使うことにより、少ない記述で済みます。
fsScript.AddClass(TData, 'TData');
だけで、クラスのプロパティーにアクセス出来ます。もちろん登録してやればメソッドにもアクセス可能です。
unit Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.DateUtils, fs_iinterpreter, fs_ipascal, uPSComponent, TestUnit, uPSI_TestUnit, uPSComponent_Default; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; Button2: TButton; ListBox: TListBox; fsScript: TfsScript; fsPascal1: TfsPascal; PSScript: TPSScript; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure PSScriptCompile(Sender: TPSScript); public constructor Create (AOwner: TComponent); OVERRIDE; function OutputFS (Instance: TObject; ClassType: TClass; const MethodName: string; var Params: variant) : variant; procedure OutputPS (s: string); function GetDataFS (Instance: TObject; ClassType: TClass; const MethodName: string; var Params: variant) : variant; function GetDataPS : TData; private fData: TData; end; var Form1: TForm1; implementation {$R *.dfm} constructor TForm1.Create(AOwner: TComponent); var p: TPSPlugin; begin inherited Create(AOwner); fData := TData.Create; p := TPSImport_TestUnit.Create(Self); TPSPluginItem(PSScript.Plugins.Add).Plugin := p; end; procedure TForm1.Button1Click(Sender: TObject); var d: TData; begin fsScript.Clear; fsScript.Lines.Text := Memo1.Text; fsScript.Parent := fsGlobalUnit; fsScript.AddMethod('procedure Log(s: String)', OutputFS); fsScript.AddMethod('function GetData : TData', GetDataFS); fsScript.AddClass(TData, 'TData'); if fsScript.Compile then begin ListBox.Items.Add('=== FastScript ==='); fsScript.Execute; ListBox.Items.Add(IntToStr(fData.Value)); end else begin OutputPS(fsScript.ErrorMsg); OutputPS(fsScript.ErrorPos); end; end; procedure TForm1.Button2Click(Sender: TObject); var a: integer; d: TData; begin PSScript.Script.Text := Memo1.Text; if PSScript.Compile then begin ListBox.Items.Add('=== Pascal Script ==='); PSScript.Execute; ListBox.Items.Add(IntToStr(fData.Value)); end else begin for a := 0 to PSScript.CompilerMessageCount - 1 do ListBox.Items.Add(PSScript.CompilerMessages[a].MessageToString); end; end; procedure TForm1.PSScriptCompile(Sender: TPSScript); begin PSScript.AddMethod(Self, @TForm1.OutputPS, 'procedure Log(s: string);'); PSScript.AddMethod(Self, @TForm1.GetDataPS, 'function GetData : TData'); end; function TForm1.OutputFS(Instance: TObject; ClassType: TClass; const MethodName: string; var Params: variant) : variant; begin OutputPS(Params[0]); end; procedure TForm1.OutputPS(s: string); begin ListBox.Items.Add(s + Format(' (%.1f)', [GetTickCount / 1000])); end; function TForm1.GetDataFS(Instance: TObject; ClassType: TClass; const MethodName: string; var Params: variant) : variant; begin GetDataFS := NativeInt(fData); end; function TForm1.GetDataPS : TData; begin GetDataPS := fData; end; end.サンプルプロジェクト: ダウンロード
※コンパイルには FastScript と Pascal Script が必要。実行ファイル付。
p.s.
FastScript の構文をハイライトで表示してくれるメモコントロールの TfsSyntaxMemo はまったく日本語に対応してませんでした。まぁ別にかまわんけど...
0 件のコメント:
コメントを投稿