xtool/contrib/CoreCipher/Source/OpCode.pas

1815 lines
46 KiB
ObjectPascal

{ * opCode * }
{ ****************************************************************************** }
{ * https://zpascal.net * }
{ * https://github.com/PassByYou888/zAI * }
{ * https://github.com/PassByYou888/ZServer4D * }
{ * https://github.com/PassByYou888/PascalString * }
{ * https://github.com/PassByYou888/zRasterization * }
{ * https://github.com/PassByYou888/CoreCipher * }
{ * https://github.com/PassByYou888/zSound * }
{ * https://github.com/PassByYou888/zChinese * }
{ * https://github.com/PassByYou888/zExpression * }
{ * https://github.com/PassByYou888/zGameWare * }
{ * https://github.com/PassByYou888/zAnalysis * }
{ * https://github.com/PassByYou888/FFMPEG-Header * }
{ * https://github.com/PassByYou888/zTranslate * }
{ * https://github.com/PassByYou888/InfiniteIoT * }
{ * https://github.com/PassByYou888/FastMD5 * }
{ ****************************************************************************** }
unit OpCode;
{$INCLUDE zDefine.inc}
interface
uses SysUtils, Variants, Math, CoreClasses, PascalStrings, DoStatusIO, ListEngine, UnicodeMixedLib, DataFrameEngine;
type
TOpValueType = (
ovtBool, ovtInt, ovtInt64, ovtUInt64, ovtWord, ovtByte, ovtSmallInt, ovtShortInt, ovtUInt,
ovtSingle, ovtDouble, ovtCurrency,
ovtString, ovtProc,
ovtUnknow);
TOpCode = class;
TOpCustomRunTime = class;
TOpParam = array of Variant;
TOnOpCall = function(var Param: TOpParam): Variant;
TOnOpMethod = function(var Param: TOpParam): Variant of object;
TOnObjectOpCall = function(OpRunTime: TOpCustomRunTime; var Param: TOpParam): Variant;
TOnObjectOpMethod = function(OpRunTime: TOpCustomRunTime; var Param: TOpParam): Variant of object;
{$IFDEF FPC}
TOnOpProc = function(var Param: TOpParam): Variant is nested;
TOnObjectOpProc = function(OpRunTime: TOpCustomRunTime; var Param: TOpParam): Variant is nested;
{$ELSE FPC}
TOnOpProc = reference to function(var Param: TOpParam): Variant;
TOnObjectOpProc = reference to function(OpRunTime: TOpCustomRunTime; var Param: TOpParam): Variant;
{$ENDIF FPC}
POpRTData = ^TOpRTData;
TOpRTData = record
Param: TOpParam;
Name, Description, Category: SystemString;
OnOpCall: TOnOpCall;
OnOpMethod: TOnOpMethod;
OnObjectOpCall: TOnObjectOpCall;
OnObjectOpMethod: TOnObjectOpMethod;
OnOpProc: TOnOpProc;
OnObjectOpProc: TOnObjectOpProc;
procedure Init;
end;
TOpCustomRunTime = class(TCoreClassObject)
protected
procedure FreeNotifyProc(p: Pointer);
function DoInt(var Param: TOpParam): Variant;
function DoFrac(var Param: TOpParam): Variant;
function DoExp(var Param: TOpParam): Variant;
function DoCos(var Param: TOpParam): Variant;
function DoSin(var Param: TOpParam): Variant;
function DoLn(var Param: TOpParam): Variant;
function DoArcTan(var Param: TOpParam): Variant;
function DoSqrt(var Param: TOpParam): Variant;
function DoSqr(var Param: TOpParam): Variant;
function DoTan(var Param: TOpParam): Variant;
function DoRound(var Param: TOpParam): Variant;
function DoTrunc(var Param: TOpParam): Variant;
function DoDeg(var Param: TOpParam): Variant;
function DoPower(var Param: TOpParam): Variant;
function DoPI(var Param: TOpParam): Variant;
function DoBool(var Param: TOpParam): Variant;
function DoTrue(var Param: TOpParam): Variant;
function DoFalse(var Param: TOpParam): Variant;
function DoRColor(var Param: TOpParam): Variant;
function DoVec2(var Param: TOpParam): Variant;
function DoVec3(var Param: TOpParam): Variant;
function DoVec4(var Param: TOpParam): Variant;
function DoRandom(var Param: TOpParam): Variant;
function DoRandomFloat(var Param: TOpParam): Variant;
function DoMax(var Param: TOpParam): Variant;
function DoMin(var Param: TOpParam): Variant;
function DoClamp(var Param: TOpParam): Variant;
function DoIfThen(var Param: TOpParam): Variant;
function DoStr(var Param: TOpParam): Variant;
function DoGetFirst(var Param: TOpParam): Variant;
function DoDeleteFirst(var Param: TOpParam): Variant;
function DoGetLast(var Param: TOpParam): Variant;
function DoDeleteLast(var Param: TOpParam): Variant;
function DoMultiple(var Param: TOpParam): Variant;
function DoPrint(var Param: TOpParam): Variant;
procedure InternalReg; virtual;
public
ProcList: THashList;
Trigger: POpRTData;
UserObject: TCoreClassObject;
UserData: Pointer;
constructor Create;
constructor CustomCreate(maxHashLen: Integer); virtual;
destructor Destroy; override;
function GetProcDescription(ProcName: SystemString): SystemString; overload;
function GetAllProcDescription(): TPascalStringList; overload;
function GetAllProcDescription(Category: U_String): TPascalStringList; overload;
function RegOpC(ProcName: SystemString; OnProc: TOnOpCall): POpRTData; overload;
function RegOpC(ProcName, ProcDescription: SystemString; OnProc: TOnOpCall): POpRTData; overload;
function RegOpM(ProcName: SystemString; OnProc: TOnOpMethod): POpRTData; overload;
function RegOpM(ProcName, ProcDescription: SystemString; OnProc: TOnOpMethod): POpRTData; overload;
function RegObjectOpC(ProcName: SystemString; OnProc: TOnObjectOpCall): POpRTData; overload;
function RegObjectOpC(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpCall): POpRTData; overload;
function RegObjectOpM(ProcName: SystemString; OnProc: TOnObjectOpMethod): POpRTData; overload;
function RegObjectOpM(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpMethod): POpRTData; overload;
function RegOpP(ProcName: SystemString; OnProc: TOnOpProc): POpRTData; overload;
function RegOpP(ProcName, ProcDescription: SystemString; OnProc: TOnOpProc): POpRTData; overload;
function RegObjectOpP(ProcName: SystemString; OnProc: TOnObjectOpProc): POpRTData; overload;
function RegObjectOpP(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpProc): POpRTData; overload;
end;
opClass = class of TOpCode;
TOpCode = class(TCoreClassObject)
private type
POpData = ^opData;
opData = record
Op: TOpCode;
Value: Variant;
ValueType: TOpValueType;
end;
protected
FParam: TCoreClassList;
FAutoFreeLink: Boolean;
function DoExecute(opRT: TOpCustomRunTime): Variant; virtual;
function GetParam(index: Integer): POpData;
procedure EvaluateParam(opRT: TOpCustomRunTime); overload;
procedure EvaluateParam(printLog: Boolean; opRT: TOpCustomRunTime); overload;
public
Owner: TOpCode;
ParsedInfo: SystemString;
ParsedLineNo: Integer;
constructor Create(AFreeLink: Boolean);
destructor Destroy; override;
procedure SaveToStream(stream: TCoreClassStream);
class function LoadFromStream(stream: TCoreClassStream; out LoadedOp: TOpCode): Boolean;
function AddValue(v: Variant): Integer; overload;
function AddValueT(v: Variant; VT: TOpValueType): Integer; overload;
function AddLink(Obj: TOpCode): Integer;
function CloneNewSelf: TOpCode;
property Param[index: Integer]: POpData read GetParam; default;
function Count: Integer;
function Execute: Variant; overload;
function Execute(opRT: TOpCustomRunTime): Variant; overload;
function OwnerRoot: TOpCode;
property AutoFreeLink: Boolean read FAutoFreeLink write FAutoFreeLink;
end;
op_Value = class sealed(TOpCode)
private
// a
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Proc = class sealed(TOpCode)
private
// proc(a,b,c...)
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Add_Prefix = class sealed(TOpCode)
private
// +proc
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Sub_Prefix = class sealed(TOpCode)
private
// -proc
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Add = class sealed(TOpCode)
private
// a + b + n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Sub = class sealed(TOpCode)
private
// a - b - n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Mul = class sealed(TOpCode)
private
// a * b * n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Div = class sealed(TOpCode)
private
// a / b / n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_IntDiv = class sealed(TOpCode)
private
// a div b div n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Pow = class sealed(TOpCode)
private
// a pow b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Mod = class sealed(TOpCode)
private
// a mod b mod n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Or = class sealed(TOpCode)
private
// a or b or n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_And = class sealed(TOpCode)
private
// a and b and n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Xor = class sealed(TOpCode)
private
// a xor b xor n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Shl = class sealed(TOpCode)
private
// a shl b shl n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Shr = class sealed(TOpCode)
private
// a shr b shr n...
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Equal = class sealed(TOpCode)
private
// a = b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_LessThan = class sealed(TOpCode)
private
// a < b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_EqualOrLessThan = class sealed(TOpCode)
private
// a <= b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_GreaterThan = class sealed(TOpCode)
private
// a > b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_EqualOrGreaterThan = class sealed(TOpCode)
private
// a >= b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_NotEqual = class sealed(TOpCode)
private
// a <> b
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Symbol_Sub = class sealed(TOpCode)
private
// -a
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
op_Symbol_Add = class sealed(TOpCode)
private
// +a
function DoExecute(opRT: TOpCustomRunTime): Variant; override;
end;
function LoadOpFromStream(stream: TCoreClassStream; out LoadedOp: TOpCode): Boolean;
var
DefaultOpRT: TOpCustomRunTime;
implementation
uses Geometry2DUnit, Geometry3DUnit;
type
opRegData = record
opClass: opClass;
OpName: TPascalString;
hash: Cardinal;
end;
POpRegData = ^opRegData;
var
OpList: TCoreClassList;
procedure TOpRTData.Init;
begin
SetLength(Param, 0);
Name := '';
Description := '';
Category := '';
OnOpCall := nil;
OnOpMethod := nil;
OnObjectOpCall := nil;
OnObjectOpMethod := nil;
OnOpProc := nil;
OnObjectOpProc := nil;
end;
function GetRegistedOp(Name: TPascalString): POpRegData;
var
i: Integer;
p: POpRegData;
hash: Cardinal;
begin
Result := nil;
hash := FastHashPPascalString(@Name);
for i := 0 to OpList.Count - 1 do
begin
p := OpList[i];
if (p^.hash = hash) and (SameText(Name, p^.OpName)) then
Exit(p);
end;
end;
procedure RegisterOp(c: opClass);
var
p: POpRegData;
begin
if GetRegistedOp(c.ClassName) <> nil then
raise Exception.Create('same op ' + c.ClassName);
new(p);
p^.opClass := c;
p^.OpName := p^.opClass.ClassName;
p^.hash := FastHashPPascalString(@p^.OpName);
OpList.Add(p);
end;
procedure _FreeOp;
var
i: Integer;
p: POpRegData;
begin
for i := 0 to OpList.Count - 1 do
begin
p := OpList[i];
Dispose(p);
end;
DisposeObject(OpList);
end;
function LoadOpFromStream(stream: TCoreClassStream; out LoadedOp: TOpCode): Boolean;
function LoadFromDataFrame_(CurDataEng: TDataFrameEngine): TOpCode;
var
AName: SystemString;
RegPtr: POpRegData;
i, cnt: Integer;
NeedNewOp: Boolean;
newDataEng: TDataFrameEngine;
v: Variant;
VT: TOpValueType;
begin
AName := CurDataEng.Reader.ReadString;
RegPtr := GetRegistedOp(AName);
if RegPtr <> nil then
begin
Result := RegPtr^.opClass.Create(True);
Result.ParsedInfo := CurDataEng.Reader.ReadString;
Result.ParsedLineNo := CurDataEng.Reader.ReadInteger;
cnt := CurDataEng.Reader.ReadInteger;
for i := 0 to cnt - 1 do
begin
NeedNewOp := CurDataEng.Reader.ReadBool;
if NeedNewOp then
begin
// create new TOpCode
newDataEng := TDataFrameEngine.Create;
CurDataEng.Reader.ReadDataFrame(newDataEng);
Result.AddLink(LoadFromDataFrame_(newDataEng));
DisposeObject(newDataEng);
end
else
begin
v := CurDataEng.Reader.ReadVariant;
VT := TOpValueType(CurDataEng.Reader.ReadInteger);
Result.AddValueT(v, VT);
end;
end;
end
else
raise Exception.Create('opCode failed');
end;
var
DataEng: TDataFrameEngine;
DataEdition: Integer;
begin
Result := False;
DataEng := TDataFrameEngine.Create;
try
DataEng.DecodeFrom(stream, True);
DataEdition := DataEng.Reader.ReadInteger;
if DataEdition = 1 then
begin
LoadedOp := LoadFromDataFrame_(DataEng);
Result := True;
end
else
LoadedOp := nil;
except
end;
DisposeObject(DataEng);
end;
procedure TOpCustomRunTime.FreeNotifyProc(p: Pointer);
begin
SetLength(POpRTData(p)^.Param, 0);
Dispose(POpRTData(p));
end;
function TOpCustomRunTime.DoInt(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Int(v);
end;
function TOpCustomRunTime.DoFrac(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Frac(v);
end;
function TOpCustomRunTime.DoExp(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Exp(v);
end;
function TOpCustomRunTime.DoCos(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Cos(v);
end;
function TOpCustomRunTime.DoSin(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Sin(v);
end;
function TOpCustomRunTime.DoLn(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := ln(v);
end;
function TOpCustomRunTime.DoArcTan(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := ArcTan(v);
end;
function TOpCustomRunTime.DoSqrt(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Sqrt(v);
end;
function TOpCustomRunTime.DoSqr(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Sqr(v);
end;
function TOpCustomRunTime.DoTan(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Tan(v);
end;
function TOpCustomRunTime.DoRound(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Round(Double(v));
end;
function TOpCustomRunTime.DoTrunc(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := Trunc(Double(v));
end;
function TOpCustomRunTime.DoDeg(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
Result := NormalizeDegAngle(TGeoFloat(v));
end;
function TOpCustomRunTime.DoPower(var Param: TOpParam): Variant;
var
v: Variant;
i: Integer;
begin
if length(Param) = 2 then
Result := Power(Param[0], Param[1])
else
Result := 0;
end;
function TOpCustomRunTime.DoPI(var Param: TOpParam): Variant;
begin
Result := PI;
end;
function TOpCustomRunTime.DoBool(var Param: TOpParam): Variant;
function v2b(const v: Variant): Boolean;
var
n: TPascalString;
begin
if VarIsStr(v) then
begin
n := VarToStr(v);
n := n.DeleteChar(#32#9);
if n.Same('True') or n.Same('Yes') or n.Same('1') then
Result := True
else
Result := False;
end
else if VarIsOrdinal(v) then
Result := Boolean(v)
else if VarIsFloat(v) then
Result := Boolean(Round(Double(v)))
else
Result := Boolean(v);
end;
var
n: Boolean;
i: Integer;
begin
n := True;
for i := low(Param) to high(Param) do
n := n and v2b(Param[i]);
Result := n;
end;
function TOpCustomRunTime.DoTrue(var Param: TOpParam): Variant;
begin
Result := True;
end;
function TOpCustomRunTime.DoFalse(var Param: TOpParam): Variant;
begin
Result := False;
end;
function TOpCustomRunTime.DoRColor(var Param: TOpParam): Variant;
var
buff: array [0 .. 3] of SystemString;
i: Integer;
begin
for i := 0 to 2 do
buff[i] := '0.0';
buff[3] := '1.0';
for i := Low(Param) to high(Param) do
buff[i] := VarToStr(Param[i]);
Result := Format('RColor(%s,%s,%s,%s)', [buff[0], buff[1], buff[2], buff[3]]);
end;
function TOpCustomRunTime.DoVec2(var Param: TOpParam): Variant;
var
buff: array [0 .. 1] of SystemString;
i: Integer;
begin
for i := Low(buff) to high(buff) do
buff[i] := '0.0';
for i := Low(Param) to high(Param) do
buff[i] := VarToStr(Param[i]);
Result := Format('Vec2(%s,%s)', [buff[0], buff[1]]);
end;
function TOpCustomRunTime.DoVec3(var Param: TOpParam): Variant;
var
buff: array [0 .. 2] of SystemString;
i: Integer;
begin
for i := Low(buff) to high(buff) do
buff[i] := '0.0';
for i := Low(Param) to high(Param) do
buff[i] := VarToStr(Param[i]);
Result := Format('Vec3(%s,%s,%s)', [buff[0], buff[1], buff[2]]);
end;
function TOpCustomRunTime.DoVec4(var Param: TOpParam): Variant;
var
buff: array [0 .. 3] of SystemString;
i: Integer;
begin
for i := Low(buff) to high(buff) do
buff[i] := '0.0';
for i := Low(Param) to high(Param) do
buff[i] := VarToStr(Param[i]);
Result := Format('Vec4(%s,%s,%s,%s)', [buff[0], buff[1], buff[2], buff[3]]);
end;
function TOpCustomRunTime.DoRandom(var Param: TOpParam): Variant;
var
v: Integer;
i: Integer;
begin
v := 0;
for i := low(Param) to high(Param) do
v := v + Param[i];
if v <> 0 then
Result := MT19937Rand32(v)
else
Result := MT19937Rand32(MaxInt);
end;
function TOpCustomRunTime.DoRandomFloat(var Param: TOpParam): Variant;
begin
Result := MT19937RandF;
end;
function TOpCustomRunTime.DoMax(var Param: TOpParam): Variant;
var
i: Integer;
begin
if length(Param) = 0 then
begin
Result := NULL;
Exit;
end;
Result := Param[0];
for i := 1 to length(Param) - 1 do
if Param[i] > Result then
Result := Param[i];
end;
function TOpCustomRunTime.DoMin(var Param: TOpParam): Variant;
var
i: Integer;
begin
if length(Param) = 0 then
begin
Result := NULL;
Exit;
end;
Result := Param[0];
for i := 1 to length(Param) - 1 do
if Param[i] < Result then
Result := Param[i];
end;
function TOpCustomRunTime.DoClamp(var Param: TOpParam): Variant;
var
minv_, maxv_: Variant;
begin
if length(Param) <> 3 then
begin
if length(Param) > 0 then
Result := Param[0]
else
Result := NULL;
Exit;
end;
if Param[1] > Param[2] then
begin
minv_ := Param[2];
maxv_ := Param[1];
end
else
begin
minv_ := Param[1];
maxv_ := Param[2];
end;
if Param[0] < minv_ then
Result := minv_
else if Param[0] > maxv_ then
Result := maxv_
else
Result := Param[0];
end;
function TOpCustomRunTime.DoIfThen(var Param: TOpParam): Variant;
begin
if length(Param) <> 3 then
begin
Result := NULL;
Exit;
end;
if Boolean(Param[0]) = True then
Result := Param[1]
else
Result := Param[2];
end;
function TOpCustomRunTime.DoStr(var Param: TOpParam): Variant;
var
n: TPascalString;
i: Integer;
begin
n := '';
for i := low(Param) to high(Param) do
n.Append(VarToStr(Param[i]));
Result := n;
end;
function TOpCustomRunTime.DoGetFirst(var Param: TOpParam): Variant;
begin
if length(Param) = 2 then
Result := umlGetFirstStr(VarToStr(Param[0]), VarToStr(Param[1])).Text
else
Result := '';
end;
function TOpCustomRunTime.DoDeleteFirst(var Param: TOpParam): Variant;
begin
if length(Param) = 2 then
Result := umlDeleteFirstStr(VarToStr(Param[0]), VarToStr(Param[1])).Text
else
Result := '';
end;
function TOpCustomRunTime.DoGetLast(var Param: TOpParam): Variant;
begin
if length(Param) = 2 then
Result := umlGetLastStr(VarToStr(Param[0]), VarToStr(Param[1])).Text
else
Result := '';
end;
function TOpCustomRunTime.DoDeleteLast(var Param: TOpParam): Variant;
begin
if length(Param) = 2 then
Result := umlDeleteLastStr(VarToStr(Param[0]), VarToStr(Param[1])).Text
else
Result := '';
end;
function TOpCustomRunTime.DoMultiple(var Param: TOpParam): Variant;
var
i: Integer;
begin
if length(Param) >= 2 then
begin
Result := True;
for i := 1 to length(Param) - 1 do
Result := Result and umlMultipleMatch(VarToStr(Param[0]), VarToStr(Param[i]));
end
else
Result := True;
end;
function TOpCustomRunTime.DoPrint(var Param: TOpParam): Variant;
var
i: Integer;
begin
for i := low(Param) to high(Param) do
begin
DoStatusNoLn(Param[i]);
if i < high(Param) then
DoStatusNoLn(#32);
end;
DoStatusNoLn;
Result := True;
end;
procedure TOpCustomRunTime.InternalReg;
begin
ProcList.OnFreePtr := {$IFDEF FPC}@{$ENDIF FPC}FreeNotifyProc;
RegOpM('Int', 'Int(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoInt)^.Category := 'Base Math';
RegOpM('Frac', 'Frac(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoFrac)^.Category := 'Base Math';
RegOpM('Exp', 'Exp(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoExp)^.Category := 'Base Math';
RegOpM('Cos', 'Cos(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoCos)^.Category := 'Base Math';
RegOpM('Sin', 'Sin(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoSin)^.Category := 'Base Math';
RegOpM('Ln', 'Ln(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoLn)^.Category := 'Base Math';
RegOpM('ArcTan', 'ArcTan(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoArcTan)^.Category := 'Base Math';
RegOpM('Sqrt', 'Sqrt(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoSqrt)^.Category := 'Base Math';
RegOpM('Sqr', 'Sqr(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoSqr)^.Category := 'Base Math';
RegOpM('Tan', 'Tan(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoTan)^.Category := 'Base Math';
RegOpM('Round', 'Round(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoRound)^.Category := 'Base Math';
RegOpM('Trunc', 'Trunc(0..n): math function', {$IFDEF FPC}@{$ENDIF FPC}DoTrunc)^.Category := 'Base Math';
RegOpM('Deg', 'Deg(0..n): NormalizeDegAngle function', {$IFDEF FPC}@{$ENDIF FPC}DoDeg)^.Category := 'Base Math';
RegOpM('Power', 'Power(float,float): Power: Raise base to any power function', {$IFDEF FPC}@{$ENDIF FPC}DoPower)^.Category := 'Base Math';
RegOpM('PI', 'PI(): return PI', {$IFDEF FPC}@{$ENDIF FPC}DoPI)^.Category := 'Base Math';
RegOpM('Bool', 'Bool(n..n): convert any variant as bool', {$IFDEF FPC}@{$ENDIF FPC}DoBool)^.Category := 'Base Math';
RegOpM('Boolean', 'Boolean(n..n): convert any variant as bool', {$IFDEF FPC}@{$ENDIF FPC}DoBool)^.Category := 'Base Math';
RegOpM('True', 'True(): return true', {$IFDEF FPC}@{$ENDIF FPC}DoTrue)^.Category := 'Base Math';
RegOpM('False', 'False(): return false', {$IFDEF FPC}@{$ENDIF FPC}DoFalse)^.Category := 'Base Math';
RegOpM('RColor', 'RColor(R,G,B,A): return RColor string', {$IFDEF FPC}@{$ENDIF FPC}DoRColor)^.Category := 'Base Math';
RegOpM('Vec2', 'Vec2(X,Y): return Vec2 string', {$IFDEF FPC}@{$ENDIF FPC}DoVec2)^.Category := 'Base Math';
RegOpM('Vec3', 'Vec3(X,Y,Z): return Vec3 string', {$IFDEF FPC}@{$ENDIF FPC}DoVec3)^.Category := 'Base Math';
RegOpM('Vec4', 'Vec4(X,Y,Z,W): return Vec4 string', {$IFDEF FPC}@{$ENDIF FPC}DoVec4)^.Category := 'Base Math';
RegOpM('Random', 'Random(0..n): return number', {$IFDEF FPC}@{$ENDIF FPC}DoRandom)^.Category := 'Base Math';
RegOpM('RandomFloat', 'RandomFloat(): return float', {$IFDEF FPC}@{$ENDIF FPC}DoRandomFloat)^.Category := 'Base Math';
RegOpM('RandomF', 'RandomF(): return float', {$IFDEF FPC}@{$ENDIF FPC}DoRandomFloat)^.Category := 'Base Math';
RegOpM('Max', 'Max(0..n): return max value', {$IFDEF FPC}@{$ENDIF FPC}DoMax)^.Category := 'Base Math';
RegOpM('Min', 'Min(0..n): return min value', {$IFDEF FPC}@{$ENDIF FPC}DoMin)^.Category := 'Base Math';
RegOpM('Clamp', 'Clamp(value, min, max): return clamp value', {$IFDEF FPC}@{$ENDIF FPC}DoClamp)^.Category := 'Base Math';
RegOpM('IfThen', 'IfThen(bool, if true then of value, if false then of value): return if value', {$IFDEF FPC}@{$ENDIF FPC}DoIfThen)^.Category := 'Base Math';
RegOpM('Str', 'Str(n..n): convert any variant as string', {$IFDEF FPC}@{$ENDIF FPC}DoStr)^.Category := 'Base String';
RegOpM('Base String', 'String(n..n): convert any variant as string', {$IFDEF FPC}@{$ENDIF FPC}DoStr)^.Category := 'Base String';
RegOpM('Text', 'Text(n..n): convert any variant as string', {$IFDEF FPC}@{$ENDIF FPC}DoStr)^.Category := 'Base String';
RegOpM('GetFirst', 'GetFirst(string, split Char): return first split segment', {$IFDEF FPC}@{$ENDIF FPC}DoGetFirst)^.Category := 'Base String';
RegOpM('First', 'First(string, split Char): return first split segment', {$IFDEF FPC}@{$ENDIF FPC}DoGetFirst)^.Category := 'Base String';
RegOpM('DeleteFirst', 'DeleteFirst(string, split Char): return removed at after first split segment of value', {$IFDEF FPC}@{$ENDIF FPC}DoDeleteFirst)^.Category := 'Base String';
RegOpM('GetLast', 'GetLast(string, split Char): return last split segment', {$IFDEF FPC}@{$ENDIF FPC}DoGetLast)^.Category := 'Base String';
RegOpM('Last', 'Last(string, split Char): return last split segment', {$IFDEF FPC}@{$ENDIF FPC}DoGetLast)^.Category := 'Base String';
RegOpM('DeleteLast', 'DeleteLast(string, split Char): return removed at after last split segment of value', {$IFDEF FPC}@{$ENDIF FPC}DoDeleteLast)^.Category := 'Base String';
RegOpM('MultipleMatch', 'MultipleMatch(multile exp, n..n): return bool', {$IFDEF FPC}@{$ENDIF FPC}DoMultiple)^.Category := 'Base String';
RegOpM('Multiple', 'MultipleMatch(multile exp, n..n): return bool', {$IFDEF FPC}@{$ENDIF FPC}DoMultiple)^.Category := 'Base String';
RegOpM('Print', 'Print(n..n): output to console', {$IFDEF FPC}@{$ENDIF FPC}DoPrint)^.Category := 'Base String';
RegOpM('DoStatus', 'DoStatus(n..n): output to console', {$IFDEF FPC}@{$ENDIF FPC}DoPrint)^.Category := 'Base String';
end;
constructor TOpCustomRunTime.Create;
begin
CustomCreate(512);
end;
constructor TOpCustomRunTime.CustomCreate(maxHashLen: Integer);
begin
inherited Create;
ProcList := THashList.CustomCreate(maxHashLen);
ProcList.AutoFreeData := True;
Trigger := nil;
UserObject := nil;
UserData := nil;
InternalReg;
end;
destructor TOpCustomRunTime.Destroy;
begin
DisposeObject(ProcList);
inherited Destroy;
end;
function TOpCustomRunTime.GetProcDescription(ProcName: SystemString): SystemString;
var
p: POpRTData;
begin
Result := ProcName + '(): no Descripion';
p := ProcList[ProcName];
if p <> nil then
if p^.Description <> '' then
Result := p^.Description;
end;
function TOpCustomRunTime.GetAllProcDescription(): TPascalStringList;
begin
Result := GetAllProcDescription('*');
end;
function TOpCustomRunTime.GetAllProcDescription(Category: U_String): TPascalStringList;
var
arry: THashDataArray;
hl: THashObjectList;
ns, tmp: TPascalStringList;
i, j: Integer;
p: POpRTData;
n: TPascalString;
begin
Result := TPascalStringList.Create;
arry := ProcList.GetHashDataArray();
hl := THashObjectList.CustomCreate(True, 256);
for i := Low(arry) to High(arry) do
begin
p := arry[i]^.Data;
if not hl.Exists(p^.Category) then
hl.FastAdd(p^.Category, TPascalStringList.Create);
tmp := hl[p^.Category] as TPascalStringList;
if p^.Description <> '' then
n := p^.Description
else
n := p^.Name + '(): no Descripion';
tmp.Add(n);
end;
SetLength(arry, 0);
ns := TPascalStringList.Create;
hl.GetListData(ns);
for i := 0 to ns.Count - 1 do
if umlMultipleMatch(Category, ns[i]) then
begin
Result.Add(PFormat('%s:', [ns[i].Text]));
tmp := ns.Objects[i] as TPascalStringList;
for j := 0 to tmp.Count - 1 do
Result.Add(' ' + tmp[j]);
Result.Add('');
end;
n := '';
DisposeObject(ns);
DisposeObject(hl);
end;
function TOpCustomRunTime.RegOpC(ProcName: SystemString; OnProc: TOnOpCall): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnOpCall := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegOpC(ProcName, ProcDescription: SystemString; OnProc: TOnOpCall): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnOpCall := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegOpM(ProcName: SystemString; OnProc: TOnOpMethod): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnOpMethod := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegOpM(ProcName, ProcDescription: SystemString; OnProc: TOnOpMethod): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnOpMethod := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpC(ProcName: SystemString; OnProc: TOnObjectOpCall): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnObjectOpCall := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpC(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpCall): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnObjectOpCall := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpM(ProcName: SystemString; OnProc: TOnObjectOpMethod): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnObjectOpMethod := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpM(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpMethod): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnObjectOpMethod := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegOpP(ProcName: SystemString; OnProc: TOnOpProc): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnOpProc := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegOpP(ProcName, ProcDescription: SystemString; OnProc: TOnOpProc): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnOpProc := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpP(ProcName: SystemString; OnProc: TOnObjectOpProc): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.OnObjectOpProc := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCustomRunTime.RegObjectOpP(ProcName, ProcDescription: SystemString; OnProc: TOnObjectOpProc): POpRTData;
var
p: POpRTData;
begin
new(p);
p^.Init;
p^.Name := ProcName;
p^.Description := ProcDescription;
p^.OnObjectOpProc := OnProc;
ProcList.Add(ProcName, p, True);
Result := p;
end;
function TOpCode.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := NULL;
end;
function TOpCode.GetParam(index: Integer): POpData;
begin
Result := FParam[index];
end;
procedure TOpCode.EvaluateParam(opRT: TOpCustomRunTime);
begin
EvaluateParam(False, opRT);
end;
procedure TOpCode.EvaluateParam(printLog: Boolean; opRT: TOpCustomRunTime);
var
i: Integer;
p: POpData;
begin
for i := 0 to FParam.Count - 1 do
begin
p := FParam[i];
if p^.Op <> nil then
begin
try
p^.Op.EvaluateParam(printLog, opRT);
except
end;
try
p^.Value := p^.Op.DoExecute(opRT);
if printLog then
DoStatus('%s value:%s', [ClassName, VarToStr(p^.Value)]);
except
end;
end;
end;
end;
constructor TOpCode.Create(AFreeLink: Boolean);
begin
inherited Create;
Owner := nil;
FParam := TCoreClassList.Create;
FAutoFreeLink := AFreeLink;
ParsedInfo := '';
ParsedLineNo := 0;
end;
destructor TOpCode.Destroy;
var
i: Integer;
p: POpData;
begin
if FParam <> nil then
begin
for i := 0 to FParam.Count - 1 do
begin
p := FParam[i];
if (FAutoFreeLink) and (p^.Op <> nil) then
DisposeObject(p^.Op);
Dispose(p);
end;
FParam.Clear;
DisposeObject(FParam);
end;
inherited Destroy;
end;
procedure TOpCode.SaveToStream(stream: TCoreClassStream);
procedure SaveToDataFrame(Op: TOpCode; CurDataEng: TDataFrameEngine);
var
i: Integer;
p: POpData;
newDataEng: TDataFrameEngine;
begin
CurDataEng.WriteString(Op.ClassName);
CurDataEng.WriteString(Op.ParsedInfo);
CurDataEng.WriteInteger(Op.ParsedLineNo);
CurDataEng.WriteInteger(Op.Count);
for i := 0 to Op.Count - 1 do
begin
p := Op[i];
if p^.Op <> nil then
begin
CurDataEng.WriteBool(True);
newDataEng := TDataFrameEngine.Create;
SaveToDataFrame(p^.Op, newDataEng);
CurDataEng.WriteDataFrame(newDataEng);
DisposeObject(newDataEng);
end
else
begin
CurDataEng.WriteBool(False);
CurDataEng.WriteVariant(p^.Value);
CurDataEng.WriteInteger(Integer(p^.ValueType));
end;
end;
end;
var
DataEng: TDataFrameEngine;
begin
DataEng := TDataFrameEngine.Create;
DataEng.WriteInteger(1);
SaveToDataFrame(Self, DataEng);
DataEng.EncodeTo(stream, True);
DisposeObject(DataEng);
end;
class function TOpCode.LoadFromStream(stream: TCoreClassStream; out LoadedOp: TOpCode): Boolean;
begin
Result := LoadOpFromStream(stream, LoadedOp);
end;
function TOpCode.AddValue(v: Variant): Integer;
var
p: POpData;
begin
new(p);
p^.Op := nil;
p^.Value := v;
case VarType(v) of
varSmallInt: p^.ValueType := ovtSmallInt;
varInteger: p^.ValueType := ovtInt;
varSingle: p^.ValueType := ovtSingle;
varDouble: p^.ValueType := ovtDouble;
varCurrency: p^.ValueType := ovtCurrency;
varBoolean: p^.ValueType := ovtBool;
varShortInt: p^.ValueType := ovtShortInt;
varByte: p^.ValueType := ovtByte;
varWord: p^.ValueType := ovtWord;
varLongWord: p^.ValueType := ovtUInt;
varInt64: p^.ValueType := ovtInt64;
varUInt64: p^.ValueType := ovtUInt64;
else
begin
if VarIsStr(v) then
p^.ValueType := ovtString
else
p^.ValueType := ovtUnknow;
end;
end;
Result := FParam.Add(p);
end;
function TOpCode.AddValueT(v: Variant; VT: TOpValueType): Integer;
var
p: POpData;
begin
new(p);
p^.Op := nil;
p^.Value := v;
p^.ValueType := VT;
Result := FParam.Add(p);
end;
function TOpCode.AddLink(Obj: TOpCode): Integer;
var
p: POpData;
begin
new(p);
if Obj.Owner <> nil then
p^.Op := Obj.CloneNewSelf
else
p^.Op := Obj;
p^.Op.Owner := Self;
p^.Value := NULL;
p^.ValueType := ovtUnknow;
Result := FParam.Add(p);
end;
function TOpCode.CloneNewSelf: TOpCode;
var
i: Integer;
p: POpData;
begin
Result := opClass(Self.ClassType).Create(True);
Result.ParsedInfo := Self.ParsedInfo;
Result.ParsedLineNo := Self.ParsedLineNo;
for i := 0 to FParam.Count - 1 do
begin
p := FParam[i];
if p^.Op <> nil then
Result.AddLink(p^.Op.CloneNewSelf)
else
Result.AddValueT(p^.Value, p^.ValueType);
end;
end;
function TOpCode.Count: Integer;
begin
Result := FParam.Count;
end;
function TOpCode.Execute: Variant;
begin
Result := Execute(DefaultOpRT);
end;
function TOpCode.Execute(opRT: TOpCustomRunTime): Variant;
begin
try
EvaluateParam(opRT);
except
Result := NULL;
Exit;
end;
try
Result := DoExecute(opRT);
except
Result := NULL;
end;
end;
function TOpCode.OwnerRoot: TOpCode;
begin
if Owner = nil then
Result := Self
else
Result := Owner.OwnerRoot;
end;
{ op_Value }
function op_Value.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value;
end;
{ op_Proc }
function op_Proc.DoExecute(opRT: TOpCustomRunTime): Variant;
var
p: POpRTData;
i: Integer;
begin
Result := NULL;
if (opRT = nil) then
opRT := DefaultOpRT;
p := opRT.ProcList[VarToStr(Param[0]^.Value)];
if p = nil then
begin
if opRT = DefaultOpRT then
Exit;
p := DefaultOpRT.ProcList[VarToStr(Param[0]^.Value)];
if p = nil then
Exit;
end;
if length(p^.Param) <> Count - 1 then
SetLength(p^.Param, Count - 1);
for i := 1 to Count - 1 do
p^.Param[i - 1] := Param[i]^.Value;
opRT.Trigger := p;
if Assigned(p^.OnOpCall) then
Result := p^.OnOpCall(p^.Param);
if Assigned(p^.OnOpMethod) then
Result := p^.OnOpMethod(p^.Param);
if Assigned(p^.OnObjectOpCall) then
Result := p^.OnObjectOpCall(opRT, p^.Param);
if Assigned(p^.OnObjectOpMethod) then
Result := p^.OnObjectOpMethod(opRT, p^.Param);
if Assigned(p^.OnOpProc) then
Result := p^.OnOpProc(p^.Param);
if Assigned(p^.OnObjectOpProc) then
Result := p^.OnObjectOpProc(opRT, p^.Param);
end;
{ op_Add_Prefix }
function op_Add_Prefix.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result + Param[i]^.Value;
Result := - - Result;
end;
{ op_Sub_Prefix }
function op_Sub_Prefix.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result + Param[i]^.Value;
Result := -Result;
end;
{ op_Add }
function op_Add.DoExecute(opRT: TOpCustomRunTime): Variant;
function Fast_VarIsStr(var v: Variant): Boolean; {$IFDEF INLINE_ASM} inline; {$ENDIF}
var
p: pVarData;
begin
// optimized
p := @TVarData(v);
while p^.VType = varByRef or varVariant do
p := pVarData(p^.VPointer);
Result := (p^.VType = varOleStr) or (p^.VType = varString) or (p^.VType = varUString);
end;
var
i: Integer;
n1, n2: TPascalString;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
if Fast_VarIsStr(Result) then
begin
// optimized
n1 := VarToStr(Result);
for i := 1 to Count - 1 do
begin
try
n1.Append(VarToStr(Param[i]^.Value));
except
end;
end;
Result := n1.Text;
end
else
begin
for i := 1 to Count - 1 do
begin
try
if Fast_VarIsStr(Result) then
begin
// SystemString combine
n1 := VarToStr(Result);
if not umlIsNumber(n1) then
begin
Result := n1 + VarToStr(Param[i]^.Value);
Continue;
end
end;
if Fast_VarIsStr(Param[i]^.Value) then
begin
// SystemString combine
n2 := VarToStr(Param[i]^.Value);
if not umlIsNumber(n2) then
begin
Result := VarToStr(Result) + n2;
Continue;
end
end;
// logic compute
Result := Result + Param[i]^.Value;
except
end;
end;
end;
end;
{ op_Sub }
function op_Sub.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result - Param[i]^.Value;
end;
{ op_Mul }
function op_Mul.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result * Param[i]^.Value;
end;
{ op_Div }
function op_Div.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result / Param[i]^.Value;
end;
{ op_IntDiv }
function op_IntDiv.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result div Param[i]^.Value;
end;
{ op_Pow }
function op_Pow.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Power(Result, Param[i]^.Value);
end;
{ op_Mod }
function op_Mod.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result mod Param[i]^.Value;
end;
{ op_Or }
function op_Or.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result or Param[i]^.Value;
end;
{ op_And }
function op_And.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result and Param[i]^.Value;
end;
{ op_Xor }
function op_Xor.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := Result xor Param[i]^.Value;
end;
{ op_shl }
function op_Shl.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := UInt64(Result) shl UInt64(Param[i]^.Value);
end;
{ op_shr }
function op_Shr.DoExecute(opRT: TOpCustomRunTime): Variant;
var
i: Integer;
begin
if Count = 0 then
Exit(NULL);
Result := Param[0]^.Value;
for i := 1 to Count - 1 do
Result := UInt64(Result) shr UInt64(Param[i]^.Value);
end;
{ op_Equal }
function op_Equal.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value = Param[1]^.Value;
end;
{ op_LessThan }
function op_LessThan.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value < Param[1]^.Value;
end;
{ op_EqualOrLessThan }
function op_EqualOrLessThan.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value <= Param[1]^.Value;
end;
{ op_GreaterThan }
function op_GreaterThan.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value > Param[1]^.Value;
end;
{ op_EqualOrGreaterThan }
function op_EqualOrGreaterThan.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value >= Param[1]^.Value;
end;
{ op_NotEqual }
function op_NotEqual.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value <> Param[1]^.Value;
end;
{ op_Symbol_Sub }
function op_Symbol_Sub.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := -Param[0]^.Value;
end;
{ op_Symbol_Add }
function op_Symbol_Add.DoExecute(opRT: TOpCustomRunTime): Variant;
begin
Result := Param[0]^.Value;
end;
initialization
DefaultOpRT := TOpCustomRunTime.Create;
OleVariantInt64AsDouble := True;
OpList := TCoreClassList.Create;
RegisterOp(op_Value);
RegisterOp(op_Proc);
RegisterOp(op_Add_Prefix);
RegisterOp(op_Sub_Prefix);
RegisterOp(op_Add);
RegisterOp(op_Sub);
RegisterOp(op_Mul);
RegisterOp(op_Div);
RegisterOp(op_IntDiv);
RegisterOp(op_Mod);
RegisterOp(op_Or);
RegisterOp(op_And);
RegisterOp(op_Xor);
RegisterOp(op_Shl);
RegisterOp(op_Shr);
RegisterOp(op_Equal);
RegisterOp(op_LessThan);
RegisterOp(op_EqualOrLessThan);
RegisterOp(op_GreaterThan);
RegisterOp(op_EqualOrGreaterThan);
RegisterOp(op_NotEqual);
RegisterOp(op_Symbol_Sub);
RegisterOp(op_Symbol_Add);
finalization
DisposeObject(DefaultOpRT);
_FreeOp;
end.