272 lines
6.9 KiB
ObjectPascal
272 lines
6.9 KiB
ObjectPascal
////////////////////////////////////////////////////////////////////////////
|
|
// PaxInvoke
|
|
// Site: http://www.paxcompiler.com
|
|
// Author: Alexander Baranovsky (paxscript@gmail.com)
|
|
// ========================================================================
|
|
// Copyright (c) Alexander Baranovsky, 2006-2014. All rights reserved.
|
|
// Code Version: 4.2
|
|
// ========================================================================
|
|
// Unit: PaxInvoke.pas
|
|
// Implements dynamically invoke of a global function or a method of object
|
|
// ========================================================================
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
{$I PaxCompiler.def}
|
|
{$O-}
|
|
unit PaxEval;
|
|
interface
|
|
uses {$I uses.def}
|
|
Classes,
|
|
SysUtils,
|
|
PAXCOMP_CONSTANTS,
|
|
PAXCOMP_TYPES,
|
|
PAXCOMP_SYS,
|
|
PAXCOMP_EVAL,
|
|
PAXCOMP_BASERUNNER,
|
|
PaxCompiler,
|
|
PaxRunner;
|
|
type
|
|
TPaxEval = class(TComponent)
|
|
private
|
|
fEval: TEval;
|
|
function GetResultAsString: String;
|
|
function GetResultAddress: Pointer;
|
|
function GetResultTypeName: String;
|
|
function GetResultTypeId: Integer;
|
|
function GetHasErrors: Boolean;
|
|
function GetValid: Boolean;
|
|
function GetErrorCount: Integer;
|
|
function GetErrorMessage(I: Integer): String;
|
|
|
|
function GetOnUnhandledException: TPaxErrNotifyEvent;
|
|
procedure SetOnUnhandledException(value: TPaxErrNotifyEvent);
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Reset;
|
|
procedure RegisterCompiler(ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner);
|
|
procedure AddNamespace(const NamespaceName: String);
|
|
procedure CompileExpression(const Source: String);
|
|
procedure CompileProgram(const Source: String);
|
|
procedure Run;
|
|
|
|
function GetEvalKernelPtr: Pointer;
|
|
property Valid: Boolean read GetValid;
|
|
property ResultAsString: String read GetResultAsString;
|
|
property ResultAddress: Pointer read GetResultAddress;
|
|
property ResultTypeName: String read GetResultTypeName;
|
|
property ResultTypeId: Integer read GetResultTypeId;
|
|
property HasErrors: Boolean read GetHasErrors;
|
|
property ErrorCount: Integer read GetErrorCount;
|
|
property ErrorMessage[I: Integer]: String read GetErrorMessage;
|
|
property OnUnhandledException: TPaxErrNotifyEvent read GetOnUnhandledException
|
|
write SetOnUnhandledException;
|
|
end;
|
|
|
|
function EvalExpression(const Source: String;
|
|
ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner): String; overload;
|
|
|
|
function EvalExpression(const Source: String; const Language: String = ''): String; overload;
|
|
|
|
|
|
procedure EvalProgram(const Source: String;
|
|
ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner);
|
|
|
|
implementation
|
|
|
|
uses
|
|
PaxBasicLanguage, PaxJavaScriptLanguage;
|
|
|
|
constructor TPaxEval.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
fEval := TEval.Create;
|
|
end;
|
|
|
|
destructor TPaxEval.Destroy;
|
|
begin
|
|
FreeAndNil(fEval);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TPaxEval.Reset;
|
|
begin
|
|
fEval.Reset;
|
|
end;
|
|
|
|
procedure TPaxEval.RegisterCompiler(ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner);
|
|
var
|
|
N: Integer;
|
|
begin
|
|
if AProgram.IsPaused then
|
|
N := AProgram.GetProgPtr.CurrN
|
|
else
|
|
N := -1;
|
|
fEval.Init(ACompiler.GetKernelPtr, AProgram.GetProgPtr, N);
|
|
end;
|
|
|
|
function TPaxEval.GetValid: Boolean;
|
|
begin
|
|
result := fEval.Valid;
|
|
end;
|
|
|
|
procedure TPaxEval.CompileExpression(const Source: String);
|
|
begin
|
|
fEval.CompileExpression(Source);
|
|
end;
|
|
|
|
procedure TPaxEval.CompileProgram(const Source: String);
|
|
begin
|
|
fEval.CompileProgram(Source);
|
|
end;
|
|
|
|
procedure TPaxEval.Run;
|
|
begin
|
|
fEval.Run;
|
|
end;
|
|
|
|
function TPaxEval.GetResultAsString: String;
|
|
begin
|
|
result := fEval.GetResultAsString;
|
|
end;
|
|
|
|
function TPaxEval.GetResultAddress: Pointer;
|
|
begin
|
|
result := fEval.GetResultAddress;
|
|
end;
|
|
|
|
function TPaxEval.GetResultTypeName: String;
|
|
begin
|
|
result := fEval.GetResultTypeName;
|
|
end;
|
|
|
|
function TPaxEval.GetResultTypeId: Integer;
|
|
begin
|
|
result := fEval.GetResultTypeId;
|
|
end;
|
|
|
|
function TPaxEval.GetHasErrors: Boolean;
|
|
begin
|
|
result := fEval.HasErrors;
|
|
end;
|
|
|
|
function TPaxEval.GetErrorCount: Integer;
|
|
begin
|
|
result := fEval.GetErrorCount;
|
|
end;
|
|
|
|
function TPaxEval.GetErrorMessage(I: Integer): String;
|
|
begin
|
|
result := fEval.GetErrorMessage(I);
|
|
end;
|
|
|
|
function TPaxEval.GetEvalKernelPtr: Pointer;
|
|
begin
|
|
result := fEval.EKernel;
|
|
end;
|
|
|
|
function TPaxEval.GetOnUnhandledException: TPaxErrNotifyEvent;
|
|
begin
|
|
result := TPaxErrNotifyEvent(TBaseRunner(fEval.EProg).OnUnhandledException);
|
|
end;
|
|
|
|
procedure TPaxEval.SetOnUnhandledException(value: TPaxErrNotifyEvent);
|
|
begin
|
|
TBaseRunner(fEval.EProg).OnUnhandledException := TErrNotifyEvent(value);
|
|
end;
|
|
|
|
procedure TPaxEval.AddNamespace(const NamespaceName: String);
|
|
begin
|
|
fEval.NamespaceList.Add(NamespaceName);
|
|
end;
|
|
|
|
function EvalExpression(const Source: String;
|
|
ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner): String;
|
|
var
|
|
Eval: TPaxEval;
|
|
begin
|
|
Eval := TPaxEval.Create(nil);
|
|
try
|
|
Eval.RegisterCompiler(ACompiler, AProgram);
|
|
Eval.CompileExpression(Source);
|
|
|
|
if Eval.HasErrors then
|
|
raise PaxCompilerException.Create(Eval.GetErrorMessage(0));
|
|
|
|
Eval.Run;
|
|
|
|
result := Eval.GetResultAsString;
|
|
finally
|
|
FreeAndNil(Eval);
|
|
end;
|
|
end;
|
|
|
|
function EvalExpression(const Source: String; const Language: String = ''): String;
|
|
var
|
|
Eval: TPaxEval;
|
|
ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner;
|
|
ALanguage: TPaxCompilerLanguage;
|
|
begin
|
|
ACompiler := TPaxCompiler.Create(nil);
|
|
AProgram := TPaxRunner.Create(nil);
|
|
if (Language = '') or StrEql(Language, 'Pascal') then
|
|
ALanguage := TPaxPascalLanguage.Create(nil)
|
|
else if StrEql(Language, 'Basic') then
|
|
ALanguage := TPaxBasicLanguage.Create(nil)
|
|
else if StrEql(Language, 'JavaScript') then
|
|
ALanguage := TPaxJavaScriptLanguage.Create(nil)
|
|
else
|
|
raise Exception.Create(Format(errUnknownLanguage, [Language]));
|
|
Eval := TPaxEval.Create(nil);
|
|
try
|
|
ACompiler.RegisterLanguage(ALanguage);
|
|
ACompiler.AddModule('1', ALanguage.LanguageName);
|
|
ACompiler.Compile(AProgram);
|
|
|
|
Eval.RegisterCompiler(ACompiler, AProgram);
|
|
Eval.CompileExpression(Source);
|
|
|
|
if Eval.HasErrors then
|
|
raise PaxCompilerException.Create(Eval.GetErrorMessage(0));
|
|
|
|
Eval.Run;
|
|
|
|
result := Eval.GetResultAsString;
|
|
finally
|
|
FreeAndNil(Eval);
|
|
FreeAndNil(ALanguage);
|
|
FreeAndNil(ACompiler);
|
|
FreeAndNil(AProgram);
|
|
end;
|
|
end;
|
|
|
|
procedure EvalProgram(const Source: String;
|
|
ACompiler: TPaxCompiler;
|
|
AProgram: TPaxRunner);
|
|
var
|
|
Eval: TPaxEval;
|
|
begin
|
|
Eval := TPaxEval.Create(nil);
|
|
try
|
|
Eval.RegisterCompiler(ACompiler, AProgram);
|
|
Eval.CompileProgram(Source);
|
|
|
|
if Eval.HasErrors then
|
|
raise PaxCompilerException.Create(Eval.GetErrorMessage(0));
|
|
|
|
Eval.Run;
|
|
finally
|
|
FreeAndNil(Eval);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
end.
|