Delphi.cz

Český portál Delphi

FastScript

Pokud jste šťastným uživatelem FastReportu, možná ani nevíte, že FastReport obsahuje i FastScript a že se dá použít nezávisle bez generování reportů. Co je to FastScript? Je to knihovna pro provádění skriptů v různých jazycích (Pascal, JS, C++, VB). Skripty mohou být celé programy, ale i obyčejný výraz. FastScript vám dává do ruky opravdu mocný nástroj.

Malý příklad, jednak vyhodnocení výrazu, druhak spustění funkce i s ShowMessage.

program Project8;

{$APPTYPE CONSOLE}

uses
  SysUtils, Variants, fs_ipascal, fs_iinterpreter;

type
  TScriptTest = class
  protected
    FScript:TfsScript;
  public
    function ScriptCallMethod(Instance: TObject; ClassType: TClass; const MethodName: String;
      Caller: TfsMethodHelper): Variant;
   function TestEvaluate(const sLine: string): Currency;
   procedure TestExec;
   procedure AddConst(const s:string; crVal:Currency);
   constructor Create;
   destructor Destroy; override;


  end;

procedure TScriptTest.AddConst(const s: string; crVal: Currency);
begin
  FScript.AddConst(s, 'Extended', crVal);
end;

constructor TScriptTest.Create;
begin
  fScript := TfsScript.Create(nil);
  fScript.SyntaxType := 'PascalScript';
end;

destructor TScriptTest.Destroy;
begin
  FreeAndNiL(FScript);
  inherited;
end;

function TScriptTest.ScriptCallMethod(Instance: TObject; ClassType: TClass; const MethodName: String;
  Caller: TfsMethodHelper): Variant;
begin
  if MethodName = 'SQR' then
    Result := Sqr(Caller.Params[0])
  else
    Result := NULL;
end;

function TScriptTest.TestEvaluate(const sLine: string): Currency;

var
  v: Variant;
begin
  FScript.Clear;
  fScript.Parent := fsGlobalUnit; // !!
  fScript.AddMethod('function Sqr(e: Extended): Extended', ScriptCallMethod );
  AddConst('ourwidth', 34);
  AddConst('ourheight', 100);
  v := FScript.Evaluate(sLine);
  if VarIsNull(v) then
    Result := 0
  else
    Result := v;
end;

procedure TScriptTest.TestExec;
var
  v: Variant;
begin
  FScript.Clear;
  fScript.Parent := fsGlobalUnit; // !!
  AddConst('ourwidth', 34);
  FScript.Lines.Text := ' function TestCount(i:Integer):Double; ' +
     'begin '+
     ' Result :=  i * ourWidth;'+
     ' ShowMessage(IntToStr(i))'+
     ' end;' +
     ' begin end. ';
  if not FScript.Compile then
  begin
    writeln(FScript.ErrorMsg);
    Exit;
  end;
  v := FScript.CallFunction('TestCount', VarArrayOf([19]));
  writeln(FloatToStr(v));
end;

var
  oTest: TScriptTest;
begin
  try
    oTest :=  TScriptTest.Create;
    try
      writeln(oTest.TestEvaluate('ourheight *10 + sqr(ourwidth)'));
      oTest.TestExec;
    finally
      otest.Free;
    end;
    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Metoda TestEvaluate vyhodnotí výraz, v ukázce tam předávám nějaké konstanty a definuji vlastní funkci pro výpočet - což je celkem silný nástroj. Implementace této funkce je v ScriptCallMethod.

Metoda TestExec volá funkci v programu, předá si parametr, něco spočítá a navíc zavolá ShowMessage přímo ze skriptu. Nemusí zůstat u Showmessage, můžete dělat třeba formuláře - ale v mém případě šlo spíše o výpočty uživatelem editovatelných vzorců s přepočítanými konstantami a uživatelskými funkcemi. A to klaplo parádně.

Datum: 2016-05-05 22:44:00 Tagy: FastReport, Object Pascal, praxe

Komponenty