scanner.pas 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336
  1. {
  2. $Id$
  3. Copyright (c) 1993,97 by Florian Klaempfl
  4. This unit implements the scanner part and handling of the switches
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit scanner;
  19. interface
  20. uses
  21. strings,dos,cobjects,globals,symtable,systems,files,verbose,link;
  22. const
  23. id_len = 14;
  24. type
  25. ident = string[id_len];
  26. const
  27. {$ifdef L_C}
  28. anz_keywords = 32;
  29. keyword : array[1..anz_keywords] of ident = (
  30. 'auto','break','case','char','const','continue','default','do',
  31. 'double','else','enum','extern','float','for','goto','if',
  32. 'int','long','register','return','short','signed','sizeof','static',
  33. 'struct','switch','typedef','union','unsigned','void','volatile',
  34. 'while');
  35. {$else}
  36. anz_keywords = 71;
  37. keyword : array[1..anz_keywords] of ident = (
  38. { 'ABSOLUTE',}
  39. 'AND',
  40. 'ARRAY','AS','ASM',
  41. { 'ASSEMBLER',}
  42. 'BEGIN',
  43. 'BREAK','CASE','CLASS',
  44. 'CONST','CONSTRUCTOR','CONTINUE',
  45. 'DESTRUCTOR','DISPOSE','DIV','DO','DOWNTO','ELSE','END',
  46. 'EXCEPT',
  47. 'EXIT',
  48. { 'EXPORT',}
  49. 'EXPORTS',
  50. { 'EXTERNAL',}
  51. 'FAIL','FALSE',
  52. { 'FAR',}
  53. 'FILE','FINALLY','FOR',
  54. { 'FORWARD',}
  55. 'FUNCTION','GOTO','IF','IMPLEMENTATION','IN',
  56. 'INHERITED','INITIALIZATION',
  57. { 'INLINE',} {INLINE is a reserved word in TP. Why?}
  58. 'INTERFACE',
  59. { 'INTERRUPT',}
  60. 'IS',
  61. 'LABEL','LIBRARY','MOD',
  62. { 'NEAR',}
  63. 'NEW','NIL','NOT','OBJECT',
  64. 'OF','ON','OPERATOR','OR','OTHERWISE','PACKED',
  65. 'PROCEDURE','PROGRAM','PROPERTY',
  66. 'RAISE','RECORD','REPEAT','SELF',
  67. 'SET','SHL','SHR','STRING','THEN','TO',
  68. 'TRUE','TRY','TYPE','UNIT','UNTIL',
  69. 'USES','VAR',
  70. { 'VIRTUAL',}
  71. 'WHILE','WITH','XOR');
  72. {***}
  73. keyword_token : array[1..anz_keywords] of ttoken = (
  74. { _ABSOLUTE,}
  75. _AND,
  76. _ARRAY,_AS,_ASM,
  77. { _ASSEMBLER,}
  78. _BEGIN,
  79. _BREAK,_CASE,_CLASS,
  80. _CONST,_CONSTRUCTOR,_CONTINUE,
  81. _DESTRUCTOR,_DISPOSE,_DIV,_DO,_DOWNTO,
  82. _ELSE,_END,_EXCEPT,
  83. _EXIT,
  84. { _EXPORT,}
  85. _EXPORTS,
  86. { _EXTERNAL,}
  87. _FAIL,_FALSE,
  88. { _FAR,}
  89. _FILE,_FINALLY,_FOR,
  90. { _FORWARD,}
  91. _FUNCTION,_GOTO,_IF,_IMPLEMENTATION,_IN,
  92. _INHERITED,_INITIALIZATION,
  93. { _INLINE,}
  94. _INTERFACE,
  95. { _INTERRUPT,}
  96. _IS,
  97. _LABEL,_LIBRARY,_MOD,
  98. { _NEAR,}
  99. _NEW,_NIL,_NOT,_OBJECT,
  100. _OF,_ON,_OPERATOR,_OR,_OTHERWISE,_PACKED,
  101. _PROCEDURE,_PROGRAM,_PROPERTY,
  102. _RAISE,_RECORD,_REPEAT,_SELF,
  103. _SET,_SHL,_SHR,_STRING,_THEN,_TO,
  104. _TRUE,_TRY,_TYPE,_UNIT,_UNTIL,
  105. _USES,_VAR,
  106. { _VIRTUAL,}
  107. _WHILE,_WITH,_XOR);
  108. {$endif}
  109. function yylex : ttoken;
  110. procedure initscanner(const fn: string);
  111. procedure donescanner(compiled_at_higher_level : boolean);
  112. { the asm parser use this function getting the input }
  113. function asmgetchar : char;
  114. { this procedure is called at the end of each line }
  115. { and the function does the statistics }
  116. procedure write_line;
  117. { this procedure must be called before starting another scanner }
  118. procedure update_line;
  119. type
  120. tpreproctoken = (PP_IFDEF,PP_IFNDEF,PP_ELSE,PP_ENDIF,PP_IFOPT);
  121. ppreprocstack = ^tpreprocstack;
  122. tpreprocstack = object
  123. t : tpreproctoken;
  124. accept : boolean;
  125. next : ppreprocstack;
  126. name : string;
  127. line_nb : longint;
  128. constructor init(_t : tpreproctoken;a : boolean;n : ppreprocstack);
  129. destructor done;
  130. end;
  131. var
  132. pattern,orgpattern : string;
  133. { true, if type declarations are parsed }
  134. parse_types : boolean;
  135. { macros }
  136. const
  137. {$ifdef TP}
  138. maxmacrolen = 1024;
  139. {$else}
  140. maxmacrolen = 16*1024;
  141. {$endif}
  142. type
  143. tmacrobuffer = array[0..maxmacrolen-1] of char;
  144. var
  145. macropos : longint;
  146. macrobuffer : ^tmacrobuffer;
  147. preprocstack : ppreprocstack;
  148. inputbuffer : pchar;
  149. inputpointer : word;
  150. s_point : boolean;
  151. c : char;
  152. comment_level : word;
  153. {this is usefull to get the write filename
  154. for the last instruction of an include file !}
  155. Const FileHasChanged : Boolean = False;
  156. implementation
  157. const
  158. newline = #10;
  159. { const
  160. line_count : longint = 0; stored in tinputfile }
  161. { used to get better line info }
  162. procedure update_line;
  163. begin
  164. inc(current_module^.current_inputfile^.line_no,
  165. current_module^.current_inputfile^.line_count);
  166. current_module^.current_inputfile^.line_count:=0;
  167. end;
  168. procedure reload;
  169. var
  170. readsize : word;
  171. i : longint;
  172. begin
  173. if filehaschanged then
  174. begin
  175. {$ifdef EXTDEBUG}
  176. writeln ('Note: Finished reading ',current_module^.current_inputfile^.name^);
  177. write (' Coming back to ');
  178. current_module^.current_inputfile^.next^.write_file_line(output);
  179. writeln;
  180. {$endif EXTDEBUG}
  181. current_module^.current_inputfile:=current_module^.current_inputfile^.next;
  182. { this was missing !}
  183. c:=inputbuffer[inputpointer];
  184. inc(inputpointer);
  185. {$ifdef EXTDEBUG}
  186. write('Next 16 char "');
  187. for i:=-1 to 14 do
  188. write(inputbuffer[inputpointer+i]);
  189. writeln('"');
  190. {$endif EXTDEBUG}
  191. filehaschanged:=false;
  192. exit;
  193. end;
  194. if current_module^.current_inputfile=nil then
  195. internalerror(14);
  196. if current_module^.current_inputfile^.filenotatend then
  197. begin
  198. { load the next piece of source }
  199. blockread(current_module^.current_inputfile^.f,inputbuffer^,
  200. current_module^.current_inputfile^.bufsize-1,readsize);
  201. { check if non-empty file }
  202. if readsize > 0 then
  203. begin
  204. { check if null character before readsize }
  205. { this mixed up the scanner.. }
  206. for i:=0 to (readsize-1) do
  207. begin
  208. if inputbuffer[i] = #0 then
  209. Message(scan_f_illegal_char);
  210. end;
  211. end;
  212. inputbuffer[readsize]:=#0;
  213. c:=inputbuffer[0];
  214. { inputpointer points always to the _next_ character to read }
  215. inputpointer:=1;
  216. if eof(current_module^.current_inputfile^.f) then
  217. begin
  218. current_module^.current_inputfile^.filenotatend:=false;
  219. { if this is the main source file then EOF }
  220. if current_module^.current_inputfile^.next=nil then
  221. inputbuffer[readsize]:=#26;
  222. end;
  223. end
  224. else
  225. begin
  226. current_module^.current_inputfile^.close;
  227. inputbuffer:=current_module^.current_inputfile^.next^.buf;
  228. inputpointer:=current_module^.current_inputfile^.next^.bufpos;
  229. if assigned(current_module^.current_inputfile^.next) then
  230. begin
  231. c:=inputbuffer[inputpointer];
  232. filehaschanged:=True;
  233. {$ifdef EXTDEBUG}
  234. write('Next 16 char "');
  235. for i := 0 to 15 do write(inputbuffer[inputpointer+i]);
  236. writeln('"');
  237. {$endif}
  238. inputbuffer[inputpointer] := #0;
  239. { if c=newline writeline is called but increment the old
  240. inputstack instead of the new one }
  241. if c=newline then
  242. begin
  243. inc(current_module^.current_inputfile^.next^.line_no);
  244. dec(current_module^.current_inputfile^.line_no);
  245. end;
  246. end;
  247. end;
  248. end;
  249. procedure write_line;
  250. var
  251. status : tcompilestatus;
  252. begin
  253. {$ifdef ver0_6}
  254. status.totalcompiledlines:=abslines;
  255. status.currentline:=current_module^.current_inputfile^.line_no
  256. +current_module^.current_inputfile^.line_count;
  257. status.currentsource:=current_module^.current_inputfile^.name^+current_module^.current_inputfile^.ext^;
  258. status.totallines:=0;
  259. {$else}
  260. with status do
  261. begin
  262. totalcompiledlines:=abslines;
  263. currentline:=current_module^.current_inputfile^.line_no
  264. +current_module^.current_inputfile^.line_count;
  265. currentsource:=current_module^.current_inputfile^.name^+current_module^.current_inputfile^.ext^;
  266. totallines:=0;
  267. end;
  268. {$endif}
  269. if compilestatusproc(status) then
  270. stop;
  271. inc(current_module^.current_inputfile^.line_count);
  272. lastlinepointer:=inputpointer;
  273. inc(abslines);
  274. end;
  275. procedure src_comment;forward;
  276. procedure nextchar;
  277. begin
  278. c:=inputbuffer[inputpointer];
  279. inc(inputpointer);
  280. if c=#0 then
  281. reload;
  282. if c in [#10,#13] then
  283. begin
  284. if (byte(inputbuffer[inputpointer])+byte(c)=23) then
  285. inc(inputpointer);
  286. write_line;
  287. c:=newline;
  288. end;
  289. end;
  290. procedure skipspace;
  291. var
  292. lastc : byte;
  293. begin
  294. lastc:=0;
  295. while c in [' ',#9,#10,#12,#13] do
  296. begin
  297. nextchar;
  298. if c='{' then
  299. src_comment;
  300. end;
  301. end;
  302. function is_keyword(var token : ttoken) : boolean;
  303. var
  304. m,n,k : integer;
  305. begin
  306. { there are no keywords with a length less than 2 }
  307. if length(pattern)<=1 then
  308. begin
  309. is_keyword:=false;
  310. exit;
  311. end;
  312. m:=1;
  313. n:=anz_keywords;
  314. while m<=n do
  315. begin
  316. k:=m+(n-m) shr 1;
  317. if pattern=keyword[k] then
  318. begin
  319. token:=keyword_token[k];
  320. is_keyword:=true;
  321. exit;
  322. end
  323. else if pattern>keyword[k] then m:=k+1 else n:=k-1;
  324. end;
  325. is_keyword:=false;
  326. end;
  327. {*****************************************************************************
  328. Preprocessor
  329. *****************************************************************************}
  330. function readmessage:string;
  331. var
  332. i : longint;
  333. begin
  334. i:=0;
  335. repeat
  336. case c of
  337. '}' : break;
  338. #26 : Message(scan_f_end_of_file);
  339. else
  340. begin
  341. if (i<255) then
  342. begin
  343. inc(i);
  344. readmessage[i]:=c;
  345. end;
  346. end;
  347. end;
  348. nextchar;
  349. until false;
  350. readmessage[0]:=chr(i);
  351. end;
  352. constructor tpreprocstack.init(_t : tpreproctoken;a : boolean;n : ppreprocstack);
  353. begin
  354. t:=_t;
  355. accept:=a;
  356. next:=n;
  357. end;
  358. destructor tpreprocstack.done;
  359. begin
  360. end;
  361. procedure dec_comment_level;
  362. begin
  363. if cs_tp_compatible in aktswitches then
  364. comment_level:=0
  365. else
  366. dec(comment_level);
  367. end;
  368. procedure handle_switches;
  369. function read_original_string : string;
  370. var
  371. hs : string;
  372. begin
  373. hs:='';
  374. while c in ['A'..'Z','a'..'z','_','0'..'9'] do
  375. begin
  376. hs:=hs+c;
  377. nextchar;
  378. end;
  379. read_original_string:=hs;
  380. end;
  381. function read_string : string;
  382. begin
  383. read_string:=upper(read_original_string);
  384. end;
  385. function read_number : longint;
  386. var
  387. hs : string;
  388. l : longint;
  389. w : word;
  390. begin
  391. read_number:=0;
  392. hs:='';
  393. while c in ['0'..'9'] do
  394. begin
  395. hs:=hs+c;
  396. nextchar;
  397. end;
  398. valint(hs,l,w);
  399. read_number:=l;
  400. end;
  401. var
  402. preprocpat : string;
  403. preproc_token : ttoken;
  404. function read_preproc : ttoken;
  405. { var
  406. y : ttoken;
  407. code : word;
  408. l : longint;
  409. hs : string;
  410. hp : pinputfile;
  411. hp2 : pchar;}
  412. label
  413. preproc_exit;
  414. begin
  415. while c in [' ',#9,#13,#12,#10] do
  416. begin
  417. { if c=#10 then write_line;}
  418. nextchar;
  419. end;
  420. case c of
  421. 'A'..'Z','a'..'z','_','0'..'9' :
  422. begin
  423. preprocpat:=c;
  424. nextchar;
  425. while c in ['A'..'Z','a'..'z','0'..'9','_'] do
  426. begin
  427. preprocpat:=preprocpat+c;
  428. nextchar;
  429. end;
  430. uppervar(preprocpat);
  431. read_preproc:=ID;
  432. goto preproc_exit;
  433. end;
  434. '(' : begin
  435. nextchar;
  436. read_preproc:=LKLAMMER;
  437. goto preproc_exit;
  438. end;
  439. ')' : begin
  440. nextchar;
  441. read_preproc:=RKLAMMER;
  442. goto preproc_exit;
  443. end;
  444. '+' : begin
  445. nextchar;
  446. read_preproc:=PLUS;
  447. goto preproc_exit;
  448. end;
  449. '-' : begin
  450. nextchar;
  451. read_preproc:=MINUS;
  452. goto preproc_exit;
  453. end;
  454. '*' : begin
  455. nextchar;
  456. read_preproc:=STAR;
  457. goto preproc_exit;
  458. end;
  459. '/' : begin
  460. nextchar;
  461. read_preproc:=SLASH;
  462. goto preproc_exit;
  463. end;
  464. '=' : begin
  465. nextchar;
  466. read_preproc:=EQUAL;
  467. goto preproc_exit;
  468. end;
  469. '>' : begin
  470. nextchar;
  471. if c='=' then
  472. begin
  473. nextchar;
  474. read_preproc:=GTE;
  475. goto preproc_exit;
  476. end
  477. else
  478. begin
  479. read_preproc:=GT;
  480. goto preproc_exit;
  481. end;
  482. end;
  483. '<' : begin
  484. nextchar;
  485. if c='>' then
  486. begin
  487. nextchar;
  488. read_preproc:=UNEQUAL;
  489. goto preproc_exit;
  490. end
  491. else if c='=' then
  492. begin
  493. nextchar;
  494. read_preproc:=LTE;
  495. goto preproc_exit;
  496. end
  497. else
  498. begin
  499. read_preproc:=LT;
  500. goto preproc_exit;
  501. end;
  502. end;
  503. #26:
  504. begin
  505. update_line;
  506. Message(scan_f_end_of_file);
  507. end
  508. else
  509. begin
  510. read_preproc:=_EOF;
  511. end;
  512. end;
  513. preproc_exit :
  514. update_line;
  515. end;
  516. procedure preproc_consume(t : ttoken);
  517. begin
  518. if t<>preproc_token then
  519. Message(scan_e_preproc_syntax_error);
  520. preproc_token:=read_preproc;
  521. end;
  522. function read_expr : string;forward;
  523. function read_factor : string;
  524. var
  525. hs : string;
  526. mac : pmacrosym;
  527. len : byte;
  528. begin
  529. if preproc_token=ID then
  530. begin
  531. if preprocpat='NOT' then
  532. begin
  533. preproc_consume(ID);
  534. hs:=read_expr;
  535. if hs='0' then
  536. read_factor:='1'
  537. else
  538. read_factor:='0';
  539. end
  540. else
  541. begin
  542. mac:=pmacrosym(macros^.search(hs));
  543. hs:=preprocpat;
  544. preproc_consume(ID);
  545. if assigned(mac) then
  546. begin
  547. if mac^.defined and assigned(mac^.buftext) then
  548. begin
  549. if mac^.buflen>255 then
  550. begin
  551. len:=255;
  552. Message(scan_w_marco_cut_after_255_chars);
  553. end
  554. else
  555. len:=mac^.buflen;
  556. hs[0]:=char(len);
  557. move(mac^.buftext^,hs[1],len);
  558. end
  559. else
  560. read_factor:='';
  561. end
  562. else
  563. read_factor:=hs;
  564. end
  565. end
  566. else if preproc_token=LKLAMMER then
  567. begin
  568. preproc_consume(LKLAMMER);
  569. read_factor:=read_expr;
  570. preproc_consume(RKLAMMER);
  571. end
  572. else
  573. Message(scan_e_error_in_preproc_expr);
  574. end;
  575. function read_term : string;
  576. var
  577. hs1,hs2 : string;
  578. begin
  579. hs1:=read_factor;
  580. while true do
  581. begin
  582. if (preproc_token=ID) then
  583. begin
  584. if preprocpat='AND' then
  585. begin
  586. preproc_consume(ID);
  587. hs2:=read_factor;
  588. if (hs1<>'0') and (hs2<>'0') then
  589. hs1:='1';
  590. end
  591. else
  592. break;
  593. end
  594. else
  595. break;
  596. end;
  597. read_term:=hs1;
  598. end;
  599. function read_simple_expr : string;
  600. var
  601. hs1,hs2 : string;
  602. begin
  603. hs1:=read_term;
  604. while true do
  605. begin
  606. if (preproc_token=ID) then
  607. begin
  608. if preprocpat='OR' then
  609. begin
  610. preproc_consume(ID);
  611. hs2:=read_term;
  612. if (hs1<>'0') or (hs2<>'0') then
  613. hs1:='1';
  614. end
  615. else
  616. break;
  617. end
  618. else
  619. break;
  620. end;
  621. read_simple_expr:=hs1;
  622. end;
  623. function read_expr : string;
  624. var
  625. hs1,hs2 : string;
  626. b : boolean;
  627. t : ttoken;
  628. w : word;
  629. l1,l2 : longint;
  630. begin
  631. hs1:=read_simple_expr;
  632. t:=preproc_token;
  633. if not(t in [EQUAL,UNEQUAL,LT,GT,LTE,GTE]) then
  634. begin
  635. read_expr:=hs1;
  636. exit;
  637. end;
  638. preproc_consume(t);
  639. hs2:=read_simple_expr;
  640. if is_number(hs1) and is_number(hs2) then
  641. begin
  642. valint(hs1,l1,w);
  643. valint(hs2,l2,w);
  644. case t of
  645. EQUAL:
  646. b:=l1=l2;
  647. UNEQUAL:
  648. b:=l1<>l2;
  649. LT:
  650. b:=l1<l2;
  651. GT:
  652. b:=l1>l2;
  653. GTE:
  654. b:=l1>=l2;
  655. LTE:
  656. b:=l1<=l2;
  657. end;
  658. end
  659. else
  660. begin
  661. case t of
  662. EQUAL:
  663. b:=hs1=hs2;
  664. UNEQUAL:
  665. b:=hs1<>hs2;
  666. LT:
  667. b:=hs1<hs2;
  668. GT:
  669. b:=hs1>hs2;
  670. GTE:
  671. b:=hs1>=hs2;
  672. LTE:
  673. b:=hs1<=hs2;
  674. end;
  675. end;
  676. if b then
  677. read_expr:='1'
  678. else
  679. read_expr:='0';
  680. end;
  681. procedure skip_until_pragma;
  682. var
  683. found : longint;
  684. begin
  685. found:=0;
  686. repeat
  687. case c of
  688. #26 : Message(scan_f_end_of_file);
  689. { newline : begin
  690. write_line;
  691. found:=0;
  692. end; }
  693. '{' : begin
  694. if comment_level=0 then
  695. found:=1;
  696. inc(comment_level);
  697. end;
  698. '}' : begin
  699. dec_comment_level;
  700. found:=0;
  701. end;
  702. '$' : begin
  703. if found=1 then
  704. found:=2;
  705. end;
  706. else
  707. found:=0;
  708. end;
  709. nextchar;
  710. until (found=2);
  711. update_line;
  712. end;
  713. function Is_conditional(const hs:string):boolean;
  714. begin
  715. Is_Conditional:=((hs='ELSE') or (hs='IFDEF') or (hs='IFNDEF') or
  716. (hs='IFOPT') or (hs='ENDIF') or (hs='ELSE') or (hs='IF'));
  717. end;
  718. var
  719. path,hs : string;
  720. hp : pinputfile;
  721. mac : pmacrosym;
  722. found : boolean;
  723. ht : ttoken;
  724. procedure popstack;
  725. var
  726. hp : ppreprocstack;
  727. begin
  728. hp:=preprocstack^.next;
  729. dispose(preprocstack,done);
  730. preprocstack:=hp;
  731. end;
  732. var
  733. _d : dirstr;
  734. _n : namestr;
  735. _e : extstr;
  736. hs2,
  737. msg : string;
  738. begin
  739. nextchar;
  740. hs:=read_string;
  741. update_line;
  742. Message1(scan_d_handling_switch,hs);
  743. if hs='I' then
  744. begin
  745. skipspace;
  746. hs:=c;
  747. nextchar;
  748. while not(c in [' ','}','*',#13,newline]) do
  749. begin
  750. hs:=hs+c;
  751. nextchar;
  752. if c=#26 then Message(scan_f_end_of_file);
  753. end;
  754. { if c=newline then write_line;}
  755. { read until end of comment }
  756. while c<>'}' do
  757. begin
  758. nextchar;
  759. if c=#26 then Message(scan_f_end_of_file);
  760. { if c=newline then write_line;}
  761. end;
  762. {
  763. dec(comment_level);
  764. }
  765. { Initialization }
  766. if (hs[1]='-') then
  767. {exclude(aktswitches,cs_iocheck) Not yet supported.}
  768. aktswitches:=aktswitches-[cs_iocheck]
  769. else if (hs[1]='+') then
  770. {include(aktswitches,cs_iocheck) Not supported yet.}
  771. aktswitches:=aktswitches+[cs_iocheck]
  772. else
  773. begin
  774. fsplit(hs,_d,_n,_e);
  775. update_line;
  776. { directory where the current file is first inspected }
  777. path:=search(hs,current_module^.current_inputfile^.path^,found);
  778. if found then
  779. hp:=new(pinputfile,init(path+_d,_n,_e))
  780. else
  781. begin
  782. path:=search(hs,includesearchpath,found);
  783. hp:=new(pinputfile,init(path+_d,_n,_e));
  784. end;
  785. hp^.reset;
  786. if ioresult=0 then
  787. begin
  788. current_module^.current_inputfile^.bufpos:=inputpointer;
  789. hp^.next:=current_module^.current_inputfile;
  790. current_module^.current_inputfile:=hp;
  791. current_module^.sourcefiles.register_file(hp);
  792. inputbuffer:=current_module^.current_inputfile^.buf;
  793. Message1(scan_u_start_include_file,current_module^.current_inputfile^.name^);
  794. reload;
  795. { we have read the }
  796. { comment end }
  797. dec_comment_level;
  798. { only warn for over one => incompatible with BP }
  799. if (comment_level>1) then
  800. Message1(scan_w_comment_level,tostr(comment_level));
  801. end
  802. else
  803. Message1(scan_f_cannot_open_includefile,_d+_n+_e);
  804. end;
  805. end
  806. { conditional compiling ? }
  807. else if Is_Conditional(hs) then
  808. begin
  809. while true do
  810. begin
  811. if hs='ENDIF' then
  812. begin
  813. { we can always accept an ELSE }
  814. if assigned(preprocstack) then
  815. begin
  816. Message1(scan_c_endif_found,preprocstack^.name);
  817. if preprocstack^.t=PP_ELSE then
  818. popstack;
  819. end
  820. else
  821. Message(scan_e_endif_without_if);
  822. { now pop the condition }
  823. if assigned(preprocstack) then
  824. begin
  825. { we only use $ifdef in the stack }
  826. if (preprocstack^.t=PP_IFDEF) then
  827. popstack
  828. else
  829. Message(scan_e_too_much_endifs);
  830. end
  831. else
  832. Message(scan_e_endif_without_if);
  833. end
  834. else if hs='IFDEF' then
  835. begin
  836. skipspace;
  837. hs:=read_string;
  838. mac:=pmacrosym(macros^.search(hs));
  839. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  840. { the block before must be accepted }
  841. { the symbole must be exist and be defined }
  842. (
  843. (preprocstack=nil) or
  844. preprocstack^.accept
  845. ) and
  846. assigned(mac) and
  847. mac^.defined,
  848. preprocstack));
  849. preprocstack^.name:=hs;
  850. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  851. if preprocstack^.accept then
  852. Message2(scan_c_ifdef_found,preprocstack^.name,'accepted')
  853. else
  854. Message2(scan_c_ifdef_found,preprocstack^.name,'rejected');
  855. end
  856. else if hs='IFOPT' then
  857. begin
  858. skipspace;
  859. hs:=read_string;
  860. { !!!! read switch state }
  861. { PP_IFDEF is correct, we doesn't distinguish between }
  862. { ifopt and ifdef }
  863. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  864. { the block before must be accepted }
  865. (
  866. (preprocstack=nil) or
  867. preprocstack^.accept
  868. ) and
  869. { !!!! subject to change: }
  870. false,
  871. preprocstack));
  872. preprocstack^.name:=hs;
  873. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  874. if preprocstack^.accept then
  875. Message2(scan_c_ifopt_found,preprocstack^.name,'accepted')
  876. else
  877. Message2(scan_c_ifopt_found,preprocstack^.name,'rejected');
  878. end
  879. else if hs='IF' then
  880. begin
  881. skipspace;
  882. { start preproc expression scanner }
  883. preproc_token:=read_preproc;
  884. hs:=read_expr;
  885. { PP_IFDEF is correct, we doesn't distinguish between }
  886. { if, ifopt and ifdef }
  887. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  888. { the block before must be accepted }
  889. (
  890. (preprocstack=nil) or
  891. preprocstack^.accept
  892. ) and
  893. (hs<>'0'),
  894. preprocstack));
  895. preprocstack^.name:=hs;
  896. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  897. if preprocstack^.accept then
  898. Message2(scan_c_if_found,preprocstack^.name,'accepted')
  899. else
  900. Message2(scan_c_if_found,preprocstack^.name,'rejected');
  901. end
  902. else if hs='IFNDEF' then
  903. begin
  904. skipspace;
  905. hs:=read_string;
  906. mac:=pmacrosym(macros^.search(hs));
  907. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  908. { the block before must be accepted }
  909. (
  910. (preprocstack=nil) or
  911. preprocstack^.accept
  912. ) and
  913. not(assigned(mac) and
  914. mac^.defined),
  915. preprocstack));
  916. preprocstack^.name:=hs;
  917. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  918. if preprocstack^.accept then
  919. Message2(scan_c_ifndef_found,preprocstack^.name,'accepted')
  920. else
  921. Message2(scan_c_ifndef_found,preprocstack^.name,'rejected');
  922. end
  923. else if hs='ELSE' then
  924. begin
  925. if assigned(preprocstack) then
  926. begin
  927. preprocstack:=new(ppreprocstack,init(PP_ELSE,
  928. { invert }
  929. not(preprocstack^.accept) and
  930. { but only true, if only the ifdef block is }
  931. { not accepted }
  932. (
  933. (preprocstack^.next=nil) or
  934. (preprocstack^.next^.accept)
  935. ),
  936. preprocstack));
  937. preprocstack^.line_nb := current_module^.current_inputfile^.line_no;
  938. preprocstack^.name := preprocstack^.next^.name;
  939. if preprocstack^.accept then
  940. Message2(scan_c_else_found,preprocstack^.name,'accepted')
  941. else
  942. Message2(scan_c_else_found,preprocstack^.name,'rejected');
  943. end
  944. else
  945. Message(scan_e_endif_without_if);
  946. end
  947. else if hs='IFOPT' then
  948. begin
  949. skipspace;
  950. hs:=read_string;
  951. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  952. false,
  953. preprocstack));
  954. end;
  955. { accept the text ? }
  956. if (preprocstack=nil) or preprocstack^.accept then
  957. break
  958. else
  959. begin
  960. Message(scan_c_skipping_until);
  961. repeat
  962. skip_until_pragma;
  963. hs:=read_string;
  964. until Is_Conditional(hs);
  965. end;
  966. end;
  967. end
  968. else if (hs='WAIT') then
  969. begin
  970. Message(scan_i_press_enter);
  971. readln;
  972. end
  973. else if (hs='INFO') or (hs='MESSAGE') then
  974. begin
  975. skipspace;
  976. Message1(scan_i_user_defined,readmessage);
  977. end
  978. else if hs='NOTE' then
  979. begin
  980. skipspace;
  981. Message1(scan_n_user_defined,readmessage);
  982. end
  983. else if hs='WARNING' then
  984. begin
  985. skipspace;
  986. Message1(scan_w_user_defined,readmessage);
  987. end
  988. else if hs='ERROR' then
  989. begin
  990. skipspace;
  991. Message1(scan_e_user_defined,readmessage);
  992. end
  993. else if (hs='FATALERROR') or (hs='STOP') then
  994. begin
  995. skipspace;
  996. Message1(scan_f_user_defined,readmessage);
  997. end
  998. else if hs='L' then
  999. begin
  1000. skipspace;
  1001. hs:='';
  1002. while not(c in [' ','}',#9,newline,#13]) do
  1003. begin
  1004. hs:=hs+c;
  1005. nextchar;
  1006. if c=#26 then Message(scan_f_end_of_file);
  1007. end;
  1008. hs:=FixFileName(hs);
  1009. if not path_absolute(hs) and (current_module^.current_inputfile^.path<>nil) then
  1010. path:=search(hs,current_module^.current_inputfile^.path^+';'+objectsearchpath,found);
  1011. Linker.AddObjectFile(path+hs);
  1012. current_module^.linkofiles.insert(hs);
  1013. end
  1014. else if hs='D' then
  1015. begin
  1016. if current_module^.in_main then
  1017. Message(scan_w_switch_is_global)
  1018. else
  1019. begin
  1020. if c='-' then
  1021. aktswitches:=aktswitches-[cs_debuginfo]
  1022. else
  1023. aktswitches:=aktswitches+[cs_debuginfo];
  1024. end;
  1025. end
  1026. else if hs='R' then
  1027. begin
  1028. if c='-' then
  1029. {exclude(aktswitches,cs_rangechecking) Not yet supported.}
  1030. aktswitches:=aktswitches-[cs_rangechecking]
  1031. else
  1032. {include(aktswitches,cs_rangechecking); Not yet supported.}
  1033. aktswitches:=aktswitches+[cs_rangechecking];
  1034. end
  1035. else if hs='Q' then
  1036. begin
  1037. if c='-' then
  1038. {include(aktswitches,cs_check_overflow) Not yet supported.}
  1039. aktswitches:=aktswitches-[cs_check_overflow]
  1040. else
  1041. {include(aktswitches,cs_check_overflow); Not yet supported.}
  1042. aktswitches:=aktswitches+[cs_check_overflow]
  1043. end
  1044. else if hs='T' then
  1045. begin
  1046. if c='-' then
  1047. aktswitches:=aktswitches-[cs_typed_addresses]
  1048. else
  1049. aktswitches:=aktswitches+[cs_typed_addresses]
  1050. end
  1051. else if hs='V' then
  1052. begin
  1053. if c='-' then
  1054. aktswitches:=aktswitches-[cs_strict_var_strings]
  1055. else
  1056. aktswitches:=aktswitches+[cs_strict_var_strings]
  1057. end
  1058. else if hs='F' then
  1059. begin
  1060. Message(scan_n_far_directive_ignored);
  1061. end
  1062. else if hs='S' then
  1063. begin
  1064. if target_info.target<>target_linux then
  1065. begin
  1066. case c of
  1067. '-' : aktswitches:=aktswitches-[cs_check_stack];
  1068. '+' : aktswitches:=aktswitches+[cs_check_stack];
  1069. else
  1070. Message(scan_w_illegal_switch);
  1071. end;
  1072. end
  1073. else
  1074. begin
  1075. if c in ['+','-'] then
  1076. Message(scan_n_stack_check_global_under_linux)
  1077. else
  1078. Message(scan_w_illegal_switch);
  1079. end;
  1080. end
  1081. else if hs='E' then
  1082. begin
  1083. { This is a global switch which affects all units }
  1084. if ((current_module = main_module) and (main_module^.in_main = false)) then
  1085. begin
  1086. case c of
  1087. '-' : aktswitches:=aktswitches-[cs_fp_emulation];
  1088. '+' : aktswitches:=aktswitches+[cs_fp_emulation];
  1089. else
  1090. Message(scan_w_illegal_switch);
  1091. end;
  1092. end
  1093. else
  1094. Message(scan_w_switch_is_global);
  1095. end
  1096. else if hs='X' then
  1097. begin
  1098. { This is a global switch which only affects the unit/program }
  1099. { being compiled }
  1100. if not (current_module^.in_main) then
  1101. begin
  1102. case c of
  1103. '-' : aktswitches:=aktswitches-[cs_extsyntax];
  1104. '+' : aktswitches:=aktswitches+[cs_extsyntax];
  1105. else
  1106. Message(scan_w_illegal_switch);
  1107. end;
  1108. end
  1109. else
  1110. Message(scan_w_switch_is_global);
  1111. end
  1112. else if hs='LINKLIB' then
  1113. begin
  1114. skipspace;
  1115. hs:=read_original_string;
  1116. Linker.AddLibraryFile(hs);
  1117. current_module^.linklibfiles.insert(hs);
  1118. end
  1119. {$ifdef i386}
  1120. else if hs='OUTPUT_FORMAT' then
  1121. begin
  1122. { this is a global switch }
  1123. if current_module^.in_main then
  1124. Message(scan_w_switch_is_global)
  1125. else
  1126. begin
  1127. skipspace;
  1128. hs:=upper(read_string);
  1129. if hs='NASM' then
  1130. current_module^.output_format:=of_nasm
  1131. else if hs='MASM' then
  1132. current_module^.output_format:=of_masm
  1133. else if hs='O' then
  1134. current_module^.output_format:=of_o
  1135. else if hs='OBJ' then
  1136. current_module^.output_format:=of_obj
  1137. else
  1138. Message(scan_w_illegal_switch);
  1139. end;
  1140. { for use in globals }
  1141. output_format:=current_module^.output_format;
  1142. end
  1143. {$endif}
  1144. {$ifdef SUPPORT_MMX}
  1145. else if hs='MMX' then
  1146. begin
  1147. if c='-' then
  1148. aktswitches:=aktswitches-[cs_mmx]
  1149. else
  1150. aktswitches:=aktswitches+[cs_mmx];
  1151. end
  1152. else if hs='SATURATION' then
  1153. begin
  1154. if c='-' then
  1155. aktswitches:=aktswitches-[cs_mmx_saturation]
  1156. else
  1157. aktswitches:=aktswitches+[cs_mmx_saturation];
  1158. end
  1159. {$endif SUPPORT_MMX}
  1160. else if hs='DEFINE' then
  1161. begin
  1162. skipspace;
  1163. hs:=read_string;
  1164. mac:=pmacrosym(macros^.search(hs));
  1165. if not assigned(mac) then
  1166. begin
  1167. mac:=new(pmacrosym,init(hs));
  1168. mac^.defined:=true;
  1169. Message1(parser_m_macro_defined,mac^.name);
  1170. macros^.insert(mac);
  1171. end
  1172. else
  1173. begin
  1174. Message1(parser_m_macro_defined,mac^.name);
  1175. mac^.defined:=true;
  1176. { delete old definition }
  1177. if assigned(mac^.buftext) then
  1178. begin
  1179. freemem(mac^.buftext,mac^.buflen);
  1180. mac^.buftext:=nil;
  1181. end;
  1182. end;
  1183. if support_macros then
  1184. begin
  1185. { key words are never substituted }
  1186. hs2:=pattern;
  1187. pattern:=hs;
  1188. if is_keyword(ht) then
  1189. Message(scan_e_keyword_cant_be_a_macro);
  1190. pattern:=hs2;
  1191. skipspace;
  1192. { !!!!!! handle macro params, need we this? }
  1193. { may be a macro? }
  1194. if c=':' then
  1195. begin
  1196. nextchar;
  1197. if c='=' then
  1198. begin
  1199. { first char }
  1200. nextchar;
  1201. macropos:=0;
  1202. while (c<>'}') do
  1203. begin
  1204. macrobuffer^[macropos]:=c;
  1205. { if c=newline then write_line;}
  1206. nextchar;
  1207. if c=#26 then Message(scan_f_end_of_file);
  1208. inc(macropos);
  1209. if macropos>maxmacrolen then
  1210. Message(scan_f_macro_buffer_overflow);
  1211. end;
  1212. { free buffer of macro ?}
  1213. if assigned(mac^.buftext) then
  1214. freemem(mac^.buftext,mac^.buflen);
  1215. { get new mem }
  1216. getmem(mac^.buftext,macropos);
  1217. mac^.buflen:=macropos;
  1218. { copy the text }
  1219. move(macrobuffer^,mac^.buftext^,macropos);
  1220. end;
  1221. end;
  1222. end;
  1223. end
  1224. else if hs='UNDEF' then
  1225. begin
  1226. skipspace;
  1227. hs:=read_string;
  1228. mac:=pmacrosym(macros^.search(hs));
  1229. if not assigned(mac) then
  1230. begin
  1231. mac:=new(pmacrosym,init(hs));
  1232. Message1(parser_m_macro_undefined,mac^.name);
  1233. mac^.defined:=false;
  1234. macros^.insert(mac);
  1235. end
  1236. else
  1237. begin
  1238. Message1(parser_m_macro_undefined,mac^.name);
  1239. mac^.defined:=false;
  1240. { delete old definition }
  1241. if assigned(mac^.buftext) then
  1242. begin
  1243. freemem(mac^.buftext,mac^.buflen);
  1244. mac^.buftext:=nil;
  1245. end;
  1246. end;
  1247. end
  1248. else if hs='PACKRECORDS' then
  1249. begin
  1250. skipspace;
  1251. if upcase(c)='N' then
  1252. begin
  1253. hs:=read_string;
  1254. if hs='NORMAL' then
  1255. aktpackrecords:=2
  1256. else
  1257. Message(scan_w_only_pack_records);
  1258. end
  1259. else
  1260. case read_number of
  1261. 1 : aktpackrecords:=1;
  1262. 2 : aktpackrecords:=2;
  1263. 4 : aktpackrecords:=4;
  1264. else Message(scan_w_only_pack_records);
  1265. end;
  1266. end
  1267. {$ifdef i386}
  1268. else if hs='I386_INTEL' then
  1269. aktasmmode:=I386_INTEL
  1270. else if hs='I386_DIRECT' then
  1271. aktasmmode:=I386_DIRECT
  1272. else if hs='I386_ATT' then
  1273. aktasmmode:=I386_ATT
  1274. {$endif}
  1275. else
  1276. begin
  1277. Message(scan_w_illegal_switch);
  1278. end;
  1279. end;
  1280. procedure src_comment;
  1281. begin
  1282. inc(comment_level);
  1283. { only warn for over one => incompatible with BP }
  1284. if (comment_level>1) then
  1285. Message1(scan_w_comment_level,tostr(comment_level));
  1286. nextchar;
  1287. while true do
  1288. begin
  1289. { handle compiler switches }
  1290. if (comment_level=1) and (c='$') then
  1291. handle_switches;
  1292. { handle_switches can dec comment_level, }
  1293. { if there is an include file }
  1294. while (c<>'}') and (comment_level>0) do
  1295. begin
  1296. if c='{' then
  1297. src_comment
  1298. else
  1299. begin
  1300. if c=#26 then Message(scan_f_end_of_file);
  1301. { if c=newline then write_line;}
  1302. nextchar;
  1303. end;
  1304. end;
  1305. { this is needed for the include files }
  1306. { if there is a end of comment then read it }
  1307. if c='}' then
  1308. begin
  1309. nextchar;
  1310. dec_comment_level;
  1311. { only warn for over one => incompatible with BP }
  1312. if (comment_level>1) then
  1313. Message1(scan_w_comment_level,tostr(comment_level));
  1314. end;
  1315. { checks }{ }
  1316. if c='{' then
  1317. begin
  1318. inc(comment_level);
  1319. { only warn for over one => incompatible with BP }
  1320. if (comment_level>1) then
  1321. Message1(scan_w_comment_level,tostr(comment_level));
  1322. nextchar;
  1323. end
  1324. else
  1325. break;
  1326. end;
  1327. end;
  1328. procedure delphi_comment;
  1329. begin
  1330. { C++/Delphi styled comment }
  1331. inc(comment_level);
  1332. nextchar;
  1333. { this is currently not supported }
  1334. if c='$' then
  1335. Message(scan_e_wrong_styled_switch);
  1336. while c<>newline do
  1337. begin
  1338. if c=#26 then Message(scan_f_end_of_file);
  1339. nextchar;
  1340. end;
  1341. dec(comment_level);
  1342. end;
  1343. const
  1344. yylexcount : longint = 0;
  1345. function yylex : ttoken;
  1346. var
  1347. y : ttoken;
  1348. code : word;
  1349. l : longint;
  1350. hs : string;
  1351. mac : pmacrosym;
  1352. hp : pinputfile;
  1353. hp2 : pchar;
  1354. label
  1355. yylex_exit;
  1356. begin
  1357. { was the last character a point ? }
  1358. { this code is needed because the scanner if there is a 1. found if }
  1359. { this is a floating point number or range like 1..3 }
  1360. if s_point then
  1361. begin
  1362. s_point:=false;
  1363. if c='.' then
  1364. begin
  1365. nextchar;
  1366. yylex:=POINTPOINT;
  1367. goto yylex_exit;
  1368. end;
  1369. yylex:=POINT;
  1370. goto yylex_exit;
  1371. end;
  1372. if c='{' then src_comment;
  1373. skipspace;
  1374. lasttokenpos:=inputpointer-1;
  1375. case c of
  1376. 'A'..'Z','a'..'z','_' :
  1377. begin
  1378. orgpattern:=c;
  1379. nextchar;
  1380. while c in ['A'..'Z','a'..'z','0'..'9','_'] do
  1381. begin
  1382. orgpattern:=orgpattern+c;
  1383. nextchar;
  1384. end;
  1385. pattern:=orgpattern;
  1386. uppervar(pattern);
  1387. if is_keyword(y) then
  1388. yylex:=y
  1389. else
  1390. begin
  1391. { this takes some time ... }
  1392. if support_macros then
  1393. begin
  1394. mac:=pmacrosym(macros^.search(pattern));
  1395. if assigned(mac) and (assigned(mac^.buftext)) then
  1396. begin
  1397. { don't forget the last char }
  1398. dec(inputpointer);
  1399. current_module^.current_inputfile^.bufpos:=inputpointer;
  1400. { this isn't a proper way, but ... }
  1401. hp:=new(pinputfile,init('','Macro '+pattern,''));
  1402. hp^.next:=current_module^.current_inputfile;
  1403. current_module^.current_inputfile:=hp;
  1404. current_module^.sourcefiles.register_file(hp);
  1405. { set an own buffer }
  1406. getmem(hp2,mac^.buflen+1);
  1407. current_module^.current_inputfile^.setbuf(hp2,mac^.buflen+1);
  1408. inputbuffer:=current_module^.current_inputfile^.buf;
  1409. { copy text }
  1410. move(mac^.buftext^,inputbuffer^,mac^.buflen);
  1411. { put end sign }
  1412. inputbuffer[mac^.buflen+1]:=#0;
  1413. { load c }
  1414. c:=inputbuffer[0];
  1415. { point to the next char }
  1416. inputpointer:=1;
  1417. { handle empty macros }
  1418. if c=#0 then reload;
  1419. { play it again ... }
  1420. inc(yylexcount);
  1421. if yylexcount>16 then
  1422. Message(scan_w_macro_deep_ten);
  1423. {$ifdef TP}
  1424. yylex:=yylex;
  1425. {$else}
  1426. yylex:=yylex();
  1427. {$endif}
  1428. { that's all folks }
  1429. dec(yylexcount);
  1430. goto yylex_exit;
  1431. end;
  1432. end;
  1433. yylex:=ID;
  1434. end;
  1435. goto yylex_exit;
  1436. end;
  1437. '$' : begin
  1438. pattern:=c;
  1439. nextchar;
  1440. while ((ord(c)>=ord('0')) and (ord(c)<=ord('9'))) or
  1441. (ord(upcase(c))>=ord('A')) and (ord(upcase(c))<=ord('F')) do
  1442. begin
  1443. pattern:=pattern+c;
  1444. nextchar;
  1445. end;
  1446. yylex:=INTCONST;
  1447. goto yylex_exit;
  1448. end;
  1449. {why ?ifdef FPC}
  1450. { because the tp val doesn't recognize this, }
  1451. { so it's useless in TP versions }
  1452. { it's solved with valint }
  1453. '%' : begin
  1454. pattern:=c;
  1455. nextchar;
  1456. while c in ['0','1'] do
  1457. begin
  1458. pattern:=pattern+c;
  1459. nextchar;
  1460. end;
  1461. yylex:=INTCONST;
  1462. goto yylex_exit;
  1463. end;
  1464. {cond removed endif}
  1465. '0'..'9' : begin
  1466. pattern:=c;
  1467. nextchar;
  1468. while c in ['0'..'9'] do
  1469. begin
  1470. pattern:=pattern+c;
  1471. nextchar;
  1472. end;
  1473. if c in ['.','e','E'] then
  1474. begin
  1475. if c='.' then
  1476. begin
  1477. nextchar;
  1478. if not(c in ['0'..'9']) then
  1479. begin
  1480. s_point:=true;
  1481. yylex:=INTCONST;
  1482. goto yylex_exit;
  1483. end;
  1484. pattern:=pattern+'.';
  1485. while c in ['0'..'9'] do
  1486. begin
  1487. pattern:=pattern+c;
  1488. nextchar;
  1489. end;
  1490. end;
  1491. if upcase(c)='E' then
  1492. begin
  1493. pattern:=pattern+'E';
  1494. nextchar;
  1495. if c in ['-','+'] then
  1496. begin
  1497. pattern:=pattern+c;
  1498. nextchar;
  1499. end;
  1500. if not(c in ['0'..'9']) then
  1501. Message(scan_f_illegal_char);
  1502. while c in ['0'..'9'] do
  1503. begin
  1504. pattern:=pattern+c;
  1505. nextchar;
  1506. end;
  1507. end;
  1508. yylex:=REALNUMBER;
  1509. goto yylex_exit;
  1510. end;
  1511. yylex:=INTCONST;
  1512. goto yylex_exit;
  1513. end;
  1514. ';' : begin
  1515. nextchar;
  1516. yylex:=SEMICOLON;
  1517. exit;
  1518. end;
  1519. '[' : begin
  1520. nextchar;
  1521. yylex:=LECKKLAMMER;
  1522. goto yylex_exit;
  1523. end;
  1524. ']' : begin
  1525. nextchar;
  1526. yylex:=RECKKLAMMER;
  1527. goto yylex_exit;
  1528. end;
  1529. '(' : begin
  1530. nextchar;
  1531. if c='*' then
  1532. begin
  1533. inc(comment_level);
  1534. nextchar;
  1535. while true do
  1536. begin
  1537. { this is currently not supported }
  1538. if c='$' then
  1539. Message(scan_e_wrong_styled_switch);
  1540. repeat
  1541. while c<>'*' do
  1542. begin
  1543. if c=#26 then Message(scan_f_end_of_file);
  1544. { if c=newline then write_line;}
  1545. nextchar;
  1546. end;
  1547. if c=#26 then Message(scan_f_end_of_file);
  1548. {if c=newline then write_line;}
  1549. nextchar;
  1550. until c=')';
  1551. dec(comment_level);
  1552. nextchar;
  1553. { check for *)(* }
  1554. if c='(' then
  1555. begin
  1556. nextchar;
  1557. if c<>'*' then
  1558. begin
  1559. yylex:=LKLAMMER;
  1560. goto yylex_exit;
  1561. end;
  1562. inc(comment_level);
  1563. nextchar;
  1564. end
  1565. else
  1566. begin
  1567. {$ifndef TP}
  1568. yylex:=yylex();
  1569. {$else TP}
  1570. yylex:=yylex;
  1571. {$endif TP}
  1572. goto yylex_exit;
  1573. end;
  1574. end;
  1575. end;
  1576. yylex:=LKLAMMER;
  1577. goto yylex_exit;
  1578. end;
  1579. ')' : begin
  1580. nextchar;
  1581. yylex:=RKLAMMER;
  1582. goto yylex_exit;
  1583. end;
  1584. '+' : begin
  1585. nextchar;
  1586. if (c='=') and c_like_operators then
  1587. begin
  1588. nextchar;
  1589. yylex:=_PLUSASN;
  1590. goto yylex_exit;
  1591. end
  1592. else
  1593. begin
  1594. yylex:=PLUS;
  1595. goto yylex_exit;
  1596. end;
  1597. end;
  1598. '-' : begin
  1599. nextchar;
  1600. if (c='=') and c_like_operators then
  1601. begin
  1602. nextchar;
  1603. yylex:=_MINUSASN;
  1604. goto yylex_exit;
  1605. end
  1606. else
  1607. begin
  1608. yylex:=MINUS;
  1609. goto yylex_exit;
  1610. end;
  1611. end;
  1612. ':' : begin
  1613. nextchar;
  1614. if c='=' then
  1615. begin
  1616. nextchar;
  1617. yylex:=ASSIGNMENT;
  1618. goto yylex_exit;
  1619. end
  1620. else
  1621. begin
  1622. yylex:=COLON;
  1623. goto yylex_exit;
  1624. end;
  1625. end;
  1626. '*' : begin
  1627. nextchar;
  1628. if (c='=') and c_like_operators then
  1629. begin
  1630. nextchar;
  1631. yylex:=_STARASN;
  1632. goto yylex_exit;
  1633. end
  1634. else
  1635. begin
  1636. yylex:=STAR;
  1637. goto yylex_exit;
  1638. end;
  1639. end;
  1640. '/' : begin
  1641. nextchar;
  1642. if (c='=') and c_like_operators then
  1643. begin
  1644. nextchar;
  1645. yylex:=_SLASHASN;
  1646. goto yylex_exit;
  1647. end
  1648. else if (c='/') then
  1649. begin
  1650. delphi_comment;
  1651. {$ifndef TP}
  1652. yylex:=yylex();
  1653. {$else TP}
  1654. yylex:=yylex;
  1655. {$endif TP}
  1656. goto yylex_exit;
  1657. end
  1658. else
  1659. begin
  1660. yylex:=SLASH;
  1661. goto yylex_exit;
  1662. end;
  1663. end;
  1664. '=' : begin
  1665. nextchar;
  1666. yylex:=EQUAL;
  1667. goto yylex_exit;
  1668. end;
  1669. '.' : begin
  1670. nextchar;
  1671. if c='.' then
  1672. begin
  1673. nextchar;
  1674. yylex:=POINTPOINT;
  1675. goto yylex_exit;
  1676. end
  1677. else
  1678. yylex:=POINT;
  1679. goto yylex_exit;
  1680. end;
  1681. '@' : begin
  1682. nextchar;
  1683. if c='@' then
  1684. begin
  1685. nextchar;
  1686. yylex:=DOUBLEADDR;
  1687. end
  1688. else
  1689. yylex:=KLAMMERAFFE;
  1690. goto yylex_exit;
  1691. end;
  1692. ',' : begin
  1693. nextchar;
  1694. yylex:=COMMA;
  1695. exit;
  1696. end;
  1697. '''','#','^' :
  1698. begin
  1699. if c='^' then
  1700. begin
  1701. nextchar;
  1702. c:=upcase(c);
  1703. if not(parse_types) and (c in ['A'..'Z']) then
  1704. begin
  1705. pattern:=chr(ord(c)-64);
  1706. nextchar;
  1707. end
  1708. else
  1709. begin
  1710. yylex:=CARET;
  1711. goto yylex_exit;
  1712. end;
  1713. end
  1714. else pattern:='';
  1715. while true do
  1716. case c of
  1717. '#' :
  1718. begin
  1719. hs:='';
  1720. nextchar;
  1721. if c='$' then
  1722. begin
  1723. hs:='$';
  1724. nextchar;
  1725. while c in (['0'..'9','a'..'f','A'..'F']) do
  1726. begin
  1727. hs:=hs+upcase(c);
  1728. nextchar;
  1729. end;
  1730. end
  1731. else
  1732. { FPC supports binary constants }
  1733. { %10101 evalutes to 37 }
  1734. if c='%' then
  1735. begin
  1736. nextchar;
  1737. while c in ['0','1'] do
  1738. begin
  1739. hs:=hs+upcase(c);
  1740. nextchar;
  1741. end;
  1742. end
  1743. else
  1744. begin
  1745. while (ord(c)>=ord('0')) and (ord(c)<=ord('9')) do
  1746. begin
  1747. hs:=hs+c;
  1748. nextchar;
  1749. end;
  1750. end;
  1751. valint(hs,l,code);
  1752. if (code<>0) or (l<0) or (l>255) then
  1753. Message(scan_e_illegal_char_const);
  1754. pattern:=pattern+chr(l);
  1755. end;
  1756. '''' :
  1757. begin
  1758. repeat
  1759. nextchar;
  1760. case c of
  1761. #26 : begin
  1762. Message(scan_f_end_of_file);
  1763. break;
  1764. end;
  1765. #13,
  1766. newline : begin
  1767. Message(scan_f_string_exceeds_line);
  1768. break;
  1769. end;
  1770. '''' : begin
  1771. nextchar;
  1772. if c<>'''' then
  1773. break;
  1774. end;
  1775. end;
  1776. pattern:=pattern+c;
  1777. until false;
  1778. end;
  1779. '^' : begin
  1780. nextchar;
  1781. c:=upcase(c);
  1782. if c in ['A'..'Z'] then
  1783. pattern:=pattern+chr(ord(c)-64)
  1784. else Message(scan_f_illegal_char);
  1785. nextchar;
  1786. end;
  1787. else break;
  1788. end;
  1789. { strings with length 1 become const chars }
  1790. if length(pattern)=1 then
  1791. yylex:=CCHAR
  1792. else yylex:=CSTRING;
  1793. goto yylex_exit;
  1794. end;
  1795. '>' : begin
  1796. nextchar;
  1797. if c='=' then
  1798. begin
  1799. nextchar;
  1800. yylex:=GTE;
  1801. goto yylex_exit;
  1802. end
  1803. else if c='>' then
  1804. begin
  1805. nextchar;
  1806. yylex:=_SHR;
  1807. goto yylex_exit;
  1808. end
  1809. else if c='<' then
  1810. begin
  1811. nextchar;
  1812. { >< is for a symetric diff for sets }
  1813. yylex:=SYMDIF;
  1814. goto yylex_exit;
  1815. end
  1816. else
  1817. begin
  1818. yylex:=GT;
  1819. goto yylex_exit;
  1820. end;
  1821. end;
  1822. '<' : begin
  1823. nextchar;
  1824. if c='>' then
  1825. begin
  1826. nextchar;
  1827. yylex:=UNEQUAL;
  1828. goto yylex_exit;
  1829. end
  1830. else if c='=' then
  1831. begin
  1832. nextchar;
  1833. yylex:=LTE;
  1834. goto yylex_exit;
  1835. end
  1836. else if c='<' then
  1837. begin
  1838. nextchar;
  1839. yylex:=_SHL;
  1840. goto yylex_exit;
  1841. end
  1842. else
  1843. begin
  1844. yylex:=LT;
  1845. goto yylex_exit;
  1846. end;
  1847. end;
  1848. #26 : begin
  1849. yylex:=_EOF;
  1850. goto yylex_exit;
  1851. end;
  1852. else
  1853. begin
  1854. update_line;
  1855. Message(scan_f_illegal_char);
  1856. end;
  1857. end;
  1858. yylex_exit :
  1859. update_line;
  1860. end;
  1861. const last_asmgetchar_was_a_comment : boolean = false;
  1862. function asmgetchar : char;
  1863. begin
  1864. if c='{' then
  1865. begin
  1866. src_comment;
  1867. { a comment is a seperator }
  1868. asmgetchar:=';';
  1869. last_asmgetchar_was_a_comment:=true;
  1870. end
  1871. else
  1872. begin
  1873. update_line;
  1874. if last_asmgetchar_was_a_comment then
  1875. begin
  1876. last_asmgetchar_was_a_comment:=false;
  1877. asmgetchar:=c;
  1878. exit;
  1879. end;
  1880. nextchar;
  1881. asmgetchar:=c;
  1882. if c='/' then
  1883. begin
  1884. nextchar;
  1885. if c='/' then
  1886. begin
  1887. delphi_comment;
  1888. asmgetchar:=c;
  1889. end
  1890. else
  1891. begin
  1892. last_asmgetchar_was_a_comment:=true;
  1893. asmgetchar:='/';
  1894. end;
  1895. end;
  1896. end;
  1897. end;
  1898. procedure initscanner(const fn: string);
  1899. var
  1900. d:dirstr;
  1901. n:namestr;
  1902. e:extstr;
  1903. begin
  1904. fsplit(fn,d,n,e);
  1905. current_module^.current_inputfile:=new(pinputfile,init(d,n,e));
  1906. current_module^.current_inputfile^.reset;
  1907. current_module^.sourcefiles.register_file(current_module^.current_inputfile);
  1908. if ioresult<>0 then
  1909. Message(scan_f_cannot_open_input);
  1910. inputbuffer:=current_module^.current_inputfile^.buf;
  1911. preprocstack:=nil;
  1912. reload;
  1913. comment_level:=0;
  1914. lasttokenpos:=0;
  1915. lastlinepointer:=0;
  1916. s_point:=false;
  1917. end;
  1918. procedure donescanner(compiled_at_higher_level : boolean);
  1919. var
  1920. st : string;
  1921. begin
  1922. if not (compiled_at_higher_level) and assigned(preprocstack) then
  1923. begin
  1924. if preprocstack^.t=PP_IFDEF then
  1925. st:='$IF(N)(DEF)'
  1926. else
  1927. st:='$ELSE';
  1928. Message3(scan_e_endif_expected,st,preprocstack^.name,tostr(preprocstack^.line_nb));
  1929. end;
  1930. end;
  1931. end.
  1932. {
  1933. $Log$
  1934. Revision 1.2 1998-03-28 23:09:57 florian
  1935. * secondin bugfix (m68k and i386)
  1936. * overflow checking bugfix (m68k and i386) -- pretty useless in
  1937. secondadd, since everything is done using 32-bit
  1938. * loading pointer to routines hopefully fixed (m68k)
  1939. * flags problem with calls to RTL internal routines fixed (still strcmp
  1940. to fix) (m68k)
  1941. * #ELSE was still incorrect (didn't take care of the previous level)
  1942. * problem with filenames in the command line solved
  1943. * problem with mangledname solved
  1944. * linking name problem solved (was case insensitive)
  1945. * double id problem and potential crash solved
  1946. * stop after first error
  1947. * and=>test problem removed
  1948. * correct read for all float types
  1949. * 2 sigsegv fixes and a cosmetic fix for Internal Error
  1950. * push/pop is now correct optimized (=> mov (%esp),reg)
  1951. Revision 1.1.1.1 1998/03/25 11:18:15 root
  1952. * Restored version
  1953. Revision 1.43 1998/03/24 21:48:34 florian
  1954. * just a couple of fixes applied:
  1955. - problem with fixed16 solved
  1956. - internalerror 10005 problem fixed
  1957. - patch for assembler reading
  1958. - small optimizer fix
  1959. - mem is now supported
  1960. Revision 1.42 1998/03/10 17:19:29 peter
  1961. * fixed bug0108
  1962. * better linebreak scanning (concentrated in nextchar(), it supports
  1963. #10, #13, #10#13, #13#10
  1964. Revision 1.41 1998/03/10 16:27:45 pierre
  1965. * better line info in stabs debug
  1966. * symtabletype and lexlevel separated into two fields of tsymtable
  1967. + ifdef MAKELIB for direct library output, not complete
  1968. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1969. working
  1970. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1971. working
  1972. Revision 1.40 1998/03/10 01:17:27 peter
  1973. * all files have the same header
  1974. * messages are fully implemented, EXTDEBUG uses Comment()
  1975. + AG... files for the Assembler generation
  1976. Revision 1.39 1998/03/09 12:58:14 peter
  1977. * FWait warning is only showed for Go32V2 and $E+
  1978. * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  1979. for m68k the same tables are removed)
  1980. + $E for i386
  1981. Revision 1.38 1998/03/06 00:52:52 peter
  1982. * replaced all old messages from errore.msg, only ExtDebug and some
  1983. Comment() calls are left
  1984. * fixed options.pas
  1985. Revision 1.37 1998/03/04 17:34:06 michael
  1986. + Changed ifdef FPK to ifdef FPC
  1987. Revision 1.36 1998/03/03 22:38:34 peter
  1988. * the last 3 files
  1989. Revision 1.35 1998/03/02 01:49:26 peter
  1990. * renamed target_DOS to target_GO32V1
  1991. + new verbose system, merged old errors and verbose units into one new
  1992. verbose.pas, so errors.pas is obsolete
  1993. Revision 1.34 1998/02/26 11:57:16 daniel
  1994. * New assembler optimizations commented out, because of bugs.
  1995. * Use of dir-/name- and extstr.
  1996. Revision 1.33 1998/02/22 23:03:32 peter
  1997. * renamed msource->mainsource and name->unitname
  1998. * optimized filename handling, filename is not seperate anymore with
  1999. path+name+ext, this saves stackspace and a lot of fsplit()'s
  2000. * recompiling of some units in libraries fixed
  2001. * shared libraries are working again
  2002. + $LINKLIB <lib> to support automatic linking to libraries
  2003. + libraries are saved/read from the ppufile, also allows more libraries
  2004. per ppufile
  2005. Revision 1.32 1998/02/17 21:20:59 peter
  2006. + Script unit
  2007. + __EXIT is called again to exit a program
  2008. - target_info.link/assembler calls
  2009. * linking works again for dos
  2010. * optimized a few filehandling functions
  2011. * fixed stabs generation for procedures
  2012. Revision 1.31 1998/02/16 12:51:44 michael
  2013. + Implemented linker object
  2014. Revision 1.30 1998/02/13 10:35:45 daniel
  2015. * Made Motorola version compilable.
  2016. * Fixed optimizer
  2017. Revision 1.29 1998/02/12 17:19:25 florian
  2018. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  2019. also that aktswitches isn't a pointer)
  2020. Revision 1.28 1998/02/12 11:50:44 daniel
  2021. Yes! Finally! After three retries, my patch!
  2022. Changes:
  2023. Complete rewrite of psub.pas.
  2024. Added support for DLL's.
  2025. Compiler requires less memory.
  2026. Platform units for each platform.
  2027. Revision 1.27 1998/02/07 09:39:27 florian
  2028. * correct handling of in_main
  2029. + $D,$T,$X,$V like tp
  2030. Revision 1.26 1998/02/05 22:27:06 florian
  2031. * small problems fixed: remake3 should now work
  2032. Revision 1.25 1998/02/03 22:13:35 florian
  2033. * clean up
  2034. Revision 1.24 1998/02/02 23:42:38 florian
  2035. * data is now dword aligned per default else the stack ajustements are useless
  2036. + $wait directive: stops compiling til return is presseed (a message is
  2037. also written, useful to give the user a change to notice a message
  2038. Revision 1.23 1998/02/02 13:13:28 pierre
  2039. * line_count transfered to tinputfile, to avoid crosscounting
  2040. Revision 1.22 1998/01/30 17:30:10 pierre
  2041. + better line counting mechanism
  2042. line count updated only when important tokens are read
  2043. (not for comment , ; )
  2044. Revision 1.21 1998/01/26 19:09:52 peter
  2045. * fixed EOF in open string constant reading
  2046. Revision 1.20 1998/01/22 08:56:55 peter
  2047. * Fixed string exceeds end of line problem (#13 is not a linux
  2048. linebreak)
  2049. Revision 1.19 1998/01/20 18:18:46 peter
  2050. * fixed skip_until_pragma, bug0044 and the compiler recompile good
  2051. Revision 1.18 1998/01/20 16:30:17 pierre
  2052. * bug with braces in log from Peter removed
  2053. Revision 1.17 1998/01/20 15:14:33 peter
  2054. * fixes bug 44 with multiple $'s between skipped $IFDEF and $ENDIF
  2055. Revision 1.16 1998/01/13 16:16:06 pierre
  2056. * bug in interdependent units handling
  2057. - primary unit was not in loaded_units list
  2058. - current_module^.symtable was assigned too early
  2059. - donescanner must not call error if the compilation
  2060. of the unit was done at a higher level.
  2061. Revision 1.15 1998/01/09 23:08:34 florian
  2062. + C++/Delphi styled //-comments
  2063. * some bugs in Delphi object model fixed
  2064. + override directive
  2065. Revision 1.14 1998/01/09 18:01:17 florian
  2066. * VIRTUAL isn't anymore a common keyword
  2067. + DYNAMIC is equal to VIRTUAL
  2068. Revision 1.13 1998/01/09 13:39:57 florian
  2069. * public, protected and private aren't anymore key words
  2070. + published is equal to public
  2071. Revision 1.12 1997/12/12 13:28:41 florian
  2072. + version 0.99.0
  2073. * all WASM options changed into MASM
  2074. + -O2 for Pentium II optimizations
  2075. Revision 1.11 1997/12/10 23:07:30 florian
  2076. * bugs fixed: 12,38 (also m68k),39,40,41
  2077. + warning if a system unit is without -Us compiled
  2078. + warning if a method is virtual and private (was an error)
  2079. * some indentions changed
  2080. + factor does a better error recovering (omit some crashes)
  2081. + problem with @type(x) removed (crashed the compiler)
  2082. Revision 1.10 1997/12/09 14:09:15 carl
  2083. * bugfix of Runerror 216 when reading a null character (such as trying to
  2084. compile a binary file)
  2085. Revision 1.9 1997/12/08 11:51:12 pierre
  2086. * corrected some buggy code in hexadecimal number reading
  2087. Revision 1.8 1997/12/05 14:22:20 daniel
  2088. * Did some source code beutification.
  2089. Revision 1.7 1997/12/03 13:43:14 carl
  2090. + OUTPUT_FORMAT switch is processor specific to i386.
  2091. Revision 1.6 1997/12/02 16:00:55 carl
  2092. * bugfix of include files - now gives out a fatalerror if not found,
  2093. otherwise would create invalid pointer operations everywhere.
  2094. * bugfix of $i+xyz now the $i+/- switch is correctly recognized as io
  2095. checking and ont an include directive.
  2096. Revision 1.5 1997/11/28 18:14:48 pierre
  2097. working version with several bug fixes
  2098. Revision 1.4 1997/11/28 14:26:26 florian
  2099. Fixed some bugs
  2100. Revision 1.3 1997/11/27 17:47:14 carl
  2101. * fixed bug with assem switches and m68k.
  2102. Revision 1.2 1997/11/27 17:40:48 carl
  2103. + assem type scanning switches for intel targets.
  2104. Revision 1.1.1.1 1997/11/27 08:33:01 michael
  2105. FPC Compiler CVS start
  2106. Pre-CVS log:
  2107. CEC Carl-Eric Codere
  2108. FK Florian Klaempfl
  2109. PM Pierre Muller
  2110. + feature added
  2111. - removed
  2112. * bug fixed or changed
  2113. History:
  2114. 6th september 1997:
  2115. + added support for global switches (i.e $X and $E (for m68k)) (CEC)
  2116. 1st october 1997:
  2117. + added $ifopt as dummy which is always rejected (FK)
  2118. 13th october 1997:
  2119. * user defined message are now written via the errors unit
  2120. and exterror (FK)
  2121. + compiler switch $INFO added, does the same like $MESSAGE,
  2122. the text is written via comment(v_info,...) (FK)
  2123. + $STOP and $FATALERROR added: they are equivalent, the
  2124. following message is written and the compiler stops (FK)
  2125. - write_c, no more necessary (FK)
  2126. 14th october 1997:
  2127. + wrong line counting corrected: <comment start> $I test
  2128. <comment end>
  2129. (FK)
  2130. 17th october 1997:
  2131. + support of $if expr (FK)
  2132. * $define a=1234 to a:=1234 (FK)
  2133. + -So allows now <comment start> <comment start> <comment end>
  2134. as comment (preocedure dec_comment_level) (FK)
  2135. 22th october 1997:
  2136. + $NOTE (FK)
  2137. 9th november 1997:
  2138. + added updating of line_no in asmgetchar. (CEC)
  2139. 14th november 1997:
  2140. * fixed problem with asm line counting. (CEC)
  2141. 17th november 1997:
  2142. + kommentar renamed src_comment and kommentarebene renamed comment_level (PM)
  2143. }