mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-04 18:03:51 +02:00
114 lines
2.2 KiB
ObjectPascal
114 lines
2.2 KiB
ObjectPascal
unit Main;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, ExtCtrls, StdCtrls, SysUtils, FileUtil, Forms, Controls, Graphics,
|
|
Dialogs, TAFuncSeries, TAGraph;
|
|
|
|
type
|
|
TForm1 = class(TForm)
|
|
btnRefresh: TButton;
|
|
Chart1: TChart;
|
|
Chart1FuncSeries1: TFuncSeries;
|
|
edFormula: TEdit;
|
|
Panel1: TPanel;
|
|
procedure btnRefreshClick(Sender: TObject);
|
|
procedure Chart1FuncSeries1Calculate(const AX: Double; out AY: Double);
|
|
end;
|
|
|
|
var
|
|
Form1: TForm1;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
uses
|
|
uPSCompiler, uPSRuntime, uPSUtils;
|
|
|
|
type
|
|
TUserFunction = function (AX: Double): Double of object;
|
|
|
|
var
|
|
exec: TPSExec;
|
|
userFunc: TUserFunction;
|
|
|
|
function ScriptOnExportCheck(
|
|
ASender: TPSPascalCompiler; AProc: TPSInternalProcedure;
|
|
const AProcDecl: string): Boolean;
|
|
begin
|
|
if AProc.Name = 'FN' then
|
|
if not ExportCheck(ASender, AProc, [btDouble, btDouble], [pmIn]) then begin
|
|
ASender.MakeError('', ecTypeMismatch, '');
|
|
exit(false);
|
|
end;
|
|
Result := true;
|
|
end;
|
|
|
|
function ScriptOnUses(ASender: TPSPascalCompiler; const AName: string): Boolean;
|
|
begin
|
|
Result := AName = 'SYSTEM';
|
|
end;
|
|
|
|
procedure CompileScript(const AScript: string);
|
|
var
|
|
data: string;
|
|
begin
|
|
FreeAndNil(exec);
|
|
|
|
with TPSPascalCompiler.Create do
|
|
try
|
|
OnUses := @ScriptOnUses;
|
|
OnExportCheck := @ScriptOnExportCheck;
|
|
AllowNoBegin := true;
|
|
AllowNoEnd := true;
|
|
if not Compile(AScript) then exit;
|
|
GetOutput(data);
|
|
finally
|
|
Free;
|
|
end;
|
|
|
|
exec := TPSExec.Create;
|
|
|
|
if not exec.LoadData(data) then begin
|
|
FreeAndNil(exec);
|
|
exit;
|
|
end;
|
|
|
|
userFunc := TUserFunction(exec.GetProcAsMethodN('FN'));
|
|
if userFunc = nil then
|
|
FreeAndNil(exec);
|
|
end;
|
|
|
|
{ TForm1 }
|
|
|
|
procedure TForm1.btnRefreshClick(Sender: TObject);
|
|
begin
|
|
CompileScript(
|
|
'function fn(x: Double): Double; begin Result := ' + edFormula.Text +
|
|
'; end;');
|
|
with edFormula do
|
|
if exec = nil then
|
|
Color := clRed
|
|
else
|
|
Color := clDefault;
|
|
Chart1FuncSeries1.Active := true;
|
|
Chart1.Invalidate;
|
|
end;
|
|
|
|
procedure TForm1.Chart1FuncSeries1Calculate(const AX: Double; out AY: Double);
|
|
begin
|
|
if exec = nil then
|
|
AY := AX
|
|
else
|
|
AY := userFunc(AX);
|
|
end;
|
|
|
|
finalization
|
|
FreeAndNil(exec);
|
|
|
|
end.
|
|
|