FastScript

vložil Radek Červinka 5. května 2016 23:44

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ě.

Tagy: , ,

Komponenty

Komentáře

6.5.2016 10:10:24 #

Stanislav Hruška

Že tam skript je, to si musí všimnúť každý (ale asi až professional?). Ešte som neštudoval a teda nepoužil. Ale zaujíma ma jeho použitie s súvislosti zo zostavami. Snáď na to tam je.

Taká laická otázka (): aký je rozdiel, keď si daný kód napíšem priamo v delphi a ako skript? Moje otázky vyzerajú na založenie nových tém :)

Stanislav Hruška

6.5.2016 10:15:05 #

Marek

Jojo, FastScript je skvělá věc, já ho tedy používám hlavně na vytváření uživatelských funkcí Fast Reportu a už jich máme pěknou řádku. Celkově na Fast Report nedám dopustit. Některé naše sestavy, to je vlastně program v programu a nic dosud nebylo problémem ve Fast Reportu udělat. Jedině občas se vyskytne nějaká malá chybička při přechodu na novou verzi (např. ze 4 na 5), ale to není nic zásadního.

Marek

7.5.2016 10:53:39 #

radekc

Stano: kod napsaný v Delphi je přeložen během překladu, ve skriptu je interpretován. To znamená že první běží rychleji, je kontrolován při překladu, ale uživatel ho nemůže za běhu změnit. U skriptu je to naopak.

radekc

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců