base_scripter.pas
来自「Delphi脚本控件」· PAS 代码 · 共 2,368 行 · 第 1/5 页
PAS
2,368 行
////////////////////////////////////////////////////////////////////////////
// PAXScript Interpreter
// Author: Alexander Baranovsky (ab@cable.netlux.org)
// ========================================================================
// Copyright (c) Alexander Baranovsky, 2003-2005. All rights reserved.
// Code Version: 3.0
// ========================================================================
// Unit: BASE_SCRIPTER.pas
// ========================================================================
////////////////////////////////////////////////////////////////////////////
{$I PaxScript.def}
unit BASE_SCRIPTER;
interface
uses
{$IFDEF WIN32}
Windows,
{$ENDIF}
{$IFDEF VARIANTS}
Variants,
{$ENDIF}
SysUtils, Classes,
{$ifndef FP}
SyncObjs,
{$endif}
BASE_CONSTS,
BASE_SYNC,
BASE_SYS, BASE_SCANNER, BASE_PARSER, BASE_SYMBOL, BASE_CODE, BASE_CLASS,
BASE_EXTERN, BASE_EVENT, BASE_REGEXP, BASE_DLL, BASE_DFM;
type
TPAXBaseScripter = class;
TPAXModule = class(TStringList)
public
Name: String;
FileName: String;
LanguageName: String;
Namespaces: TPAXIds;
S1, P1, C1, S2, P2, C2: Integer;
IsSource: Boolean;
BuffStream: TStream;
Scripter: TPaxBaseScripter;
constructor Create(Scripter: TPaxBaseScripter);
destructor Destroy; override;
procedure AddNamespace(ID: Integer);
function GetTextPos(LineNumber, Position: Integer): Integer;
procedure _SaveToStream(S: TStream);
procedure _LoadFromStream(S: TStream);
end;
TPAXModules = class(TStringList)
private
Scripter: TPaxBaseScripter;
function GetModule(Index: Integer): TPAXModule;
function GetSourceCode: String;
public
constructor Create(Scripter: TPaxBaseScripter);
procedure Clear; reintroduce;
function IndexOf(const Name: String): Integer; override;
function Add(const Name, LanguageName: String): Integer; reintroduce;
procedure Delete(Index: Integer); reintroduce;
procedure _SaveToStream(S: TStream);
procedure _LoadFromStream(S: TStream);
destructor Destroy; override;
procedure Dump(const FileName: String);
property Items[Index: Integer]: TPAXModule read GetModule;
property SourceCode: String read GetSourceCode;
end;
TScripterEvent = procedure(Sender: TObject) of object;
TCompilerProgressEvent = procedure(Sender: TObject; ModuleNumber: Integer) of object;
TPrintEvent = procedure(Sender: TObject; const S: String) of object;
TReadEvent = procedure(Sender: TObject; var S: String) of object;
TVarEvent = procedure (Sender: TObject; ID: Integer) of object;
TVarEventEx = procedure (Sender: TObject; ID: Integer; var Mode: Integer) of object;
TCodeEvent = procedure(Sender: TObject;
N: Integer;
var Handled: Boolean) of object;
TUsedModuleEvent = procedure(Sender: TObject; const UsedModuleName, FileName: String;
var SourceCode: String) of object;
TLoadSourceCodeEvent = procedure(Sender: TObject; const UsedModuleName, FileName: String;
var SourceCode: String) of object;
TIncludeEvent = procedure(Sender: TObject; const IncludedFileName: String;
var SourceCode: String) of object;
TStreamEvent = procedure(Sender: TObject; Stream: TStream;
const ModuleName: String) of object;
TOnDefineEvent = procedure(Sender: TObject; const DirectiveName: String) of object;
TOnChangeStateEvent = procedure(Sender: TObject; OldState, NewState: TPaxScripterState) of object;
TOnInstanceEvent = procedure(Sender: TObject; Instance: TObject) of object;
TLoadDllEvent = procedure(Sender: TObject; const DllName, ProcName: String; var Address: Pointer) of object;
TVarArray = array of Variant;
TVirtualObjectMethodCallEvent = function(Sender: TObject; const ObjectName,
PropName: String; const Params: TVarArray): Variant of object;
TVirtualObjectPutPropertyEvent = procedure(Sender: TObject; const ObjectName,
PropName: String; const Params: TVarArray; const Value: Variant) of object;
TPAXBaseScripter = class
private
fOnHalt: TScripterEvent;
fOnShowError: TScripterEvent;
fOnCompilerProgress: TCompilerProgressEvent;
fOnRunning: TCodeEvent;
fOnPrint: TPrintEvent;
fOnRead: TReadEvent;
{$IFDEF UNDECLARED_EX}
fOnUndeclaredIdentifier: TVarEventEx;
{$ELSE}
fOnUndeclaredIdentifier: TVarEvent;
{$ENDIF}
fOnChangedVariable: TVarEvent;
fOnReadExtraData, fOnWriteExtraData: TStreamEvent;
fOnUsedModule: TUsedModuleEvent;
fOnInclude: TIncludeEvent;
fOnLoadSourceCode: TLoadSourceCodeEvent;
fOnDefine: TOnDefineEvent;
fOnChangeState: TOnChangeStateEvent;
fOnDelphiInstanceCreate: TOnInstanceEvent;
fOnDelphiInstanceDestroy: TOnInstanceEvent;
fOnLoadDll: TLoadDllEvent;
fOnVirtualObjectMethodCall: TVirtualObjectMethodCallEvent;
fOnVirtualObjectPutProperty: TVirtualObjectPutPropertyEvent;
SignDefs: Boolean;
fOverrideHandlerMode: Integer;
{$IFDEF ONRUNNING}
// Event to replace OnRunning event. Event will be executed when
// fOnRunningUpdateActive is enabled and the event is assigned.
fOnRunningUpdate: TScripterEvent;
// Flag used to fire the OnRunningUpdate event. This allows scripter
// to run quickly when flag is disabled (False). Flag can be
// enabled/disabled during script run-time.
fOnRunningUpdateActive: Boolean;
// Event fires when executing a function or property and UserData is non-zero.
// Used for multi-thread applications.
fOnRunningSync: TScripterEvent;
{$ENDIF}
procedure SetState(Value: TPAXScripterState);
procedure CopyLevelStack(Parser: TPAXParser);
public
EvalCount: Integer;
Owner: TObject;
Modules: TPAXModules;
SymbolTable: TPAXSymbolTable;
Code: TPAXCode;
ClassList: TPAXClassList;
EventHandlerList: TPAXEventHandlerList;
MethodBody: TPAXMethodBody;
VariantStack: TPaxVariantStack;
NegVarList: TPaxVarList;
ScriptObjectList: TPAXScriptObjectList;
ActiveXObjectList: TPaxObjectList;
CompileTimeHeap: TPAXCompileTimeHeap;
fState: TPAXScripterState;
Error: Variant;
ErrorInstance: TPAXError;
RegisteredFieldList: TPAXFieldList;
ParserList: TPAXParserList;
ExtraCodeList: TPAXCodeList;
fTotalLineCount: Integer;
ParamList: TPAXParamList;
ArrayClassRec: TPAXClassRec;
LastResultID: Integer;
fLastResult: Variant;
DoNotDestroyList: TPAXIds;
TempObjectList: TPAXAssocList;
ForbiddenPublishedProperties: TList;
ForbiddenPublishedPropertiesEx: TStringList;
PrototypeNameIndex: Integer;
ConstructorNameIndex: Integer;
fStackSize: Integer;
fLongStrLiterals: Boolean;
CurrModule: Integer;
OwnerEventHandlerMethod: TMethod;
AllowedEvents: Boolean;
Visited: TList;
ExtraModuleList: TStringList;
DefList: TStringList;
RunList: TPaxStack;
fSearchPathes: TStringList;
DefaultParameterList: TDefaultParameterList;
UnknownTypes: TPaxIDRecList;
CallRecList: TPaxCallRecList;
TypeAliasList: TPaxAssociativeList;
NameList: TPAXNameList;
LocalDefinitions: TPAXDefinitionList;
TempVariant: Variant;
CancelMessage: String;
_ObjCount: Int64;
LastDefinitionListCount: Integer;
IgnoreBreakpoints: Boolean;
constructor Create(Owner: TObject);
destructor Destroy; override;
procedure AddDefs;
procedure AddLocalDefs;
function AddModule(const ModuleName, LanguageName: String): Integer;
procedure AddCode(const ModuleName, Code: String);
procedure AddCodeFromFile(const ModuleName, FileName: String);
function CompileModule(const Name: String; Parser: TPAXParser;
SyntaxCheckOnly: Boolean = false): Boolean;
procedure CompileExtraCode;
procedure Link(reallocate: boolean);
procedure Run(RunMode: Integer = _rmRun; DestLine: Integer = 0);
procedure ResetCompileStage;
procedure ResetScripterEx;
procedure InitRunStage;
procedure ResetRunStage;
procedure DiscardError;
function IsError: boolean;
function AddBreakpoint(const ModuleName: String; SourceLineNumber: Integer;
const Condition: String; PassCount: Integer): Boolean;
function RemoveBreakpoint(const ModuleName: String; SourceLineNumber: Integer;
const Condition: String; PassCount: Integer): Boolean;
procedure RemoveAllBreakpoints;
function SourceLineToPCodeLine(const ModuleName: String; SourceLineNumber: Integer): Integer;
procedure CreateErrorObject(const Message: String; PosNumber: Integer);
procedure ShowError;
function CallMethod(SubID: Integer;
const This: Variant;
const P: array of const;
IsEventHandler: Boolean = false): Variant;
function CallMethodEx(SubID: Integer;
const This: Variant;
const P: array of const;
const StrTypes: array of String;
IsEventHandler: Boolean = false): Variant;
function AssignedObject(SO: TPAXScriptObject): Boolean;
procedure DisconnectObjects;
procedure Dump;
function GetProperty(const ScriptObject: Variant; PropertyName: String): Variant;
function Eval(const SourceCode: String; Parser: TPAXParser): Variant;
procedure EvalStatementList(const SourceCode: String; Parser: TPAXParser);
function GetName(NameIndex: Integer): String;
procedure SaveToStream(S: TStream);
procedure LoadFromStream(S: TStream);
procedure SaveCompiledModuleToStream(M: TPaxModule; S: TStream);
procedure LoadCompiledModuleFromStream(M: TPaxModule; S: TStream);
property State: TPAXScripterState read fState write SetState;
property TotalLineCount: Integer read fTotalLineCount write fTotalLineCount;
procedure AddExtraModule(const ModuleName, SourceCode: String;
SyntaxCheckOnly: Boolean; const PaxLanguage: String);
procedure RunEx(ExtendedRun: Boolean);
function FindFullName(const FileName: String): String;
function IsCompiledScript(const FileName: String): Boolean;
procedure CreateRunList;
procedure CheckForUndeclared;
procedure CheckCalls;
function GetTypeID(ID: Integer): Integer;
function MatchAssignment(T1, T2: Integer): Boolean;
function MatchAssignmentStrict(T1, T2: Integer): Boolean;
function OpResultType(T1, T2: Integer): Integer;
function MatchTypes(T1, T2: Integer): Integer;
function strIncompatibleTypes(T1, T2: Integer): String;
function ConvertDelphiForm1(const DfmFileName, UnitFileName, PaxLanguage: String): String;
function ConvertDelphiForm2(const DfmFileName: String; UsedUnits: TStringList; const PaxLanguage: String): String;
procedure AddDelphiForm(const DfmFileName, UnitFileName, PaxLanguage: String);
function HasForbiddenPublishedProperty(C: TClass; const PropName: String): Boolean;
property OverrideHandlerMode: Integer read fOverrideHandlerMode write fOverrideHandlerMode;
property OnHalt: TScripterEvent read fOnHalt write fOnHalt;
property OnShowError: TScripterEvent read fOnShowError write fOnShowError;
property OnCompilerProgress: TCompilerProgressEvent read fOnCompilerProgress write fOnCompilerProgress;
property OnPrint: TPrintEvent read fOnPrint write fOnPrint;
property OnRead: TReadEvent read fOnRead write fOnRead;
{$IFDEF UNDECLARED_EX}
property OnUndeclaredIdentifier: TVarEventEx read fOnUndeclaredIdentifier write fOnUndeclaredIdentifier;
{$ELSE}
property OnUndeclaredIdentifier: TVarEvent read fOnUndeclaredIdentifier write fOnUndeclaredIdentifier;
{$ENDIF}
property OnChangedVariable: TVarEvent
read fOnChangedVariable write fOnChangedVariable;
property OnRunning: TCodeEvent read fOnRunning write fOnRunning;
{$IFDEF ONRUNNING}
// See variable definitions above for details.
property OnRunningUpdate: TScripterEvent read fOnRunningUpdate write fOnRunningUpdate;
property OnRunningUpdateActive: Boolean read fOnRunningUpdateActive write fOnRunningUpdateActive;
property OnRunningSync: TScripterEvent read fOnRunningSync write fOnRunningSync;
{$ENDIF}
property OnReadExtraData: TStreamEvent read fOnReadExtraData write fOnReadExtraData;
property OnWriteExtraData: TStreamEvent read fOnWriteExtraData write fOnWriteExtraData;
property OnUsedModule: TUsedModuleEvent read fOnUsedModule write fOnUsedModule;
property OnInclude: TIncludeEvent read fOnInclude write fOnInclude;
property OnLoadSourceCode: TLoadSourceCodeEvent read fOnLoadSourceCode write fOnLoadSourceCode;
property OnDefine: TOnDefineEvent read fOnDefine write fOnDefine;
property OnChangeState: TOnChangeStateEvent read fOnChangeState write fOnChangeState;
property OnDelphiInstanceCreate: TOnInstanceEvent read fOnDelphiInstanceCreate write fOnDelphiInstanceCreate;
property OnDelphiInstanceDestroy: TOnInstanceEvent read fOnDelphiInstanceDestroy write fOnDelphiInstanceDestroy;
property OnLoadDll: TLoadDllEvent read fOnLoadDll write fOnLoadDll;
property OnVirtualObjectMethodCall: TVirtualObjectMethodCallEvent read fOnVirtualObjectMethodCall write fOnVirtualObjectMethodCall;
property OnVirtualObjectPutProperty: TVirtualObjectPutPropertyEvent read fOnVirtualObjectPutProperty write fOnVirtualObjectPutProperty;
end;
var
__Self: TObject;
__Scripter: TObject;
ScripterList: TList;
DllList: TPaxDllList;
CurrScripter: TPAXBaseScripter;
function _Eval(const SourceCode: String;
Scripter: TPAXBaseScripter;
Parser: TPAXParser): Variant;
implementation
uses
PASCAL_PARSER, PAX_JAVASCRIPT;
constructor TPAXModule.Create(Scripter: TPaxBaseScripter);
begin
inherited Create;
Self.Scripter := Scripter;
Namespaces := TPAXIds.Create(false);
IsSource := true;
BuffStream := TMemoryStream.Create;
end;
destructor TPAXModule.Destroy;
begin
Namespaces.Free;
BuffStream.Free;
inherited;
end;
procedure TPAXModule.AddNamespace(ID: Integer);
begin
if Namespaces.IndexOf(ID) = -1 then
Namespaces.Add(ID);
end;
function TPAXModule.GetTextPos(LineNumber, Position: Integer): Integer;
var
S: String;
P, LineCount: Integer;
begin
result := 0;
P := 1;
LineCount := 1;
S := Text + #255;
while S[P] <> #255 do
begin
if S[P] in [#10,#13] then
begin
Inc(LineCount);
if S[P] = #13 then
Inc(P);
end;
if LineCount = LineNumber then
begin
while S[P] in [#10,#13] do
Inc(P);
result := P + Position;
Exit;
end;
Inc(P);
end;
end;
procedure TPAXModule._SaveToStream(S: TStream);
begin
SaveString(Name, S);
SaveString(FileName, S);
SaveString(LanguageName, S);
SaveInteger(Count, S);
Namespaces.SaveToStream(S);
SaveInteger(S1, S);
SaveInteger(S2, S);
SaveInteger(P1, S);
SaveInteger(P2, S);
SaveInteger(C1, S);
SaveInteger(C2, S);
end;
procedure TPAXModule._LoadFromStream(S: TStream);
var
I, K: Integer;
St: String;
begin
Name := LoadString(S);
FileName := LoadString(S);
LanguageName := LoadString(S);
K := LoadInteger(S);
Namespaces.LoadFromStream(S);
S1 := LoadInteger(S);
S2 := LoadInteger(S);
P1 := LoadInteger(S);
P2 := LoadInteger(S);
C1 := LoadInteger(S);
C2 := LoadInteger(S);
if Assigned(Scripter.fOnLoadSourceCode) then
begin
Scripter.fOnLoadSourceCode(Scripter.Owner, Name, FileName, St);
Text := St;
end
else
begin
if FileExists(FileName) then
LoadFromFile(FileName)
else
for I:=0 to K - 1 do
Add('##' + IntToStr(I) + '##');
end;
IsSource := false;
end;
constructor TPAXModules.Create(Scripter: TPaxBaseScripter);
begin
inherited Create;
Self.Scripter := Scripter;
end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?