dbf_prsdef.pas 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. unit dbf_prsdef;
  2. interface
  3. {$I dbf_common.inc}
  4. uses
  5. SysUtils,
  6. Classes,
  7. Db,
  8. dbf_prssupp;
  9. const
  10. MaxArg = 6;
  11. ArgAllocSize = 32;
  12. type
  13. TExpressionType = (etInteger, etString, etBoolean, etLargeInt, etFloat, etDateTime,
  14. etLeftBracket, etRightBracket, etComma, etUnknown);
  15. PPChar = ^PChar;
  16. PBoolean = ^Boolean;
  17. PInteger = ^Integer;
  18. PDateTime = ^TDateTime;
  19. EParserException = class(Exception);
  20. PExpressionRec = ^TExpressionRec;
  21. PDynamicType = ^TDynamicType;
  22. PDateTimeRec = ^TDateTimeRec;
  23. {$ifdef SUPPORT_INT64}
  24. PLargeInt = ^Int64;
  25. {$endif}
  26. TExprWord = class;
  27. TExprFunc = procedure(Expr: PExpressionRec);
  28. //-----
  29. TDynamicType = class(TObject)
  30. private
  31. FMemory: PPChar;
  32. FMemoryPos: PPChar;
  33. FSize: PInteger;
  34. public
  35. constructor Create(DestMem, DestPos: PPChar; ASize: PInteger);
  36. procedure AssureSpace(ASize: Integer);
  37. procedure Resize(NewSize: Integer; Exact: Boolean);
  38. procedure Rewind;
  39. procedure Append(Source: PChar; Length: Integer);
  40. procedure AppendInteger(Source: Integer);
  41. property Memory: PPChar read FMemory;
  42. property MemoryPos: PPChar read FMemoryPos;
  43. property Size: PInteger read FSize;
  44. end;
  45. TExpressionRec = record
  46. //used both as linked tree and linked list for maximum evaluation efficiency
  47. Oper: TExprFunc;
  48. Next: PExpressionRec;
  49. Res: TDynamicType;
  50. ExprWord: TExprWord;
  51. AuxData: pointer;
  52. ResetDest: boolean;
  53. WantsFunction: boolean;
  54. Args: array[0..MaxArg-1] of PChar;
  55. ArgsPos: array[0..MaxArg-1] of PChar;
  56. ArgsSize: array[0..MaxArg-1] of Integer;
  57. ArgsType: array[0..MaxArg-1] of TExpressionType;
  58. ArgList: array[0..MaxArg-1] of PExpressionRec;
  59. end;
  60. TExprCollection = class(TNoOwnerCollection)
  61. public
  62. procedure Check;
  63. procedure EraseExtraBrackets;
  64. end;
  65. TExprWordRec = record
  66. Name: PChar;
  67. ShortName: PChar;
  68. IsOperator: Boolean;
  69. IsVariable: Boolean;
  70. IsFunction: Boolean;
  71. NeedsCopy: Boolean;
  72. FixedLen: Boolean;
  73. CanVary: Boolean;
  74. ResultType: TExpressionType;
  75. MinArg: Integer;
  76. MaxArg: Integer;
  77. TypeSpec: PChar;
  78. Description: PChar;
  79. ExprFunc: TExprFunc;
  80. end;
  81. TExprWord = class(TObject)
  82. private
  83. FName: string;
  84. FExprFunc: TExprFunc;
  85. protected
  86. FRefCount: Cardinal;
  87. function GetIsOperator: Boolean; virtual;
  88. function GetIsVariable: Boolean;
  89. function GetNeedsCopy: Boolean;
  90. function GetFixedLen: Integer; virtual;
  91. function GetCanVary: Boolean; virtual;
  92. function GetResultType: TExpressionType; virtual;
  93. function GetMinFunctionArg: Integer; virtual;
  94. function GetMaxFunctionArg: Integer; virtual;
  95. function GetDescription: string; virtual;
  96. function GetTypeSpec: string; virtual;
  97. function GetShortName: string; virtual;
  98. procedure SetFixedLen(NewLen: integer); virtual;
  99. public
  100. constructor Create(AName: string; AExprFunc: TExprFunc);
  101. function LenAsPointer: PInteger; virtual;
  102. function AsPointer: PChar; virtual;
  103. function IsFunction: Boolean; virtual;
  104. property ExprFunc: TExprFunc read FExprFunc;
  105. property IsOperator: Boolean read GetIsOperator;
  106. property CanVary: Boolean read GetCanVary;
  107. property IsVariable: Boolean read GetIsVariable;
  108. property NeedsCopy: Boolean read GetNeedsCopy;
  109. property FixedLen: Integer read GetFixedLen write SetFixedLen;
  110. property ResultType: TExpressionType read GetResultType;
  111. property MinFunctionArg: Integer read GetMinFunctionArg;
  112. property MaxFunctionArg: Integer read GetMaxFunctionArg;
  113. property Name: string read FName;
  114. property ShortName: string read GetShortName;
  115. property Description: string read GetDescription;
  116. property TypeSpec: string read GetTypeSpec;
  117. end;
  118. TExpressShortList = class(TSortedCollection)
  119. public
  120. function KeyOf(Item: Pointer): Pointer; override;
  121. function Compare(Key1, Key2: Pointer): Integer; override;
  122. procedure FreeItem(Item: Pointer); override;
  123. end;
  124. TExpressList = class(TSortedCollection)
  125. private
  126. FShortList: TExpressShortList;
  127. public
  128. constructor Create;
  129. destructor Destroy; override;
  130. procedure Add(Item: Pointer); override;
  131. function KeyOf(Item: Pointer): Pointer; override;
  132. function Compare(Key1, Key2: Pointer): Integer; override;
  133. function Search(Key: Pointer; var Index: Integer): Boolean; override;
  134. procedure FreeItem(Item: Pointer); override;
  135. end;
  136. TConstant = class(TExprWord)
  137. private
  138. FResultType: TExpressionType;
  139. protected
  140. function GetResultType: TExpressionType; override;
  141. public
  142. constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
  143. end;
  144. TFloatConstant = class(TConstant)
  145. private
  146. FValue: Double;
  147. public
  148. // not overloaded to support older Delphi versions
  149. constructor Create(AName: string; AValue: string);
  150. constructor CreateAsDouble(AName: string; AValue: Double);
  151. function AsPointer: PChar; override;
  152. property Value: Double read FValue write FValue;
  153. end;
  154. TUserConstant = class(TFloatConstant)
  155. private
  156. FDescription: string;
  157. protected
  158. function GetDescription: string; override;
  159. public
  160. constructor CreateAsDouble(AName, Descr: string; AValue: Double);
  161. end;
  162. TStringConstant = class(TConstant)
  163. private
  164. FValue: string;
  165. public
  166. constructor Create(AValue: string);
  167. function AsPointer: PChar; override;
  168. end;
  169. TIntegerConstant = class(TConstant)
  170. private
  171. FValue: Integer;
  172. public
  173. constructor Create(AValue: Integer);
  174. function AsPointer: PChar; override;
  175. end;
  176. TBooleanConstant = class(TConstant)
  177. private
  178. FValue: Boolean;
  179. public
  180. // not overloaded to support older Delphi versions
  181. constructor Create(AName: string; AValue: Boolean);
  182. function AsPointer: PChar; override;
  183. property Value: Boolean read FValue write FValue;
  184. end;
  185. TVariable = class(TExprWord)
  186. private
  187. FResultType: TExpressionType;
  188. protected
  189. function GetCanVary: Boolean; override;
  190. function GetResultType: TExpressionType; override;
  191. public
  192. constructor Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
  193. end;
  194. TFloatVariable = class(TVariable)
  195. private
  196. FValue: PDouble;
  197. public
  198. constructor Create(AName: string; AValue: PDouble);
  199. function AsPointer: PChar; override;
  200. end;
  201. TStringVariable = class(TVariable)
  202. private
  203. FValue: PPChar;
  204. FFixedLen: Integer;
  205. protected
  206. function GetFixedLen: Integer; override;
  207. procedure SetFixedLen(NewLen: integer); override;
  208. public
  209. constructor Create(AName: string; AValue: PPChar);
  210. function LenAsPointer: PInteger; override;
  211. function AsPointer: PChar; override;
  212. property FixedLen: Integer read FFixedLen;
  213. end;
  214. TDateTimeVariable = class(TVariable)
  215. private
  216. FValue: PDateTimeRec;
  217. public
  218. constructor Create(AName: string; AValue: PDateTimeRec);
  219. function AsPointer: PChar; override;
  220. end;
  221. TIntegerVariable = class(TVariable)
  222. private
  223. FValue: PInteger;
  224. public
  225. constructor Create(AName: string; AValue: PInteger);
  226. function AsPointer: PChar; override;
  227. end;
  228. {$ifdef SUPPORT_INT64}
  229. TLargeIntVariable = class(TVariable)
  230. private
  231. FValue: PLargeInt;
  232. public
  233. constructor Create(AName: string; AValue: PLargeInt);
  234. function AsPointer: PChar; override;
  235. end;
  236. {$endif}
  237. TBooleanVariable = class(TVariable)
  238. private
  239. FValue: PBoolean;
  240. public
  241. constructor Create(AName: string; AValue: PBoolean);
  242. function AsPointer: PChar; override;
  243. end;
  244. TLeftBracket = class(TExprWord)
  245. function GetResultType: TExpressionType; override;
  246. end;
  247. TRightBracket = class(TExprWord)
  248. protected
  249. function GetResultType: TExpressionType; override;
  250. end;
  251. TComma = class(TExprWord)
  252. protected
  253. function GetResultType: TExpressionType; override;
  254. end;
  255. TFunction = class(TExprWord)
  256. private
  257. FIsOperator: Boolean;
  258. FOperPrec: Integer;
  259. FMinFunctionArg: Integer;
  260. FMaxFunctionArg: Integer;
  261. FDescription: string;
  262. FTypeSpec: string;
  263. FShortName: string;
  264. FResultType: TExpressionType;
  265. protected
  266. function GetDescription: string; override;
  267. function GetIsOperator: Boolean; override;
  268. function GetMinFunctionArg: Integer; override;
  269. function GetMaxFunctionArg: Integer; override;
  270. function GetResultType: TExpressionType; override;
  271. function GetTypeSpec: string; override;
  272. function GetShortName: string; override;
  273. procedure InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
  274. AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer);
  275. public
  276. constructor Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType; AExprFunc: TExprFunc; Descr: string);
  277. constructor CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType; AExprFunc: TExprFunc; AOperPrec: Integer);
  278. function IsFunction: Boolean; override;
  279. property OperPrec: Integer read FOperPrec;
  280. property TypeSpec: string read FTypeSpec;
  281. end;
  282. TVaryingFunction = class(TFunction)
  283. // Functions that can vary for ex. random generators
  284. // should be TVaryingFunction to be sure that they are
  285. // always evaluated
  286. protected
  287. function GetCanVary: Boolean; override;
  288. end;
  289. const
  290. ListChar = ','; {the delimiter used with the 'in' operator: e.g.,
  291. ('a' in 'a,b') =True
  292. ('c' in 'a,b') =False}
  293. function ExprCharToExprType(ExprChar: Char): TExpressionType;
  294. implementation
  295. function ExprCharToExprType(ExprChar: Char): TExpressionType;
  296. begin
  297. case ExprChar of
  298. 'B': Result := etBoolean;
  299. 'I': Result := etInteger;
  300. 'L': Result := etLargeInt;
  301. 'F': Result := etFloat;
  302. 'D': Result := etDateTime;
  303. 'S': Result := etString;
  304. else
  305. Result := etUnknown;
  306. end;
  307. end;
  308. procedure _FloatVariable(Param: PExpressionRec);
  309. begin
  310. with Param^ do
  311. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^;
  312. end;
  313. procedure _BooleanVariable(Param: PExpressionRec);
  314. begin
  315. with Param^ do
  316. PBoolean(Res.MemoryPos^)^ := PBoolean(Args[0])^;
  317. end;
  318. procedure _StringConstant(Param: PExpressionRec);
  319. begin
  320. with Param^ do
  321. Res.Append(Args[0], StrLen(Args[0]));
  322. end;
  323. procedure _StringVariable(Param: PExpressionRec);
  324. var
  325. length: integer;
  326. begin
  327. with Param^ do
  328. begin
  329. length := PInteger(Args[1])^;
  330. if length = -1 then
  331. length := StrLen(PPChar(Args[0])^);
  332. Res.Append(PPChar(Args[0])^, length);
  333. end;
  334. end;
  335. procedure _DateTimeVariable(Param: PExpressionRec);
  336. begin
  337. with Param^ do
  338. PDateTimeRec(Res.MemoryPos^)^ := PDateTimeRec(Args[0])^;
  339. end;
  340. procedure _IntegerVariable(Param: PExpressionRec);
  341. begin
  342. with Param^ do
  343. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^;
  344. end;
  345. {
  346. procedure _SmallIntVariable(Param: PExpressionRec);
  347. begin
  348. with Param^ do
  349. PSmallInt(Res.MemoryPos^)^ := PSmallInt(Args[0])^;
  350. end;
  351. }
  352. {$ifdef SUPPORT_INT64}
  353. procedure _LargeIntVariable(Param: PExpressionRec);
  354. begin
  355. with Param^ do
  356. PLargeInt(Res.MemoryPos^)^ := PLargeInt(Args[0])^;
  357. end;
  358. {$endif}
  359. { TExpressionWord }
  360. constructor TExprWord.Create(AName: string; AExprFunc: TExprFunc);
  361. begin
  362. FName := AName;
  363. FExprFunc := AExprFunc;
  364. end;
  365. function TExprWord.GetCanVary: Boolean;
  366. begin
  367. Result := False;
  368. end;
  369. function TExprWord.GetDescription: string;
  370. begin
  371. Result := EmptyStr;
  372. end;
  373. function TExprWord.GetShortName: string;
  374. begin
  375. Result := EmptyStr;
  376. end;
  377. function TExprWord.GetIsOperator: Boolean;
  378. begin
  379. Result := False;
  380. end;
  381. function TExprWord.GetIsVariable: Boolean;
  382. begin
  383. // delphi wants to call the function pointed to by the variable, use '@'
  384. // fpc simply returns pointer to function, no '@' needed
  385. Result := (@FExprFunc = @_StringVariable) or
  386. (@FExprFunc = @_StringConstant) or
  387. (@FExprFunc = @_FloatVariable) or
  388. (@FExprFunc = @_IntegerVariable) or
  389. // (FExprFunc = @_SmallIntVariable) or
  390. {$ifdef SUPPORT_INT64}
  391. (@FExprFunc = @_LargeIntVariable) or
  392. {$endif}
  393. (@FExprFunc = @_DateTimeVariable) or
  394. (@FExprFunc = @_BooleanVariable);
  395. end;
  396. function TExprWord.GetNeedsCopy: Boolean;
  397. begin
  398. Result := (@FExprFunc <> @_StringConstant) and
  399. // (@FExprFunc <> @_StringVariable) and
  400. // (@FExprFunc <> @_StringVariableFixedLen) and
  401. // string variable cannot be used as normal parameter
  402. // because it is indirectly referenced and possibly
  403. // not null-terminated (fixed len)
  404. (@FExprFunc <> @_FloatVariable) and
  405. (@FExprFunc <> @_IntegerVariable) and
  406. // (FExprFunc <> @_SmallIntVariable) and
  407. {$ifdef SUPPORT_INT64}
  408. (@FExprFunc <> @_LargeIntVariable) and
  409. {$endif}
  410. (@FExprFunc <> @_DateTimeVariable) and
  411. (@FExprFunc <> @_BooleanVariable);
  412. end;
  413. function TExprWord.GetFixedLen: Integer;
  414. begin
  415. // -1 means variable, non-fixed length
  416. Result := -1;
  417. end;
  418. function TExprWord.GetMinFunctionArg: Integer;
  419. begin
  420. Result := 0;
  421. end;
  422. function TExprWord.GetMaxFunctionArg: Integer;
  423. begin
  424. Result := 0;
  425. end;
  426. function TExprWord.GetResultType: TExpressionType;
  427. begin
  428. Result := etUnknown;
  429. end;
  430. function TExprWord.GetTypeSpec: string;
  431. begin
  432. Result := EmptyStr;
  433. end;
  434. function TExprWord.AsPointer: PChar;
  435. begin
  436. Result := nil;
  437. end;
  438. function TExprWord.LenAsPointer: PInteger;
  439. begin
  440. Result := nil;
  441. end;
  442. function TExprWord.IsFunction: Boolean;
  443. begin
  444. Result := False;
  445. end;
  446. procedure TExprWord.SetFixedLen(NewLen: integer);
  447. begin
  448. end;
  449. { TConstant }
  450. constructor TConstant.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
  451. begin
  452. inherited Create(AName, AExprFunc);
  453. FResultType := AVarType;
  454. end;
  455. function TConstant.GetResultType: TExpressionType;
  456. begin
  457. Result := FResultType;
  458. end;
  459. { TFloatConstant }
  460. constructor TFloatConstant.Create(AName, AValue: string);
  461. begin
  462. inherited Create(AName, etFloat, _FloatVariable);
  463. if Length(AValue) > 0 then
  464. FValue := StrToFloat(AValue)
  465. else
  466. FValue := 0.0;
  467. end;
  468. constructor TFloatConstant.CreateAsDouble(AName: string; AValue: Double);
  469. begin
  470. inherited Create(AName, etFloat, _FloatVariable);
  471. FValue := AValue;
  472. end;
  473. function TFloatConstant.AsPointer: PChar;
  474. begin
  475. Result := PChar(@FValue);
  476. end;
  477. { TUserConstant }
  478. constructor TUserConstant.CreateAsDouble(AName, Descr: string; AValue: Double);
  479. begin
  480. FDescription := Descr;
  481. inherited CreateAsDouble(AName, AValue);
  482. end;
  483. function TUserConstant.GetDescription: string;
  484. begin
  485. Result := FDescription;
  486. end;
  487. { TStringConstant }
  488. constructor TStringConstant.Create(AValue: string);
  489. var
  490. firstChar, lastChar: Char;
  491. begin
  492. inherited Create(AValue, etString, _StringConstant);
  493. firstChar := AValue[1];
  494. lastChar := AValue[Length(AValue)];
  495. if (firstChar = lastChar) and ((firstChar = '''') or (firstChar = '"')) then
  496. FValue := Copy(AValue, 2, Length(AValue) - 2)
  497. else
  498. FValue := AValue;
  499. end;
  500. function TStringConstant.AsPointer: PChar;
  501. begin
  502. Result := PChar(FValue);
  503. end;
  504. { TBooleanConstant }
  505. constructor TBooleanConstant.Create(AName: string; AValue: Boolean);
  506. begin
  507. inherited Create(AName, etBoolean, _BooleanVariable);
  508. FValue := AValue;
  509. end;
  510. function TBooleanConstant.AsPointer: PChar;
  511. begin
  512. Result := PChar(@FValue);
  513. end;
  514. { TIntegerConstant }
  515. constructor TIntegerConstant.Create(AValue: Integer);
  516. begin
  517. inherited Create(IntToStr(AValue), etInteger, _IntegerVariable);
  518. FValue := AValue;
  519. end;
  520. function TIntegerConstant.AsPointer: PChar;
  521. begin
  522. Result := PChar(@FValue);
  523. end;
  524. { TVariable }
  525. constructor TVariable.Create(AName: string; AVarType: TExpressionType; AExprFunc: TExprFunc);
  526. begin
  527. inherited Create(AName, AExprFunc);
  528. FResultType := AVarType;
  529. end;
  530. function TVariable.GetCanVary: Boolean;
  531. begin
  532. Result := True;
  533. end;
  534. function TVariable.GetResultType: TExpressionType;
  535. begin
  536. Result := FResultType;
  537. end;
  538. { TFloatVariable }
  539. constructor TFloatVariable.Create(AName: string; AValue: PDouble);
  540. begin
  541. inherited Create(AName, etFloat, _FloatVariable);
  542. FValue := AValue;
  543. end;
  544. function TFloatVariable.AsPointer: PChar;
  545. begin
  546. Result := PChar(FValue);
  547. end;
  548. { TStringVariable }
  549. constructor TStringVariable.Create(AName: string; AValue: PPChar);
  550. begin
  551. // variable or fixed length?
  552. inherited Create(AName, etString, _StringVariable);
  553. // store pointer to string
  554. FValue := AValue;
  555. FFixedLen := -1;
  556. end;
  557. function TStringVariable.AsPointer: PChar;
  558. begin
  559. Result := PChar(FValue);
  560. end;
  561. function TStringVariable.GetFixedLen: Integer;
  562. begin
  563. Result := FFixedLen;
  564. end;
  565. function TStringVariable.LenAsPointer: PInteger;
  566. begin
  567. Result := @FFixedLen;
  568. end;
  569. procedure TStringVariable.SetFixedLen(NewLen: integer);
  570. begin
  571. FFixedLen := NewLen;
  572. end;
  573. { TDateTimeVariable }
  574. constructor TDateTimeVariable.Create(AName: string; AValue: PDateTimeRec);
  575. begin
  576. inherited Create(AName, etDateTime, _DateTimeVariable);
  577. FValue := AValue;
  578. end;
  579. function TDateTimeVariable.AsPointer: PChar;
  580. begin
  581. Result := PChar(FValue);
  582. end;
  583. { TIntegerVariable }
  584. constructor TIntegerVariable.Create(AName: string; AValue: PInteger);
  585. begin
  586. inherited Create(AName, etInteger, _IntegerVariable);
  587. FValue := AValue;
  588. end;
  589. function TIntegerVariable.AsPointer: PChar;
  590. begin
  591. Result := PChar(FValue);
  592. end;
  593. {$ifdef SUPPORT_INT64}
  594. { TLargeIntVariable }
  595. constructor TLargeIntVariable.Create(AName: string; AValue: PLargeInt);
  596. begin
  597. inherited Create(AName, etLargeInt, _LargeIntVariable);
  598. FValue := AValue;
  599. end;
  600. function TLargeIntVariable.AsPointer: PChar;
  601. begin
  602. Result := PChar(FValue);
  603. end;
  604. {$endif}
  605. { TBooleanVariable }
  606. constructor TBooleanVariable.Create(AName: string; AValue: PBoolean);
  607. begin
  608. inherited Create(AName, etBoolean, _BooleanVariable);
  609. FValue := AValue;
  610. end;
  611. function TBooleanVariable.AsPointer: PChar;
  612. begin
  613. Result := PChar(FValue);
  614. end;
  615. { TLeftBracket }
  616. function TLeftBracket.GetResultType: TExpressionType;
  617. begin
  618. Result := etLeftBracket;
  619. end;
  620. { TRightBracket }
  621. function TRightBracket.GetResultType: TExpressionType;
  622. begin
  623. Result := etRightBracket;
  624. end;
  625. { TComma }
  626. function TComma.GetResultType: TExpressionType;
  627. begin
  628. Result := etComma;
  629. end;
  630. { TExpressList }
  631. constructor TExpressList.Create;
  632. begin
  633. inherited;
  634. FShortList := TExpressShortList.Create;
  635. end;
  636. destructor TExpressList.Destroy;
  637. begin
  638. inherited;
  639. FShortList.Free;
  640. end;
  641. procedure TExpressList.Add(Item: Pointer);
  642. var
  643. I: Integer;
  644. begin
  645. inherited;
  646. { remember we reference the object }
  647. Inc(TExprWord(Item).FRefCount);
  648. { also add ShortName as reference }
  649. if Length(TExprWord(Item).ShortName) > 0 then
  650. begin
  651. FShortList.Search(FShortList.KeyOf(Item), I);
  652. FShortList.Insert(I, Item);
  653. end;
  654. end;
  655. function TExpressList.Compare(Key1, Key2: Pointer): Integer;
  656. begin
  657. Result := StrIComp(PChar(Key1), PChar(Key2));
  658. end;
  659. function TExpressList.KeyOf(Item: Pointer): Pointer;
  660. begin
  661. Result := PChar(TExprWord(Item).Name);
  662. end;
  663. procedure TExpressList.FreeItem(Item: Pointer);
  664. begin
  665. Dec(TExprWord(Item).FRefCount);
  666. FShortList.Remove(Item);
  667. if TExprWord(Item).FRefCount = 0 then
  668. inherited;
  669. end;
  670. function TExpressList.Search(Key: Pointer; var Index: Integer): Boolean;
  671. var
  672. SecIndex: Integer;
  673. begin
  674. Result := inherited Search(Key, Index);
  675. if not Result then
  676. begin
  677. Result := FShortList.Search(Key, SecIndex);
  678. if Result then
  679. Index := IndexOf(FShortList.Items[SecIndex]);
  680. end;
  681. end;
  682. function TExpressShortList.Compare(Key1, Key2: Pointer): Integer;
  683. begin
  684. Result := StrIComp(PChar(Key1), PChar(Key2));
  685. end;
  686. function TExpressShortList.KeyOf(Item: Pointer): Pointer;
  687. begin
  688. Result := PChar(TExprWord(Item).ShortName);
  689. end;
  690. procedure TExpressShortList.FreeItem(Item: Pointer);
  691. begin
  692. end;
  693. { TExprCollection }
  694. procedure TExprCollection.Check;
  695. var
  696. brCount, I: Integer;
  697. begin
  698. brCount := 0;
  699. for I := 0 to Count - 1 do
  700. begin
  701. case TExprWord(Items[I]).ResultType of
  702. etLeftBracket: Inc(brCount);
  703. etRightBracket: Dec(brCount);
  704. end;
  705. end;
  706. if brCount <> 0 then
  707. raise EParserException.Create('Unequal brackets');
  708. end;
  709. procedure TExprCollection.EraseExtraBrackets;
  710. var
  711. I: Integer;
  712. brCount: Integer;
  713. begin
  714. if (TExprWord(Items[0]).ResultType = etLeftBracket) then
  715. begin
  716. brCount := 1;
  717. I := 1;
  718. while (I < Count) and (brCount > 0) do
  719. begin
  720. case TExprWord(Items[I]).ResultType of
  721. etLeftBracket: Inc(brCount);
  722. etRightBracket: Dec(brCount);
  723. end;
  724. Inc(I);
  725. end;
  726. if (brCount = 0) and (I = Count) and (TExprWord(Items[I - 1]).ResultType =
  727. etRightBracket) then
  728. begin
  729. for I := 0 to Count - 3 do
  730. Items[I] := Items[I + 1];
  731. Count := Count - 2;
  732. EraseExtraBrackets; //Check if there are still too many brackets
  733. end;
  734. end;
  735. end;
  736. { TFunction }
  737. constructor TFunction.Create(AName, AShortName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
  738. AExprFunc: TExprFunc; Descr: string);
  739. begin
  740. //to increase compatibility don't use default parameters
  741. FDescription := Descr;
  742. FShortName := AShortName;
  743. InternalCreate(AName, ATypeSpec, AMinFuncArg, AResultType, AExprFunc, false, 0);
  744. end;
  745. constructor TFunction.CreateOper(AName, ATypeSpec: string; AResultType: TExpressionType;
  746. AExprFunc: TExprFunc; AOperPrec: Integer);
  747. begin
  748. InternalCreate(AName, ATypeSpec, -1, AResultType, AExprFunc, true, AOperPrec);
  749. end;
  750. procedure TFunction.InternalCreate(AName, ATypeSpec: string; AMinFuncArg: Integer; AResultType: TExpressionType;
  751. AExprFunc: TExprFunc; AIsOperator: Boolean; AOperPrec: Integer);
  752. begin
  753. inherited Create(AName, AExprFunc);
  754. FMaxFunctionArg := Length(ATypeSpec);
  755. FMinFunctionArg := AMinFuncArg;
  756. if AMinFuncArg = -1 then
  757. FMinFunctionArg := FMaxFunctionArg;
  758. FIsOperator := AIsOperator;
  759. FOperPrec := AOperPrec;
  760. FTypeSpec := ATypeSpec;
  761. FResultType := AResultType;
  762. // check correctness
  763. if FMaxFunctionArg > MaxArg then
  764. raise EParserException.Create('Too many arguments');
  765. end;
  766. function TFunction.GetDescription: string;
  767. begin
  768. Result := FDescription;
  769. end;
  770. function TFunction.GetIsOperator: Boolean;
  771. begin
  772. Result := FIsOperator;
  773. end;
  774. function TFunction.GetMinFunctionArg: Integer;
  775. begin
  776. Result := FMinFunctionArg;
  777. end;
  778. function TFunction.GetMaxFunctionArg: Integer;
  779. begin
  780. Result := FMaxFunctionArg;
  781. end;
  782. function TFunction.GetResultType: TExpressionType;
  783. begin
  784. Result := FResultType;
  785. end;
  786. function TFunction.GetShortName: string;
  787. begin
  788. Result := FShortName;
  789. end;
  790. function TFunction.GetTypeSpec: string;
  791. begin
  792. Result := FTypeSpec;
  793. end;
  794. function TFunction.IsFunction: Boolean;
  795. begin
  796. Result := True;
  797. end;
  798. { TVaryingFunction }
  799. function TVaryingFunction.GetCanVary: Boolean;
  800. begin
  801. Result := True;
  802. end;
  803. { TDynamicType }
  804. constructor TDynamicType.Create(DestMem, DestPos: PPChar; ASize: PInteger);
  805. begin
  806. inherited Create;
  807. FMemory := DestMem;
  808. FMemoryPos := DestPos;
  809. FSize := ASize;
  810. end;
  811. procedure TDynamicType.Rewind;
  812. begin
  813. FMemoryPos^ := FMemory^;
  814. end;
  815. procedure TDynamicType.AssureSpace(ASize: Integer);
  816. begin
  817. // need more memory?
  818. if ((FMemoryPos^) - (FMemory^) + ASize) > (FSize^) then
  819. Resize((FMemoryPos^) - (FMemory^) + ASize, False);
  820. end;
  821. procedure TDynamicType.Resize(NewSize: Integer; Exact: Boolean);
  822. var
  823. tempBuf: PChar;
  824. bytesCopy, pos: Integer;
  825. begin
  826. // if not exact requested make newlength a multiple of ArgAllocSize
  827. if not Exact then
  828. NewSize := NewSize div ArgAllocSize * ArgAllocSize + ArgAllocSize;
  829. // create new buffer
  830. GetMem(tempBuf, NewSize);
  831. // copy memory
  832. bytesCopy := FSize^;
  833. if bytesCopy > NewSize then
  834. bytesCopy := NewSize;
  835. Move(FMemory^^, tempBuf^, bytesCopy);
  836. // save position in string
  837. pos := FMemoryPos^ - FMemory^;
  838. // delete old mem
  839. FreeMem(FMemory^);
  840. // assign new
  841. FMemory^ := tempBuf;
  842. FSize^ := NewSize;
  843. // assign position
  844. FMemoryPos^ := FMemory^ + pos;
  845. end;
  846. procedure TDynamicType.Append(Source: PChar; Length: Integer);
  847. begin
  848. // make room for string plus null-terminator
  849. AssureSpace(Length+4);
  850. // copy
  851. Move(Source^, FMemoryPos^^, Length);
  852. Inc(FMemoryPos^, Length);
  853. // null-terminate
  854. FMemoryPos^^ := #0;
  855. end;
  856. procedure TDynamicType.AppendInteger(Source: Integer);
  857. begin
  858. // make room for number
  859. AssureSpace(12);
  860. Inc(FMemoryPos^, GetStrFromInt(Source, FMemoryPos^));
  861. FMemoryPos^^ := #0;
  862. end;
  863. end.