12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055 |
- unit dbf_prsdef;
- interface
- {$I dbf_common.inc}
- uses
- SysUtils,
- Classes,
- Db,
- dbf_prssupp;
- const
- MaxArg = 6;
- ArgAllocSize = 32;
- type
- TExpressionType = (etInteger, etString, etBoolean, etLargeInt, etFloat, etDateTime,
- etLeftBracket, etRightBracket, etComma, etUnknown);
- PPChar = ^PChar;
- PBoolean = ^Boolean;
- PInteger = ^Integer;
- PDateTime = ^TDateTime;
- EParserException = class(Exception);
- PExpressionRec = ^TExpressionRec;
- PDynamicType = ^TDynamicType;
- PDateTimeRec = ^TDateTimeRec;
- {$ifdef SUPPORT_INT64}
- PLargeInt = ^Int64;
- {$endif}
- TExprWord = class;
- TExprFunc = procedure(Expr: PExpressionRec);
- //-----
- TDynamicType = class(TObject)
- private
- FMemory: PPChar;
- FMemoryPos: PPChar;
- FSize: PInteger;
- public
- constructor Create(DestMem, DestPos: PPChar; ASize: PInteger);
- procedure AssureSpace(ASize: Integer);
- procedure Resize(NewSize: Integer; Exact: Boolean);
- procedure Rewind;
- procedure Append(Source: PChar; Length: Integer);
- procedure AppendInteger(Source: Integer);
- property Memory: PPChar read FMemory;
- property MemoryPos: PPChar read FMemoryPos;
- property Size: PInteger read FSize;
- end;
- TExpressionRec = record
- //used both as linked tree and linked list for maximum evaluation efficiency
- Oper: TExprFunc;
- Next: PExpressionRec;
- Res: TDynamicType;
- ExprWord: TExprWord;
- AuxData: pointer;
- ResetDest: boolean;
- WantsFunction: boolean;
- Args: array[0..MaxArg-1] of PChar;
- ArgsPos: array[0..MaxArg-1] of PChar;
- ArgsSize: array[0..MaxArg-1] of Integer;
- ArgsType: array[0..MaxArg-1] of TExpressionType;
- ArgList: array[0..MaxArg-1] of PExpressionRec;
- end;
- TExprCollection = class(TNoOwnerCollection)
- public
- procedure Check;
- procedure EraseExtraBrackets;
- end;
- TExprWordRec = record
- Name: PChar;
- ShortName: PChar;
- IsOperator: Boolean;
- IsVariable: Boolean;
- IsFunction: Boolean;
- NeedsCopy: Boolean;
- FixedLen: Boolean;
- CanVary: Boolean;
- ResultType: TExpressionType;
- MinArg: Integer;
- MaxArg: Integer;
- TypeSpec: PChar;
- Description: PChar;
- ExprFunc: TExprFunc;
- end;
- TExprWord = class(TObject)
- private
- FName: string;
- FExprFunc: TExprFunc;
- protected
- FRefCount: Cardinal;
- function GetIsOperator: Boolean; virtual;
- function GetIsVariable: Boolean;
- function GetNeedsCopy: Boolean;
- function GetFixedLen: Integer; virtual;
- function GetCanVary: Boolean; virtual;
- function GetResultType: TExpressionType; virtual;
- function GetMinFunctionArg: Integer; virtual;
- function GetMaxFunctionArg: Integer; virtual;
- function GetDescription: string; virtual;
- function GetTypeSpec: string; virtual;
- function GetShortName: string; virtual;
- procedure SetFixedLen(NewLen: integer); virtual;
- public
- constructor Create(AName: string; AExprFunc: TExprFunc);
- function LenAsPointer: PInteger; virtual;
- function AsPointer: PChar; virtual;
- function IsFunction: Boolean; virtual;
- property ExprFunc: TExprFunc read FExprFunc;
- property IsOperator: Boolean read GetIsOperator;
- property CanVary: Boolean read GetCanVary;
- property IsVariable: Boolean read GetIsVariable;
- property NeedsCopy: Boolean read GetNeedsCopy;
- property FixedLen: Integer read GetFixedLen write SetFixedLen;
- property ResultType: TExpressionType read GetResultType;
- property MinFunctionArg: Integer read GetMinFunctionArg;
- property MaxFunctionArg: Integer read GetMaxFunctionArg;
- property Name: string read FName;
- property ShortName: string read GetShortName;
- property Description: string read GetDescription;
- property TypeSpec: string read GetTypeSpec;
- end;
- TExpressShortList = class(TSortedCollection)
- public
- function KeyOf(Item: Pointer): Pointer; override;
- function Compare(Key1, Key2: Pointer): Integer; override;
- procedure FreeItem(Item: Pointer); override;
- end;
- TExpressList = class(TSortedCollection)
- private
- FShortList: TExpressShortList;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Add(Item: Pointer); override;
- function KeyOf(Item: Pointer): Pointer; override;
- function Compare(Key1, Key2: Pointer): Integer; override;
- function Search(Key: Pointer; var Index: Integer): Boolean; override;
- procedure FreeItem(Item: Pointer); override;
- end;
- TConstant = class(TExprWord)
- private
- FResultType: TExpressionType;
- protected
- function GetResultType: TExpressionType; override;
- public
- constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
- end;
- TFloatConstant = class(TConstant)
- private
- FValue: Double;
- public
- // not overloaded to support older Delphi versions
- constructor Create(AName: string; AValue: string);
- constructor CreateAsDouble(AName: string; AValue: Double);
- function AsPointer: PChar; override;
- property Value: Double read FValue write FValue;
- end;
- TUserConstant = class(TFloatConstant)
- private
- FDescription: string;
- protected
- function GetDescription: string; override;
- public
- constructor CreateAsDouble(AName, Descr: string; AValue: Double);
- end;
- TStringConstant = class(TConstant)
- private
- FValue: string;
- public
- constructor Create(AValue: string);
- function AsPointer: PChar; override;
- end;
- TIntegerConstant = class(TConstant)
- private
- FValue: Integer;
- public
- constructor Create(AValue: Integer);
- function AsPointer: PChar; override;
- end;
- TBooleanConstant = class(TConstant)
- private
- FValue: Boolean;
- public
- // not overloaded to support older Delphi versions
- constructor Create(AName: string; AValue: Boolean);
- function AsPointer: PChar; override;
- property Value: Boolean read FValue write FValue;
- end;
- TVariable = class(TExprWord)
- private
- FResultType: TExpressionType;
- protected
- function GetCanVary: Boolean; override;
- function GetResultType: TExpressionType; override;
- public
- constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
- end;
- TFloatVariable = class(TVariable)
- private
- FValue: PDouble;
- public
- constructor Create(AName: string; AValue: PDouble);
- function AsPointer: PChar; override;
- end;
- TStringVariable = class(TVariable)
- private
- FValue: PPChar;
- FFixedLen: Integer;
- protected
- function GetFixedLen: Integer; override;
- procedure SetFixedLen(NewLen: integer); override;
- public
- constructor Create(AName: string; AValue: PPChar);
- function LenAsPointer: PInteger; override;
- function AsPointer: PChar; override;
- property FixedLen: Integer read FFixedLen;
- end;
- TDateTimeVariable = class(TVariable)
- private
- FValue: PDateTimeRec;
- public
- constructor Create(AName: string; AValue: PDateTimeRec);
- function AsPointer: PChar; override;
- end;
- TIntegerVariable = class(TVariable)
- private
- FValue: PInteger;
- public
- constructor Create(AName: string; AValue: PInteger);
- function AsPointer: PChar; override;
- end;
- {$ifdef SUPPORT_INT64}
- TLargeIntVariable = class(TVariable)
- private
- FValue: PLargeInt;
- public
- constructor Create(AName: string; AValue: PLargeInt);
- function AsPointer: PChar; override;
- end;
- {$endif}
- TBooleanVariable = class(TVariable)
- private
- FValue: PBoolean;
- public
- constructor Create(AName: string; AValue: PBoolean);
- function AsPointer: PChar; override;
- end;
- TLeftBracket = class(TExprWord)
- function GetResultType: TExpressionType; override;
- end;
- TRightBracket = class(TExprWord)
- protected
- function GetResultType: TExpressionType; override;
- end;
- TComma = class(TExprWord)
- protected
- function GetResultType: TExpressionType; override;
- end;
- TFunction = class(TExprWord)
- private
- FIsOperator: Boolean;
- FOperPrec: Integer;
- FMinFunctionArg: Integer;
- FMaxFunctionArg: Integer;
- FDescription: string;
- FTypeSpec: string;
- FShortName: string;
- FResultType: TExpressionType;
- protected
- function GetDescription: string; override;
- function GetIsOperator: Boolean; override;
- function GetMinFunctionArg: Integer; override;
- function GetMaxFunctionArg: Integer; override;
- function GetResultType: TExpressionType; override;
- function GetTypeSpec: string; override;
- function GetShortName: string; override;
- procedure InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
- AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer);
- public
- constructor Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; AExprFunc: TExprFunc; Descr: string);
- constructor CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; AExprFunc: TExprFunc; AOperPrec: Integer);
- function IsFunction: Boolean; override;
- property OperPrec: Integer read FOperPrec;
- property TypeSpec: string read FTypeSpec;
- end;
- TVaryingFunction = class(TFunction)
- // Functions that can vary for ex. random generators
- // should be TVaryingFunction to be sure that they are
- // always evaluated
- protected
- function GetCanVary: Boolean; override;
- end;
- const
- ListChar = ','; {the delimiter used with the 'in' operator: e.g.,
- ('a' in 'a,b') =True
- ('c' in 'a,b') =False}
- function ExprCharToExprType(ExprChar: Char): TExpressionType;
- implementation
- function ExprCharToExprType(ExprChar: Char): TExpressionType;
- begin
- case ExprChar of
- 'B': Result := etBoolean;
- 'I': Result := etInteger;
- 'L': Result := etLargeInt;
- 'F': Result := etFloat;
- 'D': Result := etDateTime;
- 'S': Result := etString;
- else
- Result := etUnknown;
- end;
- end;
- procedure _FloatVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^;
- end;
- procedure _BooleanVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PBoolean(Res.MemoryPos^)^ := PBoolean(Args[0])^;
- end;
- procedure _StringConstant(Param: PExpressionRec);
- begin
- with Param^ do
- Res.Append(Args[0], StrLen(Args[0]));
- end;
- procedure _StringVariable(Param: PExpressionRec);
- var
- length: integer;
- begin
- with Param^ do
- begin
- length := PInteger(Args[1])^;
- if length = -1 then
- length := StrLen(PPChar(Args[0])^);
- Res.Append(PPChar(Args[0])^, length);
- end;
- end;
- procedure _DateTimeVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PDateTimeRec(Res.MemoryPos^)^ := PDateTimeRec(Args[0])^;
- end;
- procedure _IntegerVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^;
- end;
- {
- procedure _SmallIntVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PSmallInt(Res.MemoryPos^)^ := PSmallInt(Args[0])^;
- end;
- }
- {$ifdef SUPPORT_INT64}
- procedure _LargeIntVariable(Param: PExpressionRec);
- begin
- with Param^ do
- PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^;
- end;
- {$endif}
- { TExpressionWord }
- constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc);
- begin
- FName := AName;
- FExprFunc := AExprFunc;
- end;
- function TExprWord.GetCanVary: Boolean;
- begin
- Result := False;
- end;
- function TExprWord.GetDescription: string;
- begin
- Result := EmptyStr;
- end;
- function TExprWord.GetShortName: string;
- begin
- Result := EmptyStr;
- end;
- function TExprWord.GetIsOperator: Boolean;
- begin
- Result := False;
- end;
- function TExprWord.GetIsVariable: Boolean;
- begin
- // delphi wants to call the function pointed to by the variable, use '@'
- // fpc simply returns pointer to function, no '@' needed
- Result := (@FExprFunc = @_StringVariable) or
- (@FExprFunc = @_StringConstant) or
- (@FExprFunc = @_FloatVariable) or
- (@FExprFunc = @_IntegerVariable) or
- // (FExprFunc = @_SmallIntVariable) or
- {$ifdef SUPPORT_INT64}
- (@FExprFunc = @_LargeIntVariable) or
- {$endif}
- (@FExprFunc = @_DateTimeVariable) or
- (@FExprFunc = @_BooleanVariable);
- end;
- function TExprWord.GetNeedsCopy: Boolean;
- begin
- Result := (@FExprFunc <> @_StringConstant) and
- // (@FExprFunc <> @_StringVariable) and
- // (@FExprFunc <> @_StringVariableFixedLen) and
- // string variable cannot be used as normal parameter
- // because it is indirectly referenced and possibly
- // not null-terminated (fixed len)
- (@FExprFunc <> @_FloatVariable) and
- (@FExprFunc <> @_IntegerVariable) and
- // (FExprFunc <> @_SmallIntVariable) and
- {$ifdef SUPPORT_INT64}
- (@FExprFunc <> @_LargeIntVariable) and
- {$endif}
- (@FExprFunc <> @_DateTimeVariable) and
- (@FExprFunc <> @_BooleanVariable);
- end;
- function TExprWord.GetFixedLen: Integer;
- begin
- // -1 means variable, non-fixed length
- Result := -1;
- end;
- function TExprWord.GetMinFunctionArg: Integer;
- begin
- Result := 0;
- end;
- function TExprWord.GetMaxFunctionArg: Integer;
- begin
- Result := 0;
- end;
- function TExprWord.GetResultType: TExpressionType;
- begin
- Result := etUnknown;
- end;
- function TExprWord.GetTypeSpec: string;
- begin
- Result := EmptyStr;
- end;
- function TExprWord.AsPointer: PChar;
- begin
- Result := nil;
- end;
- function TExprWord.LenAsPointer: PInteger;
- begin
- Result := nil;
- end;
- function TExprWord.IsFunction: Boolean;
- begin
- Result := False;
- end;
- procedure TExprWord.SetFixedLen(NewLen: integer);
- begin
- end;
- { TConstant }
- constructor TConstant.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
- begin
- inherited Create(AName, AExprFunc);
- FResultType := AVarType;
- end;
- function TConstant.GetResultType: TExpressionType;
- begin
- Result := FResultType;
- end;
- { TFloatConstant }
- constructor TFloatConstant.Create(AName, AValue: string);
- begin
- inherited Create(AName, etFloat, _FloatVariable);
- if Length(AValue) > 0 then
- FValue := StrToFloat(AValue)
- else
- FValue := 0.0;
- end;
- constructor TFloatConstant.CreateAsDouble(AName: string; AValue: Double);
- begin
- inherited Create(AName, etFloat, _FloatVariable);
- FValue := AValue;
- end;
- function TFloatConstant.AsPointer: PChar;
- begin
- Result := PChar(@FValue);
- end;
- { TUserConstant }
- constructor TUserConstant.CreateAsDouble(AName, Descr: string; AValue: Double);
- begin
- FDescription := Descr;
- inherited CreateAsDouble(AName, AValue);
- end;
- function TUserConstant.GetDescription: string;
- begin
- Result := FDescription;
- end;
- { TStringConstant }
- constructor TStringConstant.Create(AValue: string);
- var
- firstChar, lastChar: Char;
- begin
- inherited Create(AValue, etString, _StringConstant);
- firstChar := AValue[1];
- lastChar := AValue[Length(AValue)];
- if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then
- FValue := Copy(AValue, 2, Length(AValue) - 2)
- else
- FValue := AValue;
- end;
- function TStringConstant.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- { TBooleanConstant }
- constructor TBooleanConstant.Create(AName: string; AValue: Boolean);
- begin
- inherited Create(AName, etBoolean, _BooleanVariable);
- FValue := AValue;
- end;
- function TBooleanConstant.AsPointer: PChar;
- begin
- Result := PChar(@FValue);
- end;
- { TIntegerConstant }
- constructor TIntegerConstant.Create(AValue: Integer);
- begin
- inherited Create(IntToStr(AValue), etInteger, _IntegerVariable);
- FValue := AValue;
- end;
- function TIntegerConstant.AsPointer: PChar;
- begin
- Result := PChar(@FValue);
- end;
- { TVariable }
- constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
- begin
- inherited Create(AName, AExprFunc);
- FResultType := AVarType;
- end;
- function TVariable.GetCanVary: Boolean;
- begin
- Result := True;
- end;
- function TVariable.GetResultType: TExpressionType;
- begin
- Result := FResultType;
- end;
- { TFloatVariable }
- constructor TFloatVariable.Create(AName: string; AValue: PDouble);
- begin
- inherited Create(AName, etFloat, _FloatVariable);
- FValue := AValue;
- end;
- function TFloatVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- { TStringVariable }
- constructor TStringVariable.Create(AName: string; AValue: PPChar);
- begin
- // variable or fixed length?
- inherited Create(AName, etString, _StringVariable);
- // store pointer to string
- FValue := AValue;
- FFixedLen := -1;
- end;
- function TStringVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- function TStringVariable.GetFixedLen: Integer;
- begin
- Result := FFixedLen;
- end;
- function TStringVariable.LenAsPointer: PInteger;
- begin
- Result := @FFixedLen;
- end;
- procedure TStringVariable.SetFixedLen(NewLen: integer);
- begin
- FFixedLen := NewLen;
- end;
- { TDateTimeVariable }
- constructor TDateTimeVariable.Create(AName: string; AValue: PDateTimeRec);
- begin
- inherited Create(AName, etDateTime, _DateTimeVariable);
- FValue := AValue;
- end;
- function TDateTimeVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- { TIntegerVariable }
- constructor TIntegerVariable.Create(AName: string; AValue: PInteger);
- begin
- inherited Create(AName, etInteger, _IntegerVariable);
- FValue := AValue;
- end;
- function TIntegerVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- {$ifdef SUPPORT_INT64}
- { TLargeIntVariable }
- constructor TLargeIntVariable.Create(AName: string; AValue: PLargeInt);
- begin
- inherited Create(AName, etLargeInt, _LargeIntVariable);
- FValue := AValue;
- end;
- function TLargeIntVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- {$endif}
- { TBooleanVariable }
- constructor TBooleanVariable.Create(AName: string; AValue: PBoolean);
- begin
- inherited Create(AName, etBoolean, _BooleanVariable);
- FValue := AValue;
- end;
- function TBooleanVariable.AsPointer: PChar;
- begin
- Result := PChar(FValue);
- end;
- { TLeftBracket }
- function TLeftBracket.GetResultType: TExpressionType;
- begin
- Result := etLeftBracket;
- end;
- { TRightBracket }
- function TRightBracket.GetResultType: TExpressionType;
- begin
- Result := etRightBracket;
- end;
- { TComma }
- function TComma.GetResultType: TExpressionType;
- begin
- Result := etComma;
- end;
- { TExpressList }
- constructor TExpressList.Create;
- begin
- inherited;
- FShortList := TExpressShortList.Create;
- end;
- destructor TExpressList.Destroy;
- begin
- inherited;
- FShortList.Free;
- end;
- procedure TExpressList.Add(Item: Pointer);
- var
- I: Integer;
- begin
- inherited;
- { remember we reference the object }
- Inc(TExprWord(Item).FRefCount);
- { also add ShortName as reference }
- if Length(TExprWord(Item).ShortName) > 0 then
- begin
- FShortList.Search(FShortList.KeyOf(Item), I);
- FShortList.Insert(I, Item);
- end;
- end;
- function TExpressList.Compare(Key1, Key2: Pointer): Integer;
- begin
- Result := StrIComp(PChar(Key1), PChar(Key2));
- end;
- function TExpressList.KeyOf(Item: Pointer): Pointer;
- begin
- Result := PChar(TExprWord(Item).Name);
- end;
- procedure TExpressList.FreeItem(Item: Pointer);
- begin
- Dec(TExprWord(Item).FRefCount);
- FShortList.Remove(Item);
- if TExprWord(Item).FRefCount = 0 then
- inherited;
- end;
- function TExpressList.Search(Key: Pointer; var Index: Integer): Boolean;
- var
- SecIndex: Integer;
- begin
- Result := inherited Search(Key, Index);
- if not Result then
- begin
- Result := FShortList.Search(Key, SecIndex);
- if Result then
- Index := IndexOf(FShortList.Items[SecIndex]);
- end;
- end;
- function TExpressShortList.Compare(Key1, Key2: Pointer): Integer;
- begin
- Result := StrIComp(PChar(Key1), PChar(Key2));
- end;
- function TExpressShortList.KeyOf(Item: Pointer): Pointer;
- begin
- Result := PChar(TExprWord(Item).ShortName);
- end;
- procedure TExpressShortList.FreeItem(Item: Pointer);
- begin
- end;
- { TExprCollection }
- procedure TExprCollection.Check;
- var
- brCount, I: Integer;
- begin
- brCount := 0;
- for I := 0 to Count - 1 do
- begin
- case TExprWord(Items[I]).ResultType of
- etLeftBracket: Inc(brCount);
- etRightBracket: Dec(brCount);
- end;
- end;
- if brCount <> 0 then
- raise EParserException.Create('Unequal brackets');
- end;
- procedure TExprCollection.EraseExtraBrackets;
- var
- I: Integer;
- brCount: Integer;
- begin
- if (TExprWord(Items[0]).ResultType = etLeftBracket) then
- begin
- brCount := 1;
- I := 1;
- while (I < Count) and (brCount > 0) do
- begin
- case TExprWord(Items[I]).ResultType of
- etLeftBracket: Inc(brCount);
- etRightBracket: Dec(brCount);
- end;
- Inc(I);
- end;
- if (brCount = 0) and (I = Count) and (TExprWord(Items[I - 1]).ResultType =
- etRightBracket) then
- begin
- for I := 0 to Count - 3 do
- Items[I] := Items[I + 1];
- Count := Count - 2;
- EraseExtraBrackets; //Check if there are still too many brackets
- end;
- end;
- end;
- { TFunction }
- constructor TFunction.Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
- AExprFunc: TExprFunc; Descr: string);
- begin
- //to increase compatibility don't use default parameters
- FDescription := Descr;
- FShortName := AShortName;
- InternalCreate(AName, ATypeSpec, AMinFuncArg, AResultType, AExprFunc, false, 0);
- end;
- constructor TFunction.CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType;
- AExprFunc: TExprFunc; AOperPrec: Integer);
- begin
- InternalCreate(AName, ATypeSpec, -1, AResultType, AExprFunc, true, AOperPrec);
- end;
- procedure TFunction.InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
- AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer);
- begin
- inherited Create(AName, AExprFunc);
- FMaxFunctionArg := Length(ATypeSpec);
- FMinFunctionArg := AMinFuncArg;
- if AMinFuncArg = -1 then
- FMinFunctionArg := FMaxFunctionArg;
- FIsOperator := AIsOperator;
- FOperPrec := AOperPrec;
- FTypeSpec := ATypeSpec;
- FResultType := AResultType;
- // check correctness
- if FMaxFunctionArg > MaxArg then
- raise EParserException.Create('Too many arguments');
- end;
- function TFunction.GetDescription: string;
- begin
- Result := FDescription;
- end;
- function TFunction.GetIsOperator: Boolean;
- begin
- Result := FIsOperator;
- end;
- function TFunction.GetMinFunctionArg: Integer;
- begin
- Result := FMinFunctionArg;
- end;
- function TFunction.GetMaxFunctionArg: Integer;
- begin
- Result := FMaxFunctionArg;
- end;
- function TFunction.GetResultType: TExpressionType;
- begin
- Result := FResultType;
- end;
- function TFunction.GetShortName: string;
- begin
- Result := FShortName;
- end;
- function TFunction.GetTypeSpec: string;
- begin
- Result := FTypeSpec;
- end;
- function TFunction.IsFunction: Boolean;
- begin
- Result := True;
- end;
- { TVaryingFunction }
- function TVaryingFunction.GetCanVary: Boolean;
- begin
- Result := True;
- end;
- { TDynamicType }
- constructor TDynamicType.Create(DestMem, DestPos: PPChar; ASize: PInteger);
- begin
- inherited Create;
- FMemory := DestMem;
- FMemoryPos := DestPos;
- FSize := ASize;
- end;
- procedure TDynamicType.Rewind;
- begin
- FMemoryPos^ := FMemory^;
- end;
- procedure TDynamicType.AssureSpace(ASize: Integer);
- begin
- // need more memory?
- if ((FMemoryPos^) - (FMemory^) + ASize) > (FSize^) then
- Resize((FMemoryPos^) - (FMemory^) + ASize, False);
- end;
- procedure TDynamicType.Resize(NewSize: Integer; Exact: Boolean);
- var
- tempBuf: PChar;
- bytesCopy, pos: Integer;
- begin
- // if not exact requested make newlength a multiple of ArgAllocSize
- if not Exact then
- NewSize := NewSize div ArgAllocSize * ArgAllocSize + ArgAllocSize;
- // create new buffer
- GetMem(tempBuf, NewSize);
- // copy memory
- bytesCopy := FSize^;
- if bytesCopy > NewSize then
- bytesCopy := NewSize;
- Move(FMemory^^, tempBuf^, bytesCopy);
- // save position in string
- pos := FMemoryPos^ - FMemory^;
- // delete old mem
- FreeMem(FMemory^);
- // assign new
- FMemory^ := tempBuf;
- FSize^ := NewSize;
- // assign position
- FMemoryPos^ := FMemory^ + pos;
- end;
- procedure TDynamicType.Append(Source: PChar; Length: Integer);
- begin
- // make room for string plus null-terminator
- AssureSpace(Length+4);
- // copy
- Move(Source^, FMemoryPos^^, Length);
- Inc(FMemoryPos^, Length);
- // null-terminate
- FMemoryPos^^ := #0;
- end;
- procedure TDynamicType.AppendInteger(Source: Integer);
- begin
- // make room for number
- AssureSpace(12);
- Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^));
- FMemoryPos^^ := #0;
- end;
- end.
|