tcscanner.pas 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731
  1. unit tcscanner;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, typinfo, fpcunit, testregistry, pscanner;
  6. type
  7. { TTestTokenFinder }
  8. TTestTokenFinder = class(TTestCase)
  9. Published
  10. Procedure TestFind;
  11. end;
  12. { TTestStreamLineReader }
  13. TTestStreamLineReader = class(TTestCase)
  14. Private
  15. FReader: TStreamLineReader;
  16. Protected
  17. procedure NewSource(Const Source : string);
  18. Procedure TestLine(Const ALine : String; ExpectEOF : Boolean = True);
  19. procedure TearDown; override;
  20. Published
  21. Procedure TestCreate;
  22. Procedure TestEOF;
  23. Procedure TestEmptyLine;
  24. Procedure TestEmptyLineCR;
  25. Procedure TestEmptyLineLF;
  26. Procedure TestEmptyLineCRLF;
  27. Procedure TestEmptyLineLFCR;
  28. Procedure TestOneLine;
  29. Procedure TestTwoLines;
  30. end;
  31. { TTestingPascalScanner }
  32. TTestingPascalScanner = Class(TPascalScanner)
  33. private
  34. FDoSpecial: Boolean;
  35. protected
  36. function HandleMacro(AIndex: integer): TToken;override;
  37. Public
  38. Property DoSpecial : Boolean Read FDoSpecial Write FDoSpecial;
  39. end;
  40. { TTestScanner }
  41. TTestScanner= class(TTestCase)
  42. Private
  43. FLI: String;
  44. FScanner : TPascalScanner;
  45. FResolver : TStreamResolver;
  46. protected
  47. procedure SetUp; override;
  48. procedure TearDown; override;
  49. Function TokenToString(tk : TToken) : string;
  50. Procedure AssertEquals(Msg : String; Expected,Actual : TToken); overload;
  51. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitch); overload;
  52. Procedure AssertEquals(Msg : String; Expected,Actual : TModeSwitches); overload;
  53. procedure NewSource(Const Source : string; DoClear : Boolean = True);
  54. Procedure DoTestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  55. Procedure TestToken(t : TToken; Const ASource : String; Const CheckEOF : Boolean = True);
  56. Procedure TestTokens(t : array of TToken; Const ASource : String; Const CheckEOF : Boolean = True;Const DoClear : Boolean = True);
  57. Property LastIDentifier : String Read FLI Write FLi;
  58. Property Scanner : TPascalScanner Read FScanner;
  59. published
  60. Procedure TestEmpty;
  61. procedure TestEOF;
  62. procedure TestWhitespace;
  63. procedure TestComment1;
  64. procedure TestComment2;
  65. procedure TestComment3;
  66. procedure TestComment4;
  67. procedure TestComment5;
  68. procedure TestNestedComment1;
  69. procedure TestNestedComment2;
  70. procedure TestNestedComment3;
  71. procedure TestNestedComment4;
  72. procedure TestNestedComment5;
  73. procedure TestIdentifier;
  74. procedure TestSelf;
  75. procedure TestSelfNoToken;
  76. procedure TestString;
  77. procedure TestNumber;
  78. procedure TestChar;
  79. procedure TestCharString;
  80. procedure TestBraceOpen;
  81. procedure TestBraceClose;
  82. procedure TestMul;
  83. procedure TestPlus;
  84. procedure TestComma;
  85. procedure TestMinus;
  86. procedure TestDot;
  87. procedure TestDivision;
  88. procedure TestColon;
  89. procedure TestSemicolon;
  90. procedure TestLessThan;
  91. procedure TestEqual;
  92. procedure TestGreaterThan;
  93. procedure TestAt;
  94. procedure TestSquaredBraceOpen;
  95. procedure TestSquaredBraceClose;
  96. procedure TestCaret;
  97. procedure TestBackslash;
  98. procedure TestDotDot;
  99. procedure TestAssign;
  100. procedure TestAssignPlus;
  101. procedure TestAssignMinus;
  102. procedure TestAssignMul;
  103. procedure TestAssignDivision;
  104. procedure TestNotEqual;
  105. procedure TestLessEqualThan;
  106. procedure TestGreaterEqualThan;
  107. procedure TestPower;
  108. procedure TestSymmetricalDifference;
  109. procedure TestAbsolute;
  110. procedure TestAnd;
  111. procedure TestArray;
  112. procedure TestAs;
  113. procedure TestAsm;
  114. procedure TestBegin;
  115. procedure TestBitpacked;
  116. procedure TestCase;
  117. procedure TestClass;
  118. procedure TestConst;
  119. procedure TestConstructor;
  120. procedure TestDestructor;
  121. procedure TestDispinterface;
  122. procedure TestDiv;
  123. procedure TestDo;
  124. procedure TestDownto;
  125. procedure TestElse;
  126. procedure TestEnd;
  127. procedure TestExcept;
  128. procedure TestExports;
  129. procedure TestFalse;
  130. procedure TestFile;
  131. procedure TestFinalization;
  132. procedure TestFinally;
  133. procedure TestFor;
  134. procedure TestFunction;
  135. procedure TestGeneric;
  136. procedure TestGoto;
  137. Procedure TestHelper;
  138. procedure TestIf;
  139. procedure TestImplementation;
  140. procedure TestIn;
  141. procedure TestInherited;
  142. procedure TestInitialization;
  143. procedure TestInline;
  144. procedure TestInterface;
  145. procedure TestIs;
  146. procedure TestLabel;
  147. procedure TestLibrary;
  148. procedure TestMod;
  149. procedure TestNil;
  150. procedure TestNot;
  151. procedure TestObject;
  152. procedure TestOf;
  153. procedure TestOn;
  154. procedure TestOperator;
  155. procedure TestOr;
  156. procedure TestPacked;
  157. procedure TestProcedure;
  158. procedure TestProgram;
  159. procedure TestProperty;
  160. procedure TestRaise;
  161. procedure TestRecord;
  162. procedure TestRepeat;
  163. procedure TestResourceString;
  164. procedure TestSet;
  165. procedure TestShl;
  166. procedure TestShr;
  167. procedure TestShlC;
  168. procedure TestShrC;
  169. procedure TestSpecialize;
  170. procedure TestThen;
  171. procedure TestThreadvar;
  172. procedure TestTo;
  173. procedure TestTrue;
  174. procedure TestTry;
  175. procedure TestType;
  176. procedure TestUnit;
  177. procedure TestUntil;
  178. procedure TestUses;
  179. procedure TestVar;
  180. procedure TestWhile;
  181. procedure TestWith;
  182. procedure TestXor;
  183. procedure TestLineEnding;
  184. procedure TestTab;
  185. Procedure TestEscapedKeyWord;
  186. Procedure TestTokenSeries;
  187. Procedure TestTokenSeriesNoWhiteSpace;
  188. Procedure TestTokenSeriesComments;
  189. Procedure TestTokenSeriesNoComments;
  190. Procedure TestDefine0;
  191. procedure TestDefine01;
  192. Procedure TestDefine1;
  193. Procedure TestDefine2;
  194. Procedure TestDefine21;
  195. procedure TestDefine22;
  196. Procedure TestDefine3;
  197. Procedure TestDefine4;
  198. Procedure TestDefine5;
  199. Procedure TestDefine6;
  200. Procedure TestDefine7;
  201. Procedure TestDefine8;
  202. Procedure TestDefine9;
  203. Procedure TestDefine10;
  204. Procedure TestDefine11;
  205. Procedure TestDefine12;
  206. Procedure TestDefine13;
  207. Procedure TestDefine14;
  208. Procedure TestInclude;
  209. Procedure TestInclude2;
  210. Procedure TestUnDefine1;
  211. Procedure TestMacro1;
  212. procedure TestMacro2;
  213. procedure TestMacro3;
  214. procedure TestMacroHandling;
  215. procedure TestIFDefined;
  216. procedure TestIFUnDefined;
  217. procedure TestIFAnd;
  218. procedure TestIFAndShortEval;
  219. procedure TestIFOr;
  220. procedure TestIFOrShortEval;
  221. procedure TestIFXor;
  222. procedure TestIFAndOr;
  223. procedure TestIFEqual;
  224. procedure TestIFNotEqual;
  225. procedure TestIFGreaterThan;
  226. procedure TestIFGreaterEqualThan;
  227. procedure TestIFLesserThan;
  228. procedure TestIFLesserEqualThan;
  229. procedure TestIFDefinedElseIf;
  230. procedure TestIfError;
  231. Procedure TestModeSwitch;
  232. end;
  233. implementation
  234. { TTestingPascalScanner }
  235. function TTestingPascalScanner.HandleMacro(AIndex: integer): TToken;
  236. begin
  237. if DoSpecial then
  238. begin
  239. Result:=tkIdentifier;
  240. SetCurTokenstring('somethingweird');
  241. end
  242. else
  243. Result:=inherited HandleMacro(AIndex);
  244. end;
  245. { TTestTokenFinder }
  246. procedure TTestTokenFinder.TestFind;
  247. Var
  248. tk,tkr : TToken;
  249. S : string;
  250. B : Boolean;
  251. begin
  252. For tk:=tkAbsolute to tkXor do
  253. begin
  254. S:=tokenInfos[tk];
  255. B:=IsNamedToken(S,tkr);
  256. AssertEquals('Token '+S+' is a token',true,B);
  257. AssertEquals('Token '+S+' returns correct token',Ord(tk),Ord(tkr));
  258. end;
  259. end;
  260. { TTestStreamLineReader }
  261. procedure TTestStreamLineReader.NewSource(Const Source: string);
  262. begin
  263. FReader:=TStringStreamLineReader.Create('afile',Source);
  264. end;
  265. procedure TTestStreamLineReader.TestLine(const ALine: String; ExpectEOF: Boolean);
  266. begin
  267. AssertNotNull('Have reader',FReader);
  268. AssertEquals('Reading source line',ALine,FReader.ReadLine);
  269. if ExpectEOF then
  270. AssertEquals('End of file reached',True,FReader.IsEOF);
  271. end;
  272. procedure TTestStreamLineReader.TearDown;
  273. begin
  274. inherited TearDown;
  275. If Assigned(FReader) then
  276. FreeAndNil(Freader);
  277. end;
  278. procedure TTestStreamLineReader.TestCreate;
  279. begin
  280. FReader:=TStreamLineReader.Create('afile');
  281. AssertEquals('Correct filename','afile',FReader.FileName);
  282. AssertEquals('Initially empty',True,FReader.isEOF);
  283. end;
  284. procedure TTestStreamLineReader.TestEOF;
  285. begin
  286. NewSource('');
  287. AssertEquals('Empty stream',True,FReader.IsEOF);
  288. end;
  289. procedure TTestStreamLineReader.TestEmptyLine;
  290. begin
  291. NewSource('');
  292. TestLine('');
  293. end;
  294. procedure TTestStreamLineReader.TestEmptyLineCR;
  295. begin
  296. NewSource(#13);
  297. TestLine('');
  298. end;
  299. procedure TTestStreamLineReader.TestEmptyLineLF;
  300. begin
  301. NewSource(#10);
  302. TestLine('');
  303. end;
  304. procedure TTestStreamLineReader.TestEmptyLineCRLF;
  305. begin
  306. NewSource(#13#10);
  307. TestLine('');
  308. end;
  309. procedure TTestStreamLineReader.TestEmptyLineLFCR;
  310. begin
  311. NewSource(#10#13);
  312. TestLine('',False);
  313. TestLine('');
  314. end;
  315. procedure TTestStreamLineReader.TestOneLine;
  316. Const
  317. S = 'a line with text';
  318. begin
  319. NewSource(S);
  320. TestLine(S);
  321. end;
  322. procedure TTestStreamLineReader.TestTwoLines;
  323. Const
  324. S = 'a line with text';
  325. begin
  326. NewSource(S+sLineBreak+S);
  327. TestLine(S,False);
  328. TestLine(S);
  329. end;
  330. { ---------------------------------------------------------------------
  331. TTestScanner
  332. ---------------------------------------------------------------------}
  333. procedure TTestScanner.SetUp;
  334. begin
  335. FResolver:=TStreamResolver.Create;
  336. FResolver.OwnsStreams:=True;
  337. FScanner:=TTestingPascalScanner.Create(FResolver);
  338. // Do nothing
  339. end;
  340. procedure TTestScanner.TearDown;
  341. begin
  342. FreeAndNil(FScanner);
  343. FreeAndNil(FResolver);
  344. end;
  345. function TTestScanner.TokenToString(tk: TToken): string;
  346. begin
  347. Result:=GetEnumName(TypeInfo(TToken),Ord(tk));
  348. end;
  349. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TToken);
  350. begin
  351. AssertEquals(Msg,TokenToString(Expected),TokenToString(Actual));
  352. end;
  353. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitch);
  354. begin
  355. AssertEquals(Msg,GetEnumName(TypeInfo(TModeSwitch),Ord(Expected)),
  356. GetEnumName(TypeInfo(TModeSwitch),Ord(Actual)))
  357. end;
  358. procedure TTestScanner.AssertEquals(Msg: String; Expected, Actual: TModeSwitches);
  359. Function ToString(S : TModeSwitches) : String;
  360. Var
  361. M : TModeSwitch;
  362. begin
  363. Result:='';
  364. For M in TModeswitch do
  365. if M in S then
  366. begin
  367. If (Result<>'') then
  368. Result:=Result+', ';
  369. Result:=Result+GetEnumName(TypeInfo(TModeSwitch), Ord(M));
  370. end;
  371. end;
  372. begin
  373. AssertEquals(Msg,ToString(Expected),ToString(Actual));
  374. end;
  375. procedure TTestScanner.NewSource(const Source: string; DoClear : Boolean = True);
  376. begin
  377. if DoClear then
  378. FResolver.Clear;
  379. FResolver.AddStream('afile.pp',TStringStream.Create(Source));
  380. Writeln('// '+TestName);
  381. Writeln(Source);
  382. // FreeAndNil(FScanner);
  383. // FScanner:=TTestingPascalScanner.Create(FResolver);
  384. FScanner.OpenFile('afile.pp');
  385. end;
  386. procedure TTestScanner.DoTestToken(t: TToken; const ASource: String;
  387. const CheckEOF: Boolean);
  388. Var
  389. tk : ttoken;
  390. begin
  391. NewSource(ASource);
  392. tk:=FScanner.FetchToken;
  393. AssertEquals('Read token equals expected token.',t,tk);
  394. if CheckEOF then
  395. begin
  396. tk:=FScanner.FetchToken;
  397. if (tk=tkLineEnding) and not (t in [tkEOF,tkLineEnding]) then
  398. tk:=FScanner.FetchToken;
  399. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  400. end
  401. end;
  402. procedure TTestScanner.TestToken(t: TToken; const ASource: String;
  403. const CheckEOF: Boolean);
  404. Var
  405. S : String;
  406. begin
  407. DoTestToken(t,ASource);
  408. if (ASource<>'') then
  409. begin
  410. S:=ASource;
  411. S[1]:=Upcase(S[1]);
  412. DoTestToken(t,S);
  413. end;
  414. DoTestToken(t,UpperCase(ASource));
  415. DoTestToken(t,LowerCase(ASource));
  416. end;
  417. procedure TTestScanner.TestTokens(t: array of TToken; const ASource: String;
  418. const CheckEOF: Boolean; const DoClear: Boolean);
  419. Var
  420. tk : ttoken;
  421. i : integer;
  422. begin
  423. NewSource(ASource,DoClear);
  424. For I:=Low(t) to High(t) do
  425. begin
  426. tk:=FScanner.FetchToken;
  427. AssertEquals(Format('Read token %d equals expected token.',[i]),t[i],tk);
  428. if tk=tkIdentifier then
  429. LastIdentifier:=FScanner.CurtokenString;
  430. end;
  431. if CheckEOF then
  432. begin
  433. tk:=FScanner.FetchToken;
  434. if (tk=tkLineEnding) then
  435. tk:=FScanner.FetchToken;
  436. AssertEquals('EOF reached.',tkEOF,FScanner.FetchToken);
  437. end;
  438. end;
  439. procedure TTestScanner.TestEmpty;
  440. begin
  441. AssertNotNull('Have Scanner',Scanner);
  442. AssertTrue('Options is empty',[]=Scanner.Options);
  443. AssertEquals('FPC modes is default',FPCModeSwitches,Scanner.CurrentModeSwitches);
  444. end;
  445. procedure TTestScanner.TestEOF;
  446. begin
  447. TestToken(tkEOF,'')
  448. end;
  449. procedure TTestScanner.TestWhitespace;
  450. begin
  451. TestToken(tkWhitespace,' ');
  452. TestToken(tkWhitespace,' ');
  453. end;
  454. procedure TTestScanner.TestComment1;
  455. begin
  456. TestToken(tkComment,'{ comment }');
  457. end;
  458. procedure TTestScanner.TestComment2;
  459. begin
  460. TestToken(tkComment,'(* comment *)');
  461. end;
  462. procedure TTestScanner.TestComment3;
  463. begin
  464. TestToken(tkComment,'//');
  465. end;
  466. procedure TTestScanner.TestComment4;
  467. begin
  468. DoTestToken(tkComment,'(* abc *)',False);
  469. AssertEquals('Correct comment',' abc ',Scanner.CurTokenString);
  470. end;
  471. procedure TTestScanner.TestComment5;
  472. begin
  473. DoTestToken(tkComment,'(* abc'+LineEnding+'def *)',False);
  474. AssertEquals('Correct comment',' abc'+LineEnding+'def ',Scanner.CurTokenString);
  475. end;
  476. procedure TTestScanner.TestNestedComment1;
  477. begin
  478. TestToken(tkComment,'// { comment } ');
  479. end;
  480. procedure TTestScanner.TestNestedComment2;
  481. begin
  482. TestToken(tkComment,'(* { comment } *)');
  483. end;
  484. procedure TTestScanner.TestNestedComment3;
  485. begin
  486. TestToken(tkComment,'{ { comment } }');
  487. end;
  488. procedure TTestScanner.TestNestedComment4;
  489. begin
  490. TestToken(tkComment,'{ (* comment *) }');
  491. end;
  492. procedure TTestScanner.TestNestedComment5;
  493. begin
  494. TestToken(tkComment,'(* (* comment *) *)');
  495. end;
  496. procedure TTestScanner.TestIdentifier;
  497. begin
  498. TestToken(tkIdentifier,'identifier');
  499. end;
  500. procedure TTestScanner.TestString;
  501. begin
  502. TestToken(pscanner.tkString,'''A string''');
  503. end;
  504. procedure TTestScanner.TestCharString;
  505. begin
  506. TestToken(pscanner.tkChar,'''A''');
  507. end;
  508. procedure TTestScanner.TestNumber;
  509. begin
  510. TestToken(tkNumber,'123');
  511. end;
  512. procedure TTestScanner.TestChar;
  513. begin
  514. TestToken(pscanner.tkChar,'#65 ', false);
  515. end;
  516. procedure TTestScanner.TestBraceOpen;
  517. begin
  518. TestToken(tkBraceOpen,'(');
  519. end;
  520. procedure TTestScanner.TestBraceClose;
  521. begin
  522. TestToken(tkBraceClose,')');
  523. end;
  524. procedure TTestScanner.TestMul;
  525. begin
  526. TestToken(tkMul,'*');
  527. end;
  528. procedure TTestScanner.TestPlus;
  529. begin
  530. TestToken(tkPlus,'+');
  531. end;
  532. procedure TTestScanner.TestComma;
  533. begin
  534. TestToken(tkComma,',');
  535. end;
  536. procedure TTestScanner.TestMinus;
  537. begin
  538. TestToken(tkMinus,'-');
  539. end;
  540. procedure TTestScanner.TestDot;
  541. begin
  542. TestToken(tkDot,'.');
  543. end;
  544. procedure TTestScanner.TestDivision;
  545. begin
  546. TestToken(tkDivision,'/');
  547. end;
  548. procedure TTestScanner.TestColon;
  549. begin
  550. TestToken(tkColon,':');
  551. end;
  552. procedure TTestScanner.TestSemicolon;
  553. begin
  554. TestToken(tkSemicolon,';');
  555. end;
  556. procedure TTestScanner.TestLessThan;
  557. begin
  558. TestToken(tkLessThan,'<');
  559. end;
  560. procedure TTestScanner.TestEqual;
  561. begin
  562. TestToken(tkEqual,'=');
  563. end;
  564. procedure TTestScanner.TestGreaterThan;
  565. begin
  566. TestToken(tkGreaterThan,'>');
  567. end;
  568. procedure TTestScanner.TestAt;
  569. begin
  570. TestToken(tkAt,'@');
  571. end;
  572. procedure TTestScanner.TestSquaredBraceOpen;
  573. begin
  574. TestToken(tkSquaredBraceOpen,'[');
  575. end;
  576. procedure TTestScanner.TestSquaredBraceClose;
  577. begin
  578. TestToken(tkSquaredBraceClose,']');
  579. end;
  580. procedure TTestScanner.TestCaret;
  581. begin
  582. TestToken(tkCaret,'^');
  583. end;
  584. procedure TTestScanner.TestBackslash;
  585. begin
  586. TestToken(tkBackslash,'\');
  587. end;
  588. procedure TTestScanner.TestDotDot;
  589. begin
  590. TestToken(tkDotDot,'..');
  591. end;
  592. procedure TTestScanner.TestAssign;
  593. begin
  594. TestToken(tkAssign,':=');
  595. end;
  596. procedure TTestScanner.TestAssignPlus;
  597. begin
  598. TestTokens([tkPlus,tkEqual],'+=');
  599. FScanner.Options:=[po_cassignments];
  600. TestToken(tkAssignPlus,'+=');
  601. end;
  602. procedure TTestScanner.TestAssignMinus;
  603. begin
  604. TestTokens([tkMinus,tkEqual],'-=');
  605. FScanner.Options:=[po_cassignments];
  606. TestToken(tkAssignMinus,'-=');
  607. end;
  608. procedure TTestScanner.TestAssignMul;
  609. begin
  610. TestTokens([tkMul,tkEqual],'*=');
  611. FScanner.Options:=[po_cassignments];
  612. TestToken(tkAssignMul,'*=');
  613. end;
  614. procedure TTestScanner.TestAssignDivision;
  615. begin
  616. TestTokens([tkDivision,tkEqual],'/=');
  617. FScanner.Options:=[po_cassignments];
  618. TestToken(tkAssignDivision,'/=');
  619. end;
  620. procedure TTestScanner.TestNotEqual;
  621. begin
  622. TestToken(tkNotEqual,'<>');
  623. end;
  624. procedure TTestScanner.TestLessEqualThan;
  625. begin
  626. TestToken(tkLessEqualThan,'<=');
  627. end;
  628. procedure TTestScanner.TestGreaterEqualThan;
  629. begin
  630. TestToken(tkGreaterEqualThan,'>=');
  631. end;
  632. procedure TTestScanner.TestPower;
  633. begin
  634. TestToken(tkPower,'**');
  635. end;
  636. procedure TTestScanner.TestSymmetricalDifference;
  637. begin
  638. TestToken(tkSymmetricalDifference,'><');
  639. end;
  640. procedure TTestScanner.TestAbsolute;
  641. begin
  642. TestToken(tkabsolute,'absolute');
  643. end;
  644. procedure TTestScanner.TestAnd;
  645. begin
  646. TestToken(tkand,'and');
  647. end;
  648. procedure TTestScanner.TestArray;
  649. begin
  650. TestToken(tkarray,'array');
  651. end;
  652. procedure TTestScanner.TestAs;
  653. begin
  654. TestToken(tkas,'as');
  655. end;
  656. procedure TTestScanner.TestAsm;
  657. begin
  658. TestToken(tkasm,'asm');
  659. end;
  660. procedure TTestScanner.TestBegin;
  661. begin
  662. TestToken(tkbegin,'begin');
  663. end;
  664. procedure TTestScanner.TestBitpacked;
  665. begin
  666. TestToken(tkbitpacked,'bitpacked');
  667. end;
  668. procedure TTestScanner.TestCase;
  669. begin
  670. TestToken(tkcase,'case');
  671. end;
  672. procedure TTestScanner.TestClass;
  673. begin
  674. TestToken(tkclass,'class');
  675. end;
  676. procedure TTestScanner.TestConst;
  677. begin
  678. TestToken(tkconst,'const');
  679. end;
  680. procedure TTestScanner.TestConstructor;
  681. begin
  682. TestToken(tkconstructor,'constructor');
  683. end;
  684. procedure TTestScanner.TestDestructor;
  685. begin
  686. TestToken(tkdestructor,'destructor');
  687. end;
  688. procedure TTestScanner.TestDispinterface;
  689. begin
  690. TestToken(tkdispinterface,'dispinterface');
  691. end;
  692. procedure TTestScanner.TestDiv;
  693. begin
  694. TestToken(tkdiv,'div');
  695. end;
  696. procedure TTestScanner.TestDo;
  697. begin
  698. TestToken(tkdo,'do');
  699. end;
  700. procedure TTestScanner.TestDownto;
  701. begin
  702. TestToken(tkdownto,'downto');
  703. end;
  704. procedure TTestScanner.TestElse;
  705. begin
  706. TestToken(tkelse,'else');
  707. end;
  708. procedure TTestScanner.TestEnd;
  709. begin
  710. TestToken(tkend,'end');
  711. end;
  712. procedure TTestScanner.TestExcept;
  713. begin
  714. TestToken(tkexcept,'except');
  715. end;
  716. procedure TTestScanner.TestExports;
  717. begin
  718. TestToken(tkexports,'exports');
  719. end;
  720. procedure TTestScanner.TestFalse;
  721. begin
  722. TestToken(tkfalse,'false');
  723. end;
  724. procedure TTestScanner.TestFile;
  725. begin
  726. TestToken(tkfile,'file');
  727. end;
  728. procedure TTestScanner.TestFinalization;
  729. begin
  730. TestToken(tkfinalization,'finalization');
  731. end;
  732. procedure TTestScanner.TestFinally;
  733. begin
  734. TestToken(tkfinally,'finally');
  735. end;
  736. procedure TTestScanner.TestFor;
  737. begin
  738. TestToken(tkfor,'for');
  739. end;
  740. procedure TTestScanner.TestFunction;
  741. begin
  742. TestToken(tkfunction,'function');
  743. end;
  744. procedure TTestScanner.TestGeneric;
  745. begin
  746. TestToken(tkgeneric,'generic');
  747. end;
  748. procedure TTestScanner.TestGoto;
  749. begin
  750. TestToken(tkgoto,'goto');
  751. end;
  752. procedure TTestScanner.TestHelper;
  753. begin
  754. TestToken(tkIdentifier,'helper');
  755. end;
  756. procedure TTestScanner.TestIf;
  757. begin
  758. TestToken(tkif,'if');
  759. end;
  760. procedure TTestScanner.TestImplementation;
  761. begin
  762. TestToken(tkimplementation,'implementation');
  763. end;
  764. procedure TTestScanner.TestIn;
  765. begin
  766. TestToken(tkin,'in');
  767. end;
  768. procedure TTestScanner.TestInherited;
  769. begin
  770. TestToken(tkinherited,'inherited');
  771. end;
  772. procedure TTestScanner.TestInitialization;
  773. begin
  774. TestToken(tkinitialization,'initialization');
  775. end;
  776. procedure TTestScanner.TestInline;
  777. begin
  778. TestToken(tkinline,'inline');
  779. end;
  780. procedure TTestScanner.TestInterface;
  781. begin
  782. TestToken(tkinterface,'interface');
  783. end;
  784. procedure TTestScanner.TestIs;
  785. begin
  786. TestToken(tkis,'is');
  787. end;
  788. procedure TTestScanner.TestLabel;
  789. begin
  790. TestToken(tklabel,'label');
  791. end;
  792. procedure TTestScanner.TestLibrary;
  793. begin
  794. TestToken(tklibrary,'library');
  795. end;
  796. procedure TTestScanner.TestMod;
  797. begin
  798. TestToken(tkmod,'mod');
  799. end;
  800. procedure TTestScanner.TestNil;
  801. begin
  802. TestToken(tknil,'nil');
  803. end;
  804. procedure TTestScanner.TestNot;
  805. begin
  806. TestToken(tknot,'not');
  807. end;
  808. procedure TTestScanner.TestObject;
  809. begin
  810. TestToken(tkobject,'object');
  811. end;
  812. procedure TTestScanner.TestOf;
  813. begin
  814. TestToken(tkof,'of');
  815. end;
  816. procedure TTestScanner.TestOn;
  817. begin
  818. TestToken(tkIdentifier,'on');
  819. end;
  820. procedure TTestScanner.TestOperator;
  821. begin
  822. TestToken(tkoperator,'operator');
  823. end;
  824. procedure TTestScanner.TestOr;
  825. begin
  826. TestToken(tkor,'or');
  827. end;
  828. procedure TTestScanner.TestPacked;
  829. begin
  830. TestToken(tkpacked,'packed');
  831. end;
  832. procedure TTestScanner.TestProcedure;
  833. begin
  834. TestToken(tkprocedure,'procedure');
  835. end;
  836. procedure TTestScanner.TestProgram;
  837. begin
  838. TestToken(tkprogram,'program');
  839. end;
  840. procedure TTestScanner.TestProperty;
  841. begin
  842. TestToken(tkproperty,'property');
  843. end;
  844. procedure TTestScanner.TestRaise;
  845. begin
  846. TestToken(tkraise,'raise');
  847. end;
  848. procedure TTestScanner.TestRecord;
  849. begin
  850. TestToken(tkrecord,'record');
  851. end;
  852. procedure TTestScanner.TestRepeat;
  853. begin
  854. TestToken(tkrepeat,'repeat');
  855. end;
  856. procedure TTestScanner.TestResourceString;
  857. begin
  858. TestToken(tkResourceString,'resourcestring');
  859. end;
  860. procedure TTestScanner.TestSelf;
  861. begin
  862. FScanner.Options:=FScanner.Options + [po_selftoken];
  863. TestToken(tkself,'self');
  864. end;
  865. procedure TTestScanner.TestSelfNoToken;
  866. begin
  867. TestToken(tkIdentifier,'self');
  868. end;
  869. procedure TTestScanner.TestSet;
  870. begin
  871. TestToken(tkset,'set');
  872. end;
  873. procedure TTestScanner.TestShl;
  874. begin
  875. TestToken(tkshl,'shl');
  876. end;
  877. procedure TTestScanner.TestShr;
  878. begin
  879. TestToken(tkshr,'shr');
  880. end;
  881. procedure TTestScanner.TestShlC;
  882. begin
  883. TestToken(tkshl,'<<');
  884. end;
  885. procedure TTestScanner.TestShrC;
  886. begin
  887. TestToken(tkshr,'>>');
  888. end;
  889. procedure TTestScanner.TestSpecialize;
  890. begin
  891. TestToken(tkspecialize,'specialize');
  892. end;
  893. procedure TTestScanner.TestThen;
  894. begin
  895. TestToken(tkthen,'then');
  896. end;
  897. procedure TTestScanner.TestThreadvar;
  898. begin
  899. TestToken(tkthreadvar,'threadvar');
  900. end;
  901. procedure TTestScanner.TestTo;
  902. begin
  903. TestToken(tkto,'to');
  904. end;
  905. procedure TTestScanner.TestTrue;
  906. begin
  907. TestToken(tktrue,'true');
  908. end;
  909. procedure TTestScanner.TestTry;
  910. begin
  911. TestToken(tktry,'try');
  912. end;
  913. procedure TTestScanner.TestType;
  914. begin
  915. TestToken(tktype,'type');
  916. end;
  917. procedure TTestScanner.TestUnit;
  918. begin
  919. TestToken(tkunit,'unit');
  920. end;
  921. procedure TTestScanner.TestUntil;
  922. begin
  923. TestToken(tkuntil,'until');
  924. end;
  925. procedure TTestScanner.TestUses;
  926. begin
  927. TestToken(tkuses,'uses');
  928. end;
  929. procedure TTestScanner.TestVar;
  930. begin
  931. TestToken(tkvar,'var');
  932. end;
  933. procedure TTestScanner.TestWhile;
  934. begin
  935. TestToken(tkwhile,'while');
  936. end;
  937. procedure TTestScanner.TestWith;
  938. begin
  939. TestToken(tkwith,'with');
  940. end;
  941. procedure TTestScanner.TestXor;
  942. begin
  943. TestToken(tkxor,'xor');
  944. end;
  945. procedure TTestScanner.TestLineEnding;
  946. begin
  947. TestToken(tkLineEnding,#10);
  948. end;
  949. procedure TTestScanner.TestTab;
  950. begin
  951. TestToken(tkTab,#9);
  952. end;
  953. procedure TTestScanner.TestEscapedKeyWord;
  954. begin
  955. TestToken(tkIdentifier,'&xor');
  956. end;
  957. procedure TTestScanner.TestTokenSeries;
  958. begin
  959. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkthen,tkWhiteSpace,tkIdentifier],'in of then aninteger')
  960. end;
  961. procedure TTestScanner.TestTokenSeriesNoWhiteSpace;
  962. begin
  963. FScanner.SkipWhiteSpace:=True;
  964. TestTokens([tkin,tkOf,tkthen,tkIdentifier],'in of then aninteger')
  965. end;
  966. procedure TTestScanner.TestTokenSeriesComments;
  967. begin
  968. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkComment,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  969. end;
  970. procedure TTestScanner.TestTokenSeriesNoComments;
  971. begin
  972. FScanner.SkipComments:=True;
  973. TestTokens([tkin,tkWhitespace,tkOf,tkWhiteSpace,tkWhiteSpace,tkIdentifier],'in of {then} aninteger')
  974. end;
  975. procedure TTestScanner.TestDefine0;
  976. begin
  977. TestTokens([tkComment],'{$DEFINE NEVER}');
  978. If FSCanner.Defines.IndexOf('NEVER')=-1 then
  979. Fail('Define not defined');
  980. end;
  981. procedure TTestScanner.TestDefine01;
  982. begin
  983. TestTokens([tkComment],'(*$DEFINE NEVER*)');
  984. If FSCanner.Defines.IndexOf('NEVER')=-1 then
  985. Fail('Define not defined');
  986. end;
  987. procedure TTestScanner.TestDefine1;
  988. begin
  989. TestTokens([tkComment],'{$IFDEF NEVER} of {$ENDIF}');
  990. end;
  991. procedure TTestScanner.TestDefine2;
  992. begin
  993. FSCanner.Defines.Add('ALWAYS');
  994. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ENDIF}');
  995. end;
  996. procedure TTestScanner.TestDefine21;
  997. begin
  998. FSCanner.Defines.Add('ALWAYS');
  999. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*) of (*$ENDIF*)');
  1000. end;
  1001. procedure TTestScanner.TestDefine22;
  1002. begin
  1003. FSCanner.Defines.Add('ALWAYS');
  1004. // No whitespace. Test border of *)
  1005. TestTokens([tkComment,tkOf,tkWhitespace,tkcomment],'(*$IFDEF ALWAYS*)of (*$ENDIF*)');
  1006. end;
  1007. procedure TTestScanner.TestDefine3;
  1008. begin
  1009. FSCanner.Defines.Add('ALWAYS');
  1010. TestTokens([tkComment,tkWhitespace,tkOf,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1011. end;
  1012. procedure TTestScanner.TestDefine4;
  1013. begin
  1014. TestTokens([tkComment,tkWhitespace,tkin,tkWhitespace,tkcomment],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1015. end;
  1016. procedure TTestScanner.TestDefine5;
  1017. begin
  1018. FScanner.SkipComments:=True;
  1019. TestTokens([tkLineEnding],'{$IFDEF NEVER} of {$ENDIF}');
  1020. end;
  1021. procedure TTestScanner.TestDefine6;
  1022. begin
  1023. FSCanner.Defines.Add('ALWAYS');
  1024. FScanner.SkipComments:=True;
  1025. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1026. end;
  1027. procedure TTestScanner.TestDefine7;
  1028. begin
  1029. FSCanner.Defines.Add('ALWAYS');
  1030. FScanner.SkipComments:=True;
  1031. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1032. end;
  1033. procedure TTestScanner.TestDefine8;
  1034. begin
  1035. FScanner.SkipComments:=True;
  1036. TestTokens([tkWhitespace,tkin,tkWhitespace],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1037. end;
  1038. procedure TTestScanner.TestDefine9;
  1039. begin
  1040. FScanner.SkipWhiteSpace:=True;
  1041. TestTokens([],'{$IFDEF NEVER} of {$ENDIF}');
  1042. end;
  1043. procedure TTestScanner.TestDefine10;
  1044. begin
  1045. FSCanner.Defines.Add('ALWAYS');
  1046. FScanner.SkipComments:=True;
  1047. TestTokens([tkWhitespace,tkOf,tkWhitespace],'{$IFDEF ALWAYS} of {$ENDIF}');
  1048. end;
  1049. procedure TTestScanner.TestDefine11;
  1050. begin
  1051. FSCanner.Defines.Add('ALWAYS');
  1052. FScanner.SkipComments:=True;
  1053. FScanner.SkipWhiteSpace:=True;
  1054. TestTokens([tkOf],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1055. end;
  1056. procedure TTestScanner.TestDefine12;
  1057. begin
  1058. FScanner.SkipComments:=True;
  1059. FScanner.SkipWhiteSpace:=True;
  1060. TestTokens([tkin],'{$IFDEF ALWAYS} of {$ELSE} in {$ENDIF}');
  1061. end;
  1062. procedure TTestScanner.TestDefine13;
  1063. begin
  1064. FScanner.SkipComments:=True;
  1065. FScanner.SkipWhiteSpace:=True;
  1066. TestTokens([tkin],'{$IFDEF ALWAYS} }; ą è {$ELSE} in {$ENDIF}');
  1067. end;
  1068. procedure TTestScanner.TestDefine14;
  1069. Const
  1070. Source = '{$ifdef NEVER_DEFINED}' +sLineBreak+
  1071. 'type'+sLineBreak+
  1072. ' TNPEventModel = ('+sLineBreak+
  1073. ' NPEventModelCarbon = 0,'+sLineBreak+
  1074. ' NPEventModelCocoa = 1'+sLineBreak+
  1075. '}; // yes, this is an error... except this code should never be included.'+sLineBreak+
  1076. 'ą'+sLineBreak+
  1077. '|'+sLineBreak+
  1078. '{$endif}'+sLineBreak+
  1079. ''+sLineBreak+
  1080. 'begin'+sLineBreak+
  1081. 'end.'+sLineBreak;
  1082. begin
  1083. NewSource(Source,True);
  1084. While FScanner.fetchToken<>tkEOF do
  1085. end;
  1086. procedure TTestScanner.TestInclude;
  1087. begin
  1088. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1089. FScanner.SkipWhiteSpace:=True;
  1090. FScanner.SkipComments:=True;
  1091. TestTokens([tkIf,tkTrue,tkThen],'{$I myinclude.inc}',True,False);
  1092. end;
  1093. procedure TTestScanner.TestInclude2;
  1094. begin
  1095. FResolver.AddStream('myinclude.inc',TStringStream.Create('if true then'));
  1096. FScanner.SkipWhiteSpace:=True;
  1097. FScanner.SkipComments:=True;
  1098. TestTokens([tkIf,tkTrue,tkThen,tkElse],'{$I myinclude.inc} else',True,False);
  1099. end;
  1100. procedure TTestScanner.TestUnDefine1;
  1101. begin
  1102. FSCanner.Defines.Add('ALWAYS');
  1103. TestTokens([tkComment],'{$UNDEF ALWAYS}');
  1104. AssertEquals('No more define',-1,FScanner.Defines.INdexOf('ALWAYS'));
  1105. end;
  1106. procedure TTestScanner.TestMacro1;
  1107. begin
  1108. FScanner.SkipWhiteSpace:=True;
  1109. FScanner.SkipComments:=True;
  1110. TestTokens([tkbegin,tkend,tkDot],'{$MACRO on}{$DEFINE MM:=begin end.}'#13#10'MM',True,False);
  1111. end;
  1112. procedure TTestScanner.TestMacro2;
  1113. begin
  1114. FScanner.SkipWhiteSpace:=True;
  1115. FScanner.SkipComments:=True;
  1116. TestTokens([tkbegin,tkend,tkDot],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'MM .',True,False);
  1117. end;
  1118. procedure TTestScanner.TestMacro3;
  1119. begin
  1120. FScanner.SkipComments:=True;
  1121. FScanner.SkipWhiteSpace:=True;
  1122. TestTokens([tkof],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'{$IFDEF MM} of {$ELSE} in {$ENDIF}');
  1123. end;
  1124. procedure TTestScanner.TestMacroHandling;
  1125. begin
  1126. TTestingPascalScanner(FScanner).DoSpecial:=True;
  1127. FScanner.SkipComments:=True;
  1128. FScanner.SkipWhiteSpace:=True;
  1129. TestTokens([tkIdentifier],'{$MACRO on}{$DEFINE MM:=begin end}'#13#10'MM');
  1130. AssertEQuals('Correct identifier', 'somethingweird',LastIdentifier);
  1131. end;
  1132. procedure TTestScanner.TestIFDefined;
  1133. begin
  1134. FScanner.SkipWhiteSpace:=True;
  1135. FScanner.SkipComments:=True;
  1136. TestTokens([tkbegin,tkend,tkDot],'{$DEFINE A}{$IF defined(A)}begin{$ENDIF}end.',True,False);
  1137. end;
  1138. procedure TTestScanner.TestIFUnDefined;
  1139. begin
  1140. FScanner.SkipWhiteSpace:=True;
  1141. FScanner.SkipComments:=True;
  1142. TestTokens([tkbegin,tkend,tkDot],'{$IF undefined(A)}begin{$ENDIF}end.',True,False);
  1143. end;
  1144. procedure TTestScanner.TestIFAnd;
  1145. begin
  1146. FScanner.SkipWhiteSpace:=True;
  1147. FScanner.SkipComments:=True;
  1148. TestTokens([tkbegin,tkend,tkDot],
  1149. '{$DEFINE A}{$IF defined(A) and undefined(B)}begin{$ENDIF}end.',True,False);
  1150. end;
  1151. procedure TTestScanner.TestIFAndShortEval;
  1152. begin
  1153. FScanner.SkipWhiteSpace:=True;
  1154. FScanner.SkipComments:=True;
  1155. TestTokens([tkbegin,tkend,tkDot],
  1156. '{$UNDEFINE A}{$IF defined(A) and undefined(B)}wrong{$ELSE}begin{$ENDIF}end.',
  1157. True,False);
  1158. end;
  1159. procedure TTestScanner.TestIFOr;
  1160. begin
  1161. FScanner.SkipWhiteSpace:=True;
  1162. FScanner.SkipComments:=True;
  1163. TestTokens([tkbegin,tkend,tkDot],
  1164. '{$DEFINE B}{$IF defined(A) or defined(B)}begin{$ENDIF}end.',True,False);
  1165. end;
  1166. procedure TTestScanner.TestIFOrShortEval;
  1167. begin
  1168. FScanner.SkipWhiteSpace:=True;
  1169. FScanner.SkipComments:=True;
  1170. TestTokens([tkbegin,tkend,tkDot],
  1171. '{$DEFINE A}{$IF defined(A) or defined(B)}begin{$ENDIF}end.',True,False);
  1172. end;
  1173. procedure TTestScanner.TestIFXor;
  1174. begin
  1175. FScanner.SkipWhiteSpace:=True;
  1176. FScanner.SkipComments:=True;
  1177. TestTokens([tkbegin,tkend,tkDot],
  1178. '{$DEFINE B}{$IF defined(A) xor defined(B)}begin{$ENDIF}end.',True,False);
  1179. end;
  1180. procedure TTestScanner.TestIFAndOr;
  1181. begin
  1182. FScanner.SkipWhiteSpace:=True;
  1183. FScanner.SkipComments:=True;
  1184. TestTokens([tkbegin,tkend,tkDot],
  1185. '{$IF defined(A) and defined(B) or defined(C)}wrong1{$ENDIF}'+LineEnding
  1186. +'{$IF defined(A) and defined(B) or undefined(C)}{$ELSE}wrong2{$ENDIF}'+LineEnding
  1187. +'{$IF defined(A) and undefined(B) or defined(C)}wrong3{$ENDIF}'+LineEnding
  1188. +'{$IF defined(A) and undefined(B) or undefined(C)}{$ELSE}wrong4{$ENDIF}'+LineEnding
  1189. +'{$IF undefined(A) and defined(B) or defined(C)}wrong5{$ENDIF}'+LineEnding
  1190. +'{$IF undefined(A) and defined(B) or undefined(C)}{$ELSE}wrong6{$ENDIF}'+LineEnding
  1191. +'{$IF undefined(A) and undefined(B) or defined(C)}{$ELSE}wrong7{$ENDIF}'+LineEnding
  1192. +'{$IF undefined(A) and undefined(B) or undefined(C)}begin{$ENDIF}end.',
  1193. True,False);
  1194. end;
  1195. procedure TTestScanner.TestIFEqual;
  1196. begin
  1197. FScanner.SkipWhiteSpace:=True;
  1198. FScanner.SkipComments:=True;
  1199. FScanner.AddMacro('Version','30101');
  1200. TestTokens([tkbegin,tkend,tkDot],
  1201. '{$IF Version=30101}begin{$ENDIF}end.',True,False);
  1202. end;
  1203. procedure TTestScanner.TestIFNotEqual;
  1204. begin
  1205. FScanner.SkipWhiteSpace:=True;
  1206. FScanner.SkipComments:=True;
  1207. FScanner.AddMacro('Version','30101');
  1208. TestTokens([tkbegin,tkend,tkDot],
  1209. '{$IF Version<>30000}begin{$ENDIF}end.',True,False);
  1210. end;
  1211. procedure TTestScanner.TestIFGreaterThan;
  1212. begin
  1213. FScanner.SkipWhiteSpace:=True;
  1214. FScanner.SkipComments:=True;
  1215. FScanner.AddMacro('Version','30101');
  1216. TestTokens([tkbegin,tkend,tkDot],
  1217. '{$IF Version>30000}begin{$ENDIF}end.',True,False);
  1218. end;
  1219. procedure TTestScanner.TestIFGreaterEqualThan;
  1220. begin
  1221. FScanner.SkipWhiteSpace:=True;
  1222. FScanner.SkipComments:=True;
  1223. FScanner.AddMacro('Version','30101');
  1224. TestTokens([tkbegin,tkend,tkDot],
  1225. '{$IF Version>=30000}begin{$ENDIF}end.',True,False);
  1226. end;
  1227. procedure TTestScanner.TestIFLesserThan;
  1228. begin
  1229. FScanner.SkipWhiteSpace:=True;
  1230. FScanner.SkipComments:=True;
  1231. FScanner.AddMacro('Version','30101');
  1232. TestTokens([tkbegin,tkend,tkDot],
  1233. '{$IF Version<40000}begin{$ENDIF}end.',True,False);
  1234. end;
  1235. procedure TTestScanner.TestIFLesserEqualThan;
  1236. begin
  1237. FScanner.SkipWhiteSpace:=True;
  1238. FScanner.SkipComments:=True;
  1239. FScanner.AddMacro('Version','30101');
  1240. TestTokens([tkbegin,tkend,tkDot],
  1241. '{$IF Version<=30101}begin{$ENDIF}end.',True,False);
  1242. end;
  1243. procedure TTestScanner.TestIFDefinedElseIf;
  1244. begin
  1245. FScanner.SkipWhiteSpace:=True;
  1246. FScanner.SkipComments:=True;
  1247. FScanner.AddDefine('cpu32');
  1248. TestTokens([tkconst,tkIdentifier,tkEqual,tkString,tkSemicolon,tkbegin,tkend,tkDot],
  1249. 'const platform = '+LineEnding
  1250. +'{$if defined(cpu32)} ''x86'''+LineEnding
  1251. +'{$elseif defined(cpu64)} ''x64'''+LineEnding
  1252. +'{$else} {$error unknown platform} {$endif};'+LineEnding
  1253. +'begin end.',True,False);
  1254. end;
  1255. procedure TTestScanner.TestIfError;
  1256. begin
  1257. FScanner.SkipWhiteSpace:=True;
  1258. FScanner.SkipComments:=True;
  1259. TestTokens([tkprogram,tkIdentifier,tkSemicolon,tkbegin,tkend,tkDot],
  1260. 'program Project1;'+LineEnding
  1261. +'begin'+LineEnding
  1262. +'{$if sizeof(integer) <> 4} {$error wrong sizeof(integer)} {$endif}'+LineEnding
  1263. +'end.',True,False);
  1264. end;
  1265. procedure TTestScanner.TestModeSwitch;
  1266. Const
  1267. PlusMinus = [' ','+','-'];
  1268. Var
  1269. M : TModeSwitch;
  1270. C : Char;
  1271. begin
  1272. For M in TModeSwitch do
  1273. for C in PlusMinus do
  1274. if SModeSwitchNames[M]<>'' then
  1275. begin
  1276. Scanner.CurrentModeSwitches:=[];
  1277. NewSource('{$MODESWITCH '+SModeSwitchNames[M]+' '+C+'}');
  1278. While not (Scanner.FetchToken=tkEOF) do;
  1279. if C in [' ','+'] then
  1280. AssertTrue(SModeSwitchNames[M]+C+' sets '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches)
  1281. else
  1282. AssertFalse(SModeSwitchNames[M]+C+' removes '+GetEnumName(TypeInfo(TModeSwitch),Ord(M)),M in Scanner.CurrentModeSwitches);
  1283. end;
  1284. end;
  1285. initialization
  1286. RegisterTests([TTestTokenFinder,TTestStreamLineReader,TTestScanner]);
  1287. end.