123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044 |
- unit dbf_prsdef;
- interface
- {$I dbf_common.inc}
- uses
- SysUtils,
- Classes,
- dbf_common,
- 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;
- 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;
- 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;
- 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;
- 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;
- public
- constructor Create(AName: string; AValue: PPChar; AFixedLen: Integer);
- 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);
- begin
- with Param^ do
- Res.Append(PPChar(Args[0])^, StrLen(PPChar(Args[0])^));
- end;
- procedure _StringVariableFixedLen(Param: PExpressionRec);
- begin
- with Param^ do
- Res.Append(PPChar(Args[0])^, PInteger(Args[1])^);
- 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 = @_StringVariableFixedLen) 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;
- { 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; AFixedLen: Integer);
- begin
- // variable or fixed length?
- if (AFixedLen < 0) then
- inherited Create(AName, etString, _StringVariable)
- else
- inherited Create(AName, etString, _StringVariableFixedLen);
- // store pointer to string
- FValue := AValue;
- FFixedLen := AFixedLen;
- 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;
- { 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.
|