tcexprparser.pas 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149
  1. unit tcexprparser;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, fpcunit, testregistry, tcbaseparser, pastree;
  6. type
  7. { TTestExpressions }
  8. TTestExpressions= class(TTestParser)
  9. private
  10. FLeft: TPAsExpr;
  11. FRight: TPAsExpr;
  12. FTheExpr: TPasExpr;
  13. FVariables : TStringList;
  14. procedure AssertLeftPrecedence(AInnerLeft: Integer; AInnerOp: TExprOpCode;
  15. AInnerRight: Integer; AOuterOp: TexprOpCode; AOuterRight: Integer);
  16. procedure AssertRightPrecedence(AOuterLeft: Integer; AOuterOp: TExprOpCode;
  17. AInnerLeft: Integer; AInnerOp: TexprOpCode; AInnerRight: Integer);
  18. procedure DeclareVar(const AVarType: String; const AVarName: String = 'a');
  19. protected
  20. procedure SetUp; override;
  21. procedure TearDown; override;
  22. Procedure SetExpression(Const AExpression : String);
  23. Procedure ParseExpression;
  24. Procedure ParseExpression(Const AExpression : String);
  25. Function AssertBinaryExpr(Const Msg : String; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
  26. Function AssertBinaryExpr(Const Msg : String; AExpr : TPasExpr; Op : TExprOpCode; Out ALeft,ARight : TPasExpr) : TBinaryExpr;
  27. Function AssertUnaryExpr(Const Msg : String; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
  28. Function AssertUnaryExpr(Const Msg : String; AExpr: TPasExpr; Op : TExprOpCode; Out AOperand : TPasExpr) : TUnaryExpr;
  29. Property TheExpr : TPasExpr read FTheExpr;
  30. Property Theleft : TPAsExpr Read FLeft;
  31. Property TheRight : TPAsExpr Read FRight;
  32. published
  33. {
  34. TPasExprKind = (pekRange,
  35. pekListOfExp, );
  36. }
  37. procedure TestPrimitiveInteger;
  38. procedure TestPrimitiveIntegerHex;
  39. procedure TestPrimitiveIntegerOctal;
  40. procedure TestPrimitiveIntegerBinary;
  41. procedure TestPrimitiveDouble;
  42. procedure TestPrimitiveDouble2;
  43. procedure TestPrimitiveDouble3;
  44. procedure TestPrimitiveDouble4;
  45. procedure TestPrimitiveDouble5;
  46. procedure TestPrimitiveDouble6;
  47. procedure TestPrimitiveDouble7;
  48. procedure TestPrimitiveDouble8;
  49. procedure TestPrimitiveDouble9;
  50. procedure TestPrimitiveDouble10;
  51. procedure TestPrimitiveDouble11;
  52. procedure TestPrimitiveString;
  53. procedure TestPrimitiveIdent;
  54. procedure TestPrimitiveBooleanFalse;
  55. procedure TestPrimitiveBooleanTrue;
  56. procedure TestPrimitiveNil;
  57. procedure TestPrimitiveSet;
  58. procedure TestPrimitiveChar;
  59. procedure TestPrimitiveControlChar;
  60. procedure TestPrimitiveSetEmpty;
  61. procedure TestPrimitiveSelf;
  62. Procedure TestInherited;
  63. Procedure TestInheritedFunction;
  64. Procedure TestUnaryMinus;
  65. Procedure TestUnaryMinusWhiteSpace;
  66. Procedure TestUnaryAddress;
  67. Procedure TestUnaryNot;
  68. Procedure TestUnaryDeref;
  69. Procedure TestUnaryDoubleDeref;
  70. Procedure TestUnaryDoubleDeref2;
  71. Procedure TestBinaryAdd;
  72. Procedure TestBinarySubtract;
  73. Procedure TestBinaryMultiply;
  74. Procedure TestBinaryDivision;
  75. Procedure TestBinaryPower;
  76. Procedure TestBinaryMod;
  77. Procedure TestBinaryDiv;
  78. procedure TestBinaryShl;
  79. procedure TestBinaryShr;
  80. Procedure TestBinarySymmetricalDifference;
  81. Procedure TestBinaryAnd;
  82. Procedure TestBinaryOr;
  83. Procedure TestBinaryXOr;
  84. Procedure TestBinaryIn;
  85. Procedure TestBinaryIs;
  86. Procedure TestBinaryAs;
  87. Procedure TestBinaryEquals;
  88. Procedure TestBinaryDiffers;
  89. Procedure TestBinaryLessThan;
  90. Procedure TestBinaryLessThanEqual;
  91. Procedure TestBinaryLargerThan;
  92. Procedure TestBinaryLargerThanEqual;
  93. procedure TestBinaryFullIdent;
  94. Procedure TestArrayElement;
  95. Procedure TestArrayElementrecord;
  96. Procedure TestArrayElement2Dims;
  97. Procedure TestFunctionCall;
  98. Procedure TestFunctionCall2args;
  99. Procedure TestFunctionCallNoArgs;
  100. Procedure ParseStrWithFormatFullyQualified;
  101. Procedure TestRange;
  102. Procedure TestBracketsTotal;
  103. Procedure TestBracketsLeft;
  104. Procedure TestBracketsRight;
  105. Procedure TestPrecedenceLeftToRight;
  106. Procedure TestPrecedenceLeftToRightMinus;
  107. Procedure TestPrecedenceLeftToRightMultiply;
  108. Procedure TestPrecedenceLeftToRightDivision;
  109. Procedure TestPrecedenceLeftToRightPlusMinus;
  110. Procedure TestPrecedenceLeftToRightMinusPlus;
  111. Procedure TestPrecedenceLeftToRightMultiplyDivision;
  112. Procedure TestPrecedenceLeftToRightDivisionMultiply;
  113. Procedure TestPrecedencePlusMultiply;
  114. Procedure TestPrecedencePlusDivide;
  115. Procedure TestPrecedenceMinusMultiply;
  116. Procedure TestPrecedenceMinusDivide;
  117. Procedure TestPrecedencePlusOr;
  118. Procedure TestPrecedenceAndOr;
  119. Procedure TestPrecedenceAndNot;
  120. Procedure TestPrecedencePlusAnd;
  121. Procedure TestPrecedenceMinusOr;
  122. Procedure TestPrecedenceMinusAnd;
  123. Procedure TestPrecedenceMultiplyOr;
  124. Procedure TestPrecedenceMultiplyAnd;
  125. Procedure TestPrecedencePlusDiv;
  126. Procedure TestPrecedencePlusMod;
  127. Procedure TestPrecedenceMultiplyDiv;
  128. Procedure TestPrecedenceDivMultiply;
  129. Procedure TestTypeCast;
  130. procedure TestTypeCast2;
  131. Procedure TestCreate;
  132. procedure TestChainedPointers;
  133. procedure TestChainedPointers2;
  134. procedure TestChainedPointers3;
  135. Procedure TestNilCaret;
  136. Procedure TestExpCaret;
  137. Procedure TestArrayAccess;
  138. Procedure TestHelperOnLiteral;
  139. end;
  140. implementation
  141. procedure TTestExpressions.DeclareVar(const AVarType: String;
  142. const AVarName: String = 'a');
  143. begin
  144. FVariables.Add(AVarName+' : '+AVarType+';');
  145. end;
  146. procedure TTestExpressions.TestPrimitiveInteger;
  147. begin
  148. ParseExpression('1');
  149. AssertExpression('Simple integer',theExpr,pekNumber,'1');
  150. end;
  151. procedure TTestExpressions.TestPrimitiveIntegerHex;
  152. begin
  153. ParseExpression('$FF');
  154. AssertExpression('Simple integer',theExpr,pekNumber,'$FF');
  155. end;
  156. procedure TTestExpressions.TestPrimitiveIntegerOctal;
  157. begin
  158. ParseExpression('&777');
  159. AssertExpression('Simple integer',theExpr,pekNumber,'&777');
  160. end;
  161. procedure TTestExpressions.TestPrimitiveIntegerBinary;
  162. begin
  163. ParseExpression('%10101010');
  164. AssertExpression('Simple integer',theExpr,pekNumber,'%10101010');
  165. end;
  166. procedure TTestExpressions.TestPrimitiveDouble;
  167. begin
  168. ParseExpression('1.2');
  169. AssertExpression('Simple double',theExpr,pekNumber,'1.2');
  170. end;
  171. procedure TTestExpressions.TestPrimitiveDouble2;
  172. begin
  173. ParseExpression('1.200');
  174. AssertExpression('Simple double',theExpr,pekNumber,'1.200');
  175. end;
  176. procedure TTestExpressions.TestPrimitiveDouble3;
  177. begin
  178. ParseExpression('01.2');
  179. AssertExpression('Simple double',theExpr,pekNumber,'01.2');
  180. end;
  181. procedure TTestExpressions.TestPrimitiveDouble4;
  182. begin
  183. ParseExpression('1.2e10');
  184. AssertExpression('Simple double',theExpr,pekNumber,'1.2e10');
  185. end;
  186. procedure TTestExpressions.TestPrimitiveDouble5;
  187. begin
  188. ParseExpression('1.2e-10');
  189. AssertExpression('Simple double',theExpr,pekNumber,'1.2e-10');
  190. end;
  191. procedure TTestExpressions.TestPrimitiveDouble6;
  192. begin
  193. ParseExpression('12e10');
  194. AssertExpression('Simple double',theExpr,pekNumber,'12e10');
  195. end;
  196. procedure TTestExpressions.TestPrimitiveDouble7;
  197. begin
  198. ParseExpression('12e-10');
  199. AssertExpression('Simple double',theExpr,pekNumber,'12e-10');
  200. end;
  201. procedure TTestExpressions.TestPrimitiveDouble8;
  202. begin
  203. ParseExpression('8.5');
  204. AssertExpression('Simple double',theExpr,pekNumber,'8.5');
  205. end;
  206. procedure TTestExpressions.TestPrimitiveDouble9;
  207. begin
  208. ParseExpression('8.E5');
  209. AssertExpression('Simple double',theExpr,pekNumber,'8.E5');
  210. end;
  211. procedure TTestExpressions.TestPrimitiveDouble10;
  212. begin
  213. ParseExpression('8.E-5');
  214. AssertExpression('Simple double',theExpr,pekNumber,'8.E-5');
  215. end;
  216. procedure TTestExpressions.TestPrimitiveDouble11;
  217. begin
  218. ParseExpression('8E+5');
  219. AssertExpression('Simple double',theExpr,pekNumber,'8E+5');
  220. end;
  221. procedure TTestExpressions.TestPrimitiveString;
  222. begin
  223. DeclareVar('string');
  224. ParseExpression('''123''');
  225. AssertExpression('Simple string',theExpr,pekString,'''123''');
  226. end;
  227. procedure TTestExpressions.TestPrimitiveIdent;
  228. begin
  229. DeclareVar('integer','a');
  230. DeclareVar('integer','b');
  231. ParseExpression('b');
  232. AssertExpression('Simple identifier',theExpr,pekIdent,'b');
  233. end;
  234. procedure TTestExpressions.TestBinaryFullIdent;
  235. begin
  236. DeclareVar('integer','a');
  237. DeclareVar('record x,y : integer; end','b');
  238. ParseExpression('b.x');
  239. AssertBinaryExpr('sub identifier',eopSubIdent,Fleft,FRight);
  240. AssertExpression('Simple identifier',Theleft,pekIdent,'b');
  241. AssertExpression('Simple identifier',Theright,pekIdent,'x');
  242. end;
  243. procedure TTestExpressions.TestArrayElement;
  244. Var
  245. P : TParamsExpr;
  246. begin
  247. DeclareVar('integer','a');
  248. DeclareVar('array[1..2] of integer','b');
  249. ParseExpression('b[1]');
  250. P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
  251. AssertExpression('Name of array',P.Value,pekIdent,'b');
  252. AssertEquals('One dimension',1,Length(p.params));
  253. AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
  254. end;
  255. procedure TTestExpressions.TestArrayElementrecord;
  256. Var
  257. P : TParamsExpr;
  258. B : TBinaryExpr;
  259. begin
  260. DeclareVar('record a : array[1..2] of integer; end ','b');
  261. ParseExpression('b.a[1]');
  262. B:=AssertExpression('Binary of record',TheExpr,pekBinary,TBinaryExpr) as TBinaryExpr;
  263. AssertEquals('Name is Subident',eopSubIdent,B.Opcode);
  264. AssertExpression('Name of array',B.Left,pekIdent,'b');
  265. P:=TParamsExpr(AssertExpression('Simple identifier',B.right,pekArrayParams,TParamsExpr));
  266. AssertExpression('Name of array',P.Value,pekIdent,'a');
  267. TAssert.AssertSame('P.value.parent=P',P,P.Value.Parent);
  268. AssertEquals('One dimension',1,Length(P.params));
  269. AssertExpression('Simple identifier',P.params[0],pekNumber,'1');
  270. TAssert.AssertSame('B.left.parent=B',B,B.left.Parent);
  271. TAssert.AssertSame('B.right.parent=B',B,B.right.Parent);
  272. end;
  273. procedure TTestExpressions.TestArrayElement2Dims;
  274. Var
  275. P : TParamsExpr;
  276. begin
  277. DeclareVar('integer','a');
  278. DeclareVar('array[1..2,1..2] of integer','b');
  279. ParseExpression('b[1,2]');
  280. P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekArrayParams,TParamsExpr));
  281. AssertExpression('Name of array',P.Value,pekIdent,'b');
  282. AssertEquals('Two dimensions',2,Length(p.params));
  283. AssertExpression('Simple identifier',p.params[0],pekNumber,'1');
  284. AssertExpression('Simple identifier',p.params[1],pekNumber,'2');
  285. end;
  286. procedure TTestExpressions.TestFunctionCall;
  287. Var
  288. P : TParamsExpr;
  289. begin
  290. DeclareVar('integer','a');
  291. ParseExpression('Random(10)');
  292. P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
  293. AssertExpression('Name of function',P.Value,pekIdent,'Random');
  294. AssertEquals('1 argument',1,Length(p.params));
  295. AssertExpression('Simple identifier',p.params[0],pekNumber,'10');
  296. end;
  297. procedure TTestExpressions.TestFunctionCall2args;
  298. Var
  299. P : TParamsExpr;
  300. begin
  301. DeclareVar('integer','a');
  302. ParseExpression('Random(10,12)');
  303. P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
  304. AssertExpression('Name of function',P.Value,pekIdent,'Random');
  305. AssertEquals('2 argument',2,Length(p.params));
  306. AssertExpression('Simple identifier 1',p.params[0],pekNumber,'10');
  307. AssertExpression('Simple identifier 2',p.params[1],pekNumber,'12');
  308. end;
  309. procedure TTestExpressions.TestFunctionCallNoArgs;
  310. Var
  311. P : TParamsExpr;
  312. begin
  313. DeclareVar('integer','a');
  314. ParseExpression('Random()');
  315. P:=TParamsExpr(AssertExpression('Simple identifier',theExpr,pekFuncParams,TParamsExpr));
  316. AssertExpression('Name of function',P.Value,pekIdent,'Random');
  317. AssertEquals('0 arguments',0,Length(p.params));
  318. end;
  319. procedure TTestExpressions.TestRange;
  320. Var
  321. P : TParamsExpr;
  322. B : TBinaryExpr;
  323. begin
  324. DeclareVar('boolean','a');
  325. DeclareVar('byte','b');
  326. ParseExpression('b in [0..10]');
  327. AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
  328. AssertExpression('Left is b',TheLeft,pekIdent,'b');
  329. P:=TParamsExpr(AssertExpression('Right is set',TheRight,pekSet,TParamsExpr));
  330. AssertEquals('Number of items',1,Length(P.Params));
  331. B:=TBinaryExpr(AssertExpression('First element is range',P.Params[0],pekRange,TBinaryExpr));
  332. AssertExpression('Left is 0',B.Left,pekNumber,'0');
  333. AssertExpression('Right is 10',B.Right,pekNumber,'10');
  334. B:=TBinaryExpr(TheExpr);
  335. TAssert.AssertSame('B.left.parent=B',B,B.left.Parent);
  336. TAssert.AssertSame('B.right.parent=B',B,B.right.Parent);
  337. end;
  338. procedure TTestExpressions.TestBracketsTotal;
  339. begin
  340. DeclareVar('integer','a');
  341. ParseExpression('(3+4)');
  342. AssertBinaryExpr('simple binary add',eopAdd,FLeft,FRight);
  343. AssertExpression('Inner Left is 3',TheLeft,pekNumber,'3');
  344. AssertExpression('Inner Right is 4',TheRight,pekNumber,'4');
  345. end;
  346. procedure TTestExpressions.TestBracketsLeft;
  347. begin
  348. DeclareVar('integer','a');
  349. ParseExpression('2*(3+4)');
  350. AssertRightPrecedence(2,eopMultiply,3,eopAdd,4);
  351. end;
  352. procedure TTestExpressions.TestBracketsRight;
  353. begin
  354. DeclareVar('integer','a');
  355. ParseExpression('(2*3)+4');
  356. AssertLeftPrecedence(2,eopMultiply,3,eopAdd,4);
  357. end;
  358. procedure TTestExpressions.TestPrecedenceLeftToRight;
  359. begin
  360. ParseExpression('1+2+3');
  361. AssertLeftPrecedence(1,eopAdd,2,eopAdd,3);
  362. end;
  363. procedure TTestExpressions.TestPrecedenceLeftToRightMinus;
  364. begin
  365. ParseExpression('1-2-3');
  366. AssertLeftPrecedence(1,eopSubtract,2,eopSubtract,3);
  367. end;
  368. procedure TTestExpressions.TestPrecedenceLeftToRightMultiply;
  369. begin
  370. ParseExpression('1*2*3');
  371. AssertLeftPrecedence(1,eopMultiply,2,eopMultiply,3);
  372. end;
  373. procedure TTestExpressions.TestPrecedenceLeftToRightDivision;
  374. begin
  375. ParseExpression('1/2/3');
  376. AssertLeftPrecedence(1,eopDivide,2,eopDivide,3);
  377. end;
  378. procedure TTestExpressions.TestPrecedenceLeftToRightPlusMinus;
  379. begin
  380. ParseExpression('1+2-3');
  381. AssertLeftPrecedence(1,eopAdd,2,eopSubtract,3);
  382. end;
  383. procedure TTestExpressions.TestPrecedenceLeftToRightMinusPlus;
  384. begin
  385. ParseExpression('1-2+3');
  386. AssertLeftPrecedence(1,eopSubtract,2,eopAdd,3);
  387. end;
  388. procedure TTestExpressions.TestPrecedenceLeftToRightMultiplyDivision;
  389. begin
  390. ParseExpression('1*2/3');
  391. AssertLeftPrecedence(1,eopMultiply,2,eopDivide,3);
  392. end;
  393. procedure TTestExpressions.TestPrecedenceLeftToRightDivisionMultiply;
  394. begin
  395. ParseExpression('1/2*3');
  396. AssertLeftPrecedence(1,eopDivide,2,eopMultiply,3);
  397. end;
  398. procedure TTestExpressions.TestPrecedencePlusMultiply;
  399. begin
  400. ParseExpression('1+2*3');
  401. AssertRightPrecedence(1,eopAdd,2,eopMultiply,3);
  402. end;
  403. procedure TTestExpressions.TestPrecedencePlusDivide;
  404. begin
  405. ParseExpression('1+2/3');
  406. AssertRightPrecedence(1,eopAdd,2,eopDivide,3);
  407. end;
  408. procedure TTestExpressions.TestPrecedenceMinusMultiply;
  409. begin
  410. ParseExpression('1-2*3');
  411. AssertRightPrecedence(1,eopsubtract,2,eopMultiply,3);
  412. end;
  413. procedure TTestExpressions.TestPrecedenceMinusDivide;
  414. begin
  415. ParseExpression('1-2/3');
  416. AssertRightPrecedence(1,eopsubtract,2,eopDivide,3);
  417. end;
  418. procedure TTestExpressions.TestPrecedencePlusOr;
  419. begin
  420. ParseExpression('1 or 2 + 3');
  421. AssertLeftPrecedence(1,eopor,2,eopAdd,3);
  422. end;
  423. procedure TTestExpressions.TestPrecedenceAndOr;
  424. begin
  425. ParseExpression('1 or 2 and 3');
  426. AssertRightPrecedence(1,eopor,2,eopAnd,3);
  427. end;
  428. procedure TTestExpressions.TestPrecedenceAndNot;
  429. begin
  430. ParseExpression('Not 1 and 3');
  431. AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
  432. AssertExpression('Outer right is 3',TheRight,pekNumber,'3');
  433. AssertUnaryExpr('Left is Unary not ',TheLeft,eopNot,FRight);
  434. AssertExpression('Inner Right is 1',TheRight,pekNumber,'1');
  435. end;
  436. procedure TTestExpressions.TestPrecedencePlusAnd;
  437. begin
  438. ParseExpression('1 + 2 and 3');
  439. AssertRightPrecedence(1,eopAdd,2,eopAnd,3);
  440. end;
  441. procedure TTestExpressions.TestPrecedenceMinusOr;
  442. begin
  443. ParseExpression('1 or 2 - 3');
  444. AssertLeftPrecedence(1,eopOr,2,eopSubtract,3);
  445. end;
  446. procedure TTestExpressions.TestPrecedenceMinusAnd;
  447. begin
  448. ParseExpression('1 - 2 and 3');
  449. AssertRightPrecedence(1,eopSubtract,2,eopand,3);
  450. end;
  451. procedure TTestExpressions.TestPrecedenceMultiplyOr;
  452. begin
  453. ParseExpression('1 or 2 * 3');
  454. AssertRightPrecedence(1,eopOr,2,eopMultiply,3);
  455. end;
  456. procedure TTestExpressions.TestPrecedenceMultiplyAnd;
  457. begin
  458. ParseExpression('1 * 2 and 3');
  459. AssertLeftPrecedence(1,eopMultiply,2,eopAnd,3);
  460. end;
  461. procedure TTestExpressions.TestPrecedencePlusDiv;
  462. begin
  463. ParseExpression('1+2 div 3');
  464. AssertRightPrecedence(1,eopAdd,2,eopDiv,3);
  465. end;
  466. procedure TTestExpressions.TestPrecedencePlusMod;
  467. begin
  468. ParseExpression('1+2 mod 3');
  469. AssertRightPrecedence(1,eopAdd,2,eopMod,3);
  470. end;
  471. procedure TTestExpressions.AssertLeftPrecedence(AInnerLeft : Integer; AInnerOp : TExprOpCode; AInnerRight : Integer; AOuterOp : TexprOpCode; AOuterRight: Integer);
  472. begin
  473. AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
  474. AssertExpression('Outer right constant',TheRight,pekNumber,intToStr(AOuterRight));
  475. AssertBinaryExpr('Inner (left) expression',TheLeft,AInnerOp,FLeft,FRight);
  476. AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
  477. AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
  478. end;
  479. procedure TTestExpressions.AssertRightPrecedence(AOuterLeft : Integer; AOuterOp : TExprOpCode; AInnerLeft : Integer; AInnerOp : TexprOpCode; AInnerRight: Integer);
  480. begin
  481. AssertBinaryExpr('Outer expression',AOuterOp,FLeft,FRight);
  482. AssertExpression('Outer left constant',TheLeft,pekNumber,intToStr(AOuterLeft));
  483. AssertBinaryExpr('Inner (right) expression',TheRight,AInnerOp,FLeft,FRight);
  484. AssertExpression('Inner Left constant',TheLeft,pekNumber,IntToStr(AInnerLeft));
  485. AssertExpression('Inner Right constant',TheRight,pekNumber,IntToStr(AInnerRight));
  486. end;
  487. procedure TTestExpressions.TestPrecedenceMultiplyDiv;
  488. begin
  489. ParseExpression('1 * 2 div 3');
  490. AssertLeftPrecedence(1,eopMultiply,2,eopDiv,3);
  491. end;
  492. procedure TTestExpressions.TestPrecedenceDivMultiply;
  493. begin
  494. ParseExpression('1 div 2 * 3');
  495. AssertLeftPrecedence(1,eopDiv,2,eopMultiply,3);
  496. end;
  497. procedure TTestExpressions.TestTypeCast;
  498. begin
  499. DeclareVar('TSDOBaseDataObjectClass');
  500. ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create');
  501. end;
  502. procedure TTestExpressions.TestTypeCast2;
  503. begin
  504. DeclareVar('TSDOBaseDataObjectClass');
  505. ParseExpression('TSDOBaseDataObjectClass(Self.ClassType).Create.D');
  506. end;
  507. procedure TTestExpressions.TestCreate;
  508. begin
  509. DeclareVar('ESDOSerializationException');
  510. ParseExpression('ESDOSerializationException.CreateFmt(SERR_InvalidDataTypeInContext,[IntToStr(Ord(AOwner^.DataType))])');
  511. end;
  512. procedure TTestExpressions.TestChainedPointers;
  513. begin
  514. // From bug report 31719
  515. Source.Add('type');
  516. Source.Add(' PTResourceManager=^TResourceManager;');
  517. Source.Add(' TResourceManager=object');
  518. Source.Add(' function LoadResourceFromFile(filename:string):PTResourceManager;');
  519. Source.Add(' end;');
  520. Source.Add(' function TResourceManager.LoadResourceFromFile(filename:string):PTResourceManager;');
  521. Source.Add(' begin');
  522. Source.Add(' result:=@self;');
  523. Source.Add(' end;');
  524. Source.Add('');
  525. Source.Add(' var');
  526. Source.Add(' ResourceManager:TResourceManager;');
  527. Source.Add('');
  528. Source.Add(' begin');
  529. Source.Add(' ResourceManager.LoadResourceFromFile(''file1'')');
  530. Source.Add(' ^.LoadResourceFromFile(''file2'');');
  531. Source.Add(' end.');
  532. ParseModule;
  533. end;
  534. procedure TTestExpressions.TestChainedPointers2;
  535. begin
  536. Source.Add('program afile;');
  537. Source.Add('procedure test;');
  538. Source.Add('begin');
  539. Source.Add('ResourcePool.Shared^.Register(TypeOf(tTexture), @LoadTexture)^.Tag(GLResourceTag)');
  540. Source.Add(' ^.Register(TypeOf(tShader), @LoadShader)^.Tag(GLResourceTag)//space - works');
  541. Source.Add('^.Register(TypeOf(ShaderProgram), @LoadShaderProgram)^.Tag(GLResourceTag);//without space - does not work');
  542. Source.Add('end;');
  543. Source.Add('begin');
  544. Source.Add('end.');
  545. ParseModule;
  546. end;
  547. procedure TTestExpressions.TestChainedPointers3;
  548. begin
  549. Source.Add('program afile;');
  550. Source.Add('procedure test;');
  551. Source.Add('begin');
  552. Source.Add('ResourcePool.Shared^.Register(TypeOf(tTexture), @LoadTexture)^.Tag(GLResourceTag)');
  553. Source.Add(' ^.Register(TypeOf(tShader), @LoadShader)^.Tag(GLResourceTag)//space - works');
  554. Source.Add(#9'^.Register(TypeOf(ShaderProgram), @LoadShaderProgram)^.Tag(GLResourceTag);// tab - does not work');
  555. Source.Add('end;');
  556. Source.Add('begin');
  557. Source.Add('end.');
  558. ParseModule;
  559. end;
  560. procedure TTestExpressions.TestNilCaret;
  561. begin
  562. Source.Add('{$mode objfpc}');
  563. Source.Add('begin');
  564. Source.Add('FillChar(nil^,10,10);');
  565. Source.Add('end.');
  566. ParseModule;
  567. end;
  568. procedure TTestExpressions.TestExpCaret;
  569. begin
  570. Source.Add('{$mode objfpc}');
  571. Source.Add('begin');
  572. Source.Add('A:=B^;');
  573. Source.Add('end.');
  574. ParseModule;
  575. end;
  576. procedure TTestExpressions.TestArrayAccess;
  577. begin
  578. Source.Add('begin');
  579. Source.Add('DoSomething((pb + 10)[4]);');
  580. Source.Add('end.');
  581. ParseModule;
  582. end;
  583. procedure TTestExpressions.TestHelperOnLiteral;
  584. begin
  585. Source.Add('begin');
  586. Source.Add('writeln(''10''.toint);');
  587. Source.Add('end.');
  588. ParseModule;
  589. end;
  590. procedure TTestExpressions.TestUnaryMinus;
  591. begin
  592. DeclareVar('integer','a');
  593. DeclareVar('integer','b');
  594. ParseExpression('-b');
  595. AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
  596. AssertExpression('Simple identifier',theLeft,pekIdent,'b');
  597. end;
  598. procedure TTestExpressions.TestUnaryMinusWhiteSpace;
  599. begin
  600. DeclareVar('integer','a');
  601. DeclareVar('integer','b');
  602. ParseExpression('- b');
  603. AssertUnaryExpr('Simple minus unary',eopSubtract,FLeft);
  604. AssertExpression('Simple identifier',theLeft,pekIdent,'b');
  605. end;
  606. procedure TTestExpressions.TestUnaryAddress;
  607. begin
  608. DeclareVar('integer','a');
  609. DeclareVar('integer','b');
  610. ParseExpression('@b');
  611. AssertUnaryExpr('Simple address unary',eopAddress,FLeft);
  612. AssertExpression('Simple identifier',theLeft,pekIdent,'b');
  613. end;
  614. procedure TTestExpressions.TestUnaryNot;
  615. begin
  616. DeclareVar('boolean','a');
  617. DeclareVar('boolean','b');
  618. ParseExpression('not b');
  619. AssertUnaryExpr('Simple address unary',eopNot,FLeft);
  620. AssertExpression('Simple identifier',theLeft,pekIdent,'b');
  621. end;
  622. procedure TTestExpressions.TestUnaryDeref;
  623. begin
  624. DeclareVar('integer','a');
  625. DeclareVar('pinteger','b');
  626. ParseExpression('b^');
  627. AssertUnaryExpr('Simple deref unary',eopDeref,FLeft);
  628. AssertExpression('Simple identifier',theLeft,pekIdent,'b');
  629. end;
  630. procedure TTestExpressions.TestUnaryDoubleDeref;
  631. begin
  632. DeclareVar('integer','a');
  633. DeclareVar('ppinteger','b');
  634. ParseExpression('(b)^^');
  635. AssertExpression('Deref expression 1',TheExpr,pekUnary,TUnaryExpr);
  636. AssertExpression('Deref expression 2',TUnaryExpr(TheExpr).Operand,pekUnary,TUnaryExpr);
  637. AssertExpression('Deref expression 3',TUnaryExpr(TUnaryExpr(TheExpr).Operand).Operand,pekIdent,'b');
  638. end;
  639. procedure TTestExpressions.TestUnaryDoubleDeref2;
  640. begin
  641. DeclareVar('integer','a');
  642. DeclareVar('ppinteger','b');
  643. ParseExpression('b^^');
  644. AssertExpression('Deref expression 1',TheExpr,pekUnary,TUnaryExpr);
  645. AssertExpression('Deref expression 2',TUnaryExpr(TheExpr).Operand,pekUnary,TUnaryExpr);
  646. AssertExpression('Deref expression 3',TUnaryExpr(TUnaryExpr(TheExpr).Operand).Operand,pekIdent,'b');
  647. end;
  648. procedure TTestExpressions.TestBinaryAdd;
  649. begin
  650. ParseExpression('1+2');
  651. AssertBinaryExpr('Simple binary add',eopAdd,FLeft,FRight);
  652. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  653. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  654. end;
  655. procedure TTestExpressions.TestBinarySubtract;
  656. begin
  657. ParseExpression('1-2');
  658. AssertBinaryExpr('Simple binary subtract',eopSubtract,FLeft,FRight);
  659. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  660. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  661. end;
  662. procedure TTestExpressions.TestBinaryMultiply;
  663. begin
  664. ParseExpression('1*2');
  665. AssertBinaryExpr('Simple binary multiply',eopMultiply,FLeft,FRight);
  666. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  667. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  668. end;
  669. procedure TTestExpressions.TestBinaryDivision;
  670. begin
  671. DeclareVar('double');
  672. ParseExpression('1/2');
  673. AssertBinaryExpr('Simple binary division',eopDivide,FLeft,FRight);
  674. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  675. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  676. end;
  677. procedure TTestExpressions.TestBinaryPower;
  678. begin
  679. DeclareVar('double');
  680. ParseExpression('1**2');
  681. AssertBinaryExpr('Simple binary power',eopPower,FLeft,FRight);
  682. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  683. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  684. end;
  685. procedure TTestExpressions.TestBinaryMod;
  686. begin
  687. ParseExpression('1 mod 2');
  688. AssertBinaryExpr('Simple binary mod',eopMod,FLeft,FRight);
  689. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  690. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  691. end;
  692. procedure TTestExpressions.TestBinaryDiv;
  693. begin
  694. ParseExpression('1 div 2');
  695. AssertBinaryExpr('Simple binary div',eopDiv,FLeft,FRight);
  696. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  697. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  698. end;
  699. procedure TTestExpressions.TestBinaryShl;
  700. begin
  701. ParseExpression('1 shl 2');
  702. AssertBinaryExpr('Simple binary shl',eopShl,FLeft,FRight);
  703. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  704. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  705. end;
  706. procedure TTestExpressions.TestBinaryShr;
  707. begin
  708. ParseExpression('1 shr 2');
  709. AssertBinaryExpr('Simple binary shr',eopShr,FLeft,FRight);
  710. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  711. AssertExpression('Right is 2',TheRight,pekNumber,'2');
  712. end;
  713. procedure TTestExpressions.TestBinarySymmetricalDifference;
  714. begin
  715. DeclareVar('Set of Byte','a');
  716. DeclareVar('Set of Byte','b');
  717. DeclareVar('Set of Byte','c');
  718. ParseExpression('b >< c');
  719. AssertBinaryExpr('Simple binary smmetrical difference',eopSymmetricalDifference,FLeft,FRight);
  720. AssertExpression('Left is b',TheLeft,pekident,'b');
  721. AssertExpression('Right is c',TheRight,pekIdent,'c');
  722. end;
  723. procedure TTestExpressions.TestBinaryAnd;
  724. begin
  725. DeclareVar('boolean','a');
  726. DeclareVar('boolean','b');
  727. DeclareVar('boolean','b');
  728. ParseExpression('b and c');
  729. AssertBinaryExpr('Simple binary and',eopAnd,FLeft,FRight);
  730. AssertExpression('Left is b',TheLeft,pekIdent,'b');
  731. AssertExpression('Right is c',TheRight,pekIdent,'c');
  732. end;
  733. procedure TTestExpressions.TestBinaryOr;
  734. begin
  735. DeclareVar('boolean','a');
  736. DeclareVar('boolean','b');
  737. DeclareVar('boolean','b');
  738. ParseExpression('b or c');
  739. AssertBinaryExpr('Simple binary or',eopOr,FLeft,FRight);
  740. AssertExpression('Left is b',TheLeft,pekIdent,'b');
  741. AssertExpression('Right is c',TheRight,pekIdent,'c');
  742. end;
  743. procedure TTestExpressions.TestBinaryXOr;
  744. begin
  745. DeclareVar('boolean','a');
  746. DeclareVar('boolean','b');
  747. DeclareVar('boolean','b');
  748. ParseExpression('b xor c');
  749. AssertBinaryExpr('Simple binary xor',eopxOr,FLeft,FRight);
  750. AssertExpression('Left is b',TheLeft,pekIdent,'b');
  751. AssertExpression('Right is c',TheRight,pekIdent,'c');
  752. end;
  753. procedure TTestExpressions.TestBinaryIn;
  754. begin
  755. DeclareVar('boolean','a');
  756. ParseExpression('1 in [1,2,3]');
  757. AssertBinaryExpr('Simple binary In',eopIn,FLeft,FRight);
  758. AssertExpression('Left is 1',TheLeft,pekNumber,'1');
  759. AssertExpression('Right is array set',TheRight,pekSet,TParamsExpr);
  760. end;
  761. procedure TTestExpressions.TestBinaryIs;
  762. begin
  763. DeclareVar('boolean','a');
  764. DeclareVar('TObject','b');
  765. ParseExpression('b is TObject');
  766. AssertBinaryExpr('Simple binary Is',eopIs,FLeft,FRight);
  767. AssertExpression('Left is 1',TheLeft,pekident,'b');
  768. AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
  769. end;
  770. procedure TTestExpressions.TestBinaryAs;
  771. begin
  772. DeclareVar('TObject','a');
  773. DeclareVar('TObject','b');
  774. ParseExpression('b as TObject');
  775. AssertBinaryExpr('Simple binary As',eopAs,FLeft,FRight);
  776. AssertExpression('Left is 1',TheLeft,pekident,'b');
  777. AssertExpression('Right is TObject',TheRight,pekIdent,'TObject');
  778. end;
  779. procedure TTestExpressions.TestBinaryEquals;
  780. begin
  781. DeclareVar('boolean','a');
  782. DeclareVar('integer','b');
  783. DeclareVar('integer','c');
  784. ParseExpression('b=c');
  785. AssertBinaryExpr('Simple binary equals',eopEqual,FLeft,FRight);
  786. AssertExpression('Left is b',TheLeft,pekident,'b');
  787. AssertExpression('Right is c',TheRight,pekIdent,'c');
  788. end;
  789. procedure TTestExpressions.TestBinaryDiffers;
  790. begin
  791. DeclareVar('boolean','a');
  792. DeclareVar('integer','b');
  793. DeclareVar('integer','c');
  794. ParseExpression('b<>c');
  795. AssertBinaryExpr('Simple binary differs',eopNotEqual,FLeft,FRight);
  796. AssertExpression('Left is b',TheLeft,pekident,'b');
  797. AssertExpression('Right is c',TheRight,pekIdent,'c');
  798. end;
  799. procedure TTestExpressions.TestBinaryLessThan;
  800. begin
  801. DeclareVar('boolean','a');
  802. DeclareVar('integer','b');
  803. DeclareVar('integer','c');
  804. ParseExpression('b<c');
  805. AssertBinaryExpr('Simple binary less than',eopLessThan,FLeft,FRight);
  806. AssertExpression('Left is b',TheLeft,pekident,'b');
  807. AssertExpression('Right is c',TheRight,pekIdent,'c');
  808. end;
  809. procedure TTestExpressions.TestBinaryLessThanEqual;
  810. begin
  811. DeclareVar('boolean','a');
  812. DeclareVar('integer','b');
  813. DeclareVar('integer','c');
  814. ParseExpression('b<=c');
  815. AssertBinaryExpr('Simple binary less than or equal',eopLessThanEqual,FLeft,FRight);
  816. AssertExpression('Left is b',TheLeft,pekident,'b');
  817. AssertExpression('Right is c',TheRight,pekIdent,'c');
  818. end;
  819. procedure TTestExpressions.TestBinaryLargerThan;
  820. begin
  821. DeclareVar('boolean','a');
  822. DeclareVar('integer','b');
  823. DeclareVar('integer','c');
  824. ParseExpression('b>c');
  825. AssertBinaryExpr('Simple binary larger than ',eopGreaterThan,FLeft,FRight);
  826. AssertExpression('Left is b',TheLeft,pekident,'b');
  827. AssertExpression('Right is c',TheRight,pekIdent,'c');
  828. end;
  829. procedure TTestExpressions.TestBinaryLargerThanEqual;
  830. begin
  831. DeclareVar('boolean','a');
  832. DeclareVar('integer','b');
  833. DeclareVar('integer','c');
  834. ParseExpression('b>=c');
  835. AssertBinaryExpr('Simple binary larger than or equal',eopGreaterThanEqual,FLeft,FRight);
  836. AssertExpression('Left is b',TheLeft,pekident,'b');
  837. AssertExpression('Right is c',TheRight,pekIdent,'c');
  838. end;
  839. procedure TTestExpressions.TestPrimitiveBooleanFalse;
  840. begin
  841. DeclareVar('boolean','a');
  842. ParseExpression('False');
  843. AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
  844. AssertEquals('Boolean false',False,TBoolConstExpr(TheExpr).Value);
  845. end;
  846. procedure TTestExpressions.TestPrimitiveBooleanTrue;
  847. begin
  848. DeclareVar('boolean','a');
  849. ParseExpression('True');
  850. AssertExpression('Simple boolean',theExpr,pekBoolConst,TBoolConstExpr);
  851. AssertEquals('Boolean true',True,TBoolConstExpr(TheExpr).Value);
  852. end;
  853. procedure TTestExpressions.TestPrimitiveNil;
  854. begin
  855. DeclareVar('pointer','a');
  856. ParseExpression('Nil');
  857. AssertExpression('Nil expr',theExpr,pekNil,TNilExpr);
  858. end;
  859. procedure TTestExpressions.TestPrimitiveSet;
  860. Var
  861. P : TParamsExpr;
  862. begin
  863. DeclareVar('set of byte','a');
  864. ParseExpression('[1,2,3]');
  865. P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
  866. AssertEquals('Element count',3,Length(P.Params));
  867. AssertExpression('Element 1 in set',P.Params[0],pekNumber,'1');
  868. AssertExpression('Element 2 in set',P.Params[1],pekNumber,'2');
  869. AssertExpression('Element 3 in set',P.Params[2],pekNumber,'3');
  870. end;
  871. procedure TTestExpressions.TestPrimitiveChar;
  872. begin
  873. DeclareVar('char');
  874. ParseExpression('#32');
  875. AssertExpression('Simple string',theExpr,pekString,'#32');
  876. end;
  877. procedure TTestExpressions.TestPrimitiveControlChar;
  878. begin
  879. DeclareVar('char');
  880. ParseExpression('^M');
  881. AssertExpression('Simple string',theExpr,pekString,'^M');
  882. end;
  883. procedure TTestExpressions.TestPrimitiveSetEmpty;
  884. Var
  885. P : TParamsExpr;
  886. begin
  887. DeclareVar('set of byte','a');
  888. ParseExpression('[]');
  889. P:=TParamsExpr(AssertExpression('Set expr',theExpr,pekSet,TParamsExpr));
  890. AssertEquals('Element count',0,Length(P.Params));
  891. end;
  892. procedure TTestExpressions.TestPrimitiveSelf;
  893. begin
  894. DeclareVar('pointer','a');
  895. ParseExpression('Self');
  896. AssertExpression('Inherited expr',theExpr,pekSelf,TSelfExpr);
  897. end;
  898. procedure TTestExpressions.TestInherited;
  899. begin
  900. DeclareVar('pointer','a');
  901. ParseExpression('inherited');
  902. AssertExpression('Inherited expr',theExpr,pekInherited,TInheritedExpr);
  903. end;
  904. procedure TTestExpressions.TestInheritedFunction;
  905. begin
  906. DeclareVar('pointer','a');
  907. ParseExpression('inherited myfunction');
  908. AssertBinaryExpr('Inherited expr',eopNone,Fleft,FRight);
  909. AssertExpression('Inherited expr',theleft,pekInherited,TInheritedExpr);
  910. AssertExpression('Inherited expr',theright,pekIdent,'myfunction');
  911. end;
  912. procedure TTestExpressions.SetUp;
  913. begin
  914. Inherited;
  915. FVariables:=TStringList.Create;
  916. end;
  917. procedure TTestExpressions.TearDown;
  918. begin
  919. FreeAndNil(FVariables);
  920. Inherited;
  921. end;
  922. procedure TTestExpressions.SetExpression(const AExpression: String);
  923. Var
  924. I : Integer;
  925. begin
  926. StartProgram(ExtractFileUnitName(MainFilename));
  927. if FVariables.Count=0 then
  928. DeclareVar('integer');
  929. Add('Var');
  930. For I:=0 to FVariables.Count-1 do
  931. Add(' '+Fvariables[I]);
  932. Add('begin');
  933. Add(' a:='+AExpression+';');
  934. end;
  935. procedure TTestExpressions.ParseExpression;
  936. begin
  937. ParseModule;
  938. AssertEquals('Have program',TPasProgram,Module.ClassType);
  939. AssertNotNull('Have program section',PasProgram.ProgramSection);
  940. AssertNotNull('Have initialization section',PasProgram.InitializationSection);
  941. AssertEquals('Have initialization statement',1,PasProgram.InitializationSection.Elements.Count);
  942. AssertNotNull('Have initialization statement',PasProgram.InitializationSection.Elements[0]);
  943. AssertEquals('Assignment statement',TPasImplAssign,TObject(PasProgram.InitializationSection.Elements[0]).ClassType);
  944. FTheExpr:=TPasImplAssign(PasProgram.InitializationSection.Elements[0]).right;
  945. AssertNotNull('Have assignment expression',FTheExpr);
  946. end;
  947. procedure TTestExpressions.ParseExpression(const AExpression: String);
  948. begin
  949. SetExpression(AExpression);
  950. ParseExpression;
  951. end;
  952. function TTestExpressions.AssertBinaryExpr(const Msg: String; Op: TExprOpCode;
  953. out ALeft, ARight: TPasExpr): TBinaryExpr;
  954. begin
  955. Result:=AssertBinaryExpr(Msg,TheExpr,Op,ALeft,ARight);
  956. end;
  957. function TTestExpressions.AssertBinaryExpr(const Msg: String; AExpr: TPasExpr;
  958. Op: TExprOpCode; out ALeft, ARight: TPasExpr): TBinaryExpr;
  959. begin
  960. AssertExpression(Msg+' is binary',AExpr,pekBinary,TBinaryExpr);
  961. Result:=AExpr as TBinaryExpr;
  962. AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
  963. ALeft:=Result.Left;
  964. ARight:=Result.Right;
  965. AssertNotNull('Have left',ALeft);
  966. AssertNotNull('Have right',ARight);
  967. TAssert.AssertSame('Result.left.parent=B',Result,Result.left.Parent);
  968. TAssert.AssertSame('Result.right.parent=B',Result,Result.right.Parent);
  969. end;
  970. function TTestExpressions.AssertUnaryExpr(const Msg: String; Op: TExprOpCode;
  971. out AOperand : TPasExpr): TUnaryExpr;
  972. begin
  973. Result:=AssertUnaryExpr(Msg,TheExpr,OP,AOperand);
  974. end;
  975. function TTestExpressions.AssertUnaryExpr(const Msg: String; AExpr: TPasExpr;
  976. Op: TExprOpCode; out AOperand: TPasExpr): TUnaryExpr;
  977. begin
  978. AssertExpression(Msg+' is unary',AExpr,pekUnary,TUnaryExpr);
  979. Result:=AExpr as TUnaryExpr;
  980. AssertEquals(Msg+' opcode OK',Op,Result.OpCode);
  981. AOperand:=Result.Operand;
  982. AssertNotNull('Have left',AOperand);
  983. end;
  984. Procedure TTestExpressions.ParseStrWithFormatFullyQualified;
  985. Var
  986. P : TParamsExpr;
  987. B : TBinaryExpr;
  988. begin
  989. DeclareVar('string','a');
  990. DeclareVar('integer','i');
  991. ParseExpression('system.str(i:0:3,a)');
  992. B:=TBinaryExpr(AssertExpression('Binary identifier',theExpr,pekBinary,TBinaryExpr));
  993. P:=TParamsExpr(AssertExpression('Simple identifier',B.Right,pekFuncParams,TParamsExpr));
  994. AssertExpression('Name of function',P.Value,pekIdent,'str');
  995. AssertEquals('2 argument',2,Length(p.params));
  996. AssertExpression('Simple identifier',p.params[0],pekIdent,'i');
  997. AssertExpression('Simple identifier',p.params[1],pekIdent,'a');
  998. end;
  999. initialization
  1000. RegisterTest(TTestExpressions);
  1001. end.