scanner.pas 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311
  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_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_string:=upper(hs);
  380. end;
  381. function read_number : longint;
  382. var
  383. hs : string;
  384. l : longint;
  385. w : word;
  386. begin
  387. read_number:=0;
  388. hs:='';
  389. while c in ['0'..'9'] do
  390. begin
  391. hs:=hs+c;
  392. nextchar;
  393. end;
  394. valint(hs,l,w);
  395. read_number:=l;
  396. end;
  397. var
  398. preprocpat : string;
  399. preproc_token : ttoken;
  400. function read_preproc : ttoken;
  401. { var
  402. y : ttoken;
  403. code : word;
  404. l : longint;
  405. hs : string;
  406. hp : pinputfile;
  407. hp2 : pchar;}
  408. label
  409. preproc_exit;
  410. begin
  411. while c in [' ',#9,#13,#12,#10] do
  412. begin
  413. { if c=#10 then write_line;}
  414. nextchar;
  415. end;
  416. case c of
  417. 'A'..'Z','a'..'z','_','0'..'9' :
  418. begin
  419. preprocpat:=c;
  420. nextchar;
  421. while c in ['A'..'Z','a'..'z','0'..'9','_'] do
  422. begin
  423. preprocpat:=preprocpat+c;
  424. nextchar;
  425. end;
  426. uppervar(preprocpat);
  427. read_preproc:=ID;
  428. goto preproc_exit;
  429. end;
  430. '(' : begin
  431. nextchar;
  432. read_preproc:=LKLAMMER;
  433. goto preproc_exit;
  434. end;
  435. ')' : begin
  436. nextchar;
  437. read_preproc:=RKLAMMER;
  438. goto preproc_exit;
  439. end;
  440. '+' : begin
  441. nextchar;
  442. read_preproc:=PLUS;
  443. goto preproc_exit;
  444. end;
  445. '-' : begin
  446. nextchar;
  447. read_preproc:=MINUS;
  448. goto preproc_exit;
  449. end;
  450. '*' : begin
  451. nextchar;
  452. read_preproc:=STAR;
  453. goto preproc_exit;
  454. end;
  455. '/' : begin
  456. nextchar;
  457. read_preproc:=SLASH;
  458. goto preproc_exit;
  459. end;
  460. '=' : begin
  461. nextchar;
  462. read_preproc:=EQUAL;
  463. goto preproc_exit;
  464. end;
  465. '>' : begin
  466. nextchar;
  467. if c='=' then
  468. begin
  469. nextchar;
  470. read_preproc:=GTE;
  471. goto preproc_exit;
  472. end
  473. else
  474. begin
  475. read_preproc:=GT;
  476. goto preproc_exit;
  477. end;
  478. end;
  479. '<' : begin
  480. nextchar;
  481. if c='>' then
  482. begin
  483. nextchar;
  484. read_preproc:=UNEQUAL;
  485. goto preproc_exit;
  486. end
  487. else if c='=' then
  488. begin
  489. nextchar;
  490. read_preproc:=LTE;
  491. goto preproc_exit;
  492. end
  493. else
  494. begin
  495. read_preproc:=LT;
  496. goto preproc_exit;
  497. end;
  498. end;
  499. #26:
  500. begin
  501. update_line;
  502. Message(scan_f_end_of_file);
  503. end
  504. else
  505. begin
  506. read_preproc:=_EOF;
  507. end;
  508. end;
  509. preproc_exit :
  510. update_line;
  511. end;
  512. procedure preproc_consume(t : ttoken);
  513. begin
  514. if t<>preproc_token then
  515. Message(scan_e_preproc_syntax_error);
  516. preproc_token:=read_preproc;
  517. end;
  518. function read_expr : string;forward;
  519. function read_factor : string;
  520. var
  521. hs : string;
  522. mac : pmacrosym;
  523. len : byte;
  524. begin
  525. if preproc_token=ID then
  526. begin
  527. if preprocpat='NOT' then
  528. begin
  529. preproc_consume(ID);
  530. hs:=read_expr;
  531. if hs='0' then
  532. read_factor:='1'
  533. else
  534. read_factor:='0';
  535. end
  536. else
  537. begin
  538. mac:=pmacrosym(macros^.search(hs));
  539. hs:=preprocpat;
  540. preproc_consume(ID);
  541. if assigned(mac) then
  542. begin
  543. if mac^.defined and assigned(mac^.buftext) then
  544. begin
  545. if mac^.buflen>255 then
  546. begin
  547. len:=255;
  548. Message(scan_w_marco_cut_after_255_chars);
  549. end
  550. else
  551. len:=mac^.buflen;
  552. hs[0]:=char(len);
  553. move(mac^.buftext^,hs[1],len);
  554. end
  555. else
  556. read_factor:='';
  557. end
  558. else
  559. read_factor:=hs;
  560. end
  561. end
  562. else if preproc_token=LKLAMMER then
  563. begin
  564. preproc_consume(LKLAMMER);
  565. read_factor:=read_expr;
  566. preproc_consume(RKLAMMER);
  567. end
  568. else
  569. Message(scan_e_error_in_preproc_expr);
  570. end;
  571. function read_term : string;
  572. var
  573. hs1,hs2 : string;
  574. begin
  575. hs1:=read_factor;
  576. while true do
  577. begin
  578. if (preproc_token=ID) then
  579. begin
  580. if preprocpat='AND' then
  581. begin
  582. preproc_consume(ID);
  583. hs2:=read_factor;
  584. if (hs1<>'0') and (hs2<>'0') then
  585. hs1:='1';
  586. end
  587. else
  588. break;
  589. end
  590. else
  591. break;
  592. end;
  593. read_term:=hs1;
  594. end;
  595. function read_simple_expr : string;
  596. var
  597. hs1,hs2 : string;
  598. begin
  599. hs1:=read_term;
  600. while true do
  601. begin
  602. if (preproc_token=ID) then
  603. begin
  604. if preprocpat='OR' then
  605. begin
  606. preproc_consume(ID);
  607. hs2:=read_term;
  608. if (hs1<>'0') or (hs2<>'0') then
  609. hs1:='1';
  610. end
  611. else
  612. break;
  613. end
  614. else
  615. break;
  616. end;
  617. read_simple_expr:=hs1;
  618. end;
  619. function read_expr : string;
  620. var
  621. hs1,hs2 : string;
  622. b : boolean;
  623. t : ttoken;
  624. w : word;
  625. l1,l2 : longint;
  626. begin
  627. hs1:=read_simple_expr;
  628. t:=preproc_token;
  629. if not(t in [EQUAL,UNEQUAL,LT,GT,LTE,GTE]) then
  630. begin
  631. read_expr:=hs1;
  632. exit;
  633. end;
  634. preproc_consume(t);
  635. hs2:=read_simple_expr;
  636. if is_number(hs1) and is_number(hs2) then
  637. begin
  638. valint(hs1,l1,w);
  639. valint(hs2,l2,w);
  640. case t of
  641. EQUAL:
  642. b:=l1=l2;
  643. UNEQUAL:
  644. b:=l1<>l2;
  645. LT:
  646. b:=l1<l2;
  647. GT:
  648. b:=l1>l2;
  649. GTE:
  650. b:=l1>=l2;
  651. LTE:
  652. b:=l1<=l2;
  653. end;
  654. end
  655. else
  656. begin
  657. case t of
  658. EQUAL:
  659. b:=hs1=hs2;
  660. UNEQUAL:
  661. b:=hs1<>hs2;
  662. LT:
  663. b:=hs1<hs2;
  664. GT:
  665. b:=hs1>hs2;
  666. GTE:
  667. b:=hs1>=hs2;
  668. LTE:
  669. b:=hs1<=hs2;
  670. end;
  671. end;
  672. if b then
  673. read_expr:='1'
  674. else
  675. read_expr:='0';
  676. end;
  677. procedure skip_until_pragma;
  678. var
  679. found : longint;
  680. begin
  681. found:=0;
  682. repeat
  683. case c of
  684. #26 : Message(scan_f_end_of_file);
  685. { newline : begin
  686. write_line;
  687. found:=0;
  688. end; }
  689. '{' : begin
  690. if comment_level=0 then
  691. found:=1;
  692. inc(comment_level);
  693. end;
  694. '}' : begin
  695. dec_comment_level;
  696. found:=0;
  697. end;
  698. '$' : begin
  699. if found=1 then
  700. found:=2;
  701. end;
  702. else
  703. found:=0;
  704. end;
  705. nextchar;
  706. until (found=2);
  707. update_line;
  708. end;
  709. function Is_conditional(const hs:string):boolean;
  710. begin
  711. Is_Conditional:=((hs='ELSE') or (hs='IFDEF') or (hs='IFNDEF') or
  712. (hs='IFOPT') or (hs='ENDIF') or (hs='ELSE') or (hs='IF'));
  713. end;
  714. var
  715. path,hs : string;
  716. hp : pinputfile;
  717. mac : pmacrosym;
  718. found : boolean;
  719. ht : ttoken;
  720. procedure popstack;
  721. var
  722. hp : ppreprocstack;
  723. begin
  724. hp:=preprocstack^.next;
  725. dispose(preprocstack,done);
  726. preprocstack:=hp;
  727. end;
  728. var
  729. _d : dirstr;
  730. _n : namestr;
  731. _e : extstr;
  732. hs2,
  733. msg : string;
  734. begin
  735. nextchar;
  736. hs:=read_string;
  737. update_line;
  738. Message1(scan_d_handling_switch,hs);
  739. if hs='I' then
  740. begin
  741. skipspace;
  742. hs:=c;
  743. nextchar;
  744. while not(c in [' ','}','*',#13,newline]) do
  745. begin
  746. hs:=hs+c;
  747. nextchar;
  748. if c=#26 then Message(scan_f_end_of_file);
  749. end;
  750. { if c=newline then write_line;}
  751. { read until end of comment }
  752. while c<>'}' do
  753. begin
  754. nextchar;
  755. if c=#26 then Message(scan_f_end_of_file);
  756. { if c=newline then write_line;}
  757. end;
  758. {
  759. dec(comment_level);
  760. }
  761. { Initialization }
  762. if (hs[1]='-') then
  763. {exclude(aktswitches,cs_iocheck) Not yet supported.}
  764. aktswitches:=aktswitches-[cs_iocheck]
  765. else if (hs[1]='+') then
  766. {include(aktswitches,cs_iocheck) Not supported yet.}
  767. aktswitches:=aktswitches+[cs_iocheck]
  768. else
  769. begin
  770. fsplit(hs,_d,_n,_e);
  771. update_line;
  772. { directory where the current file is first inspected }
  773. path:=search(hs,current_module^.current_inputfile^.path^,found);
  774. if found then
  775. hp:=new(pinputfile,init(path+_d,_n,_e))
  776. else
  777. begin
  778. path:=search(hs,includesearchpath,found);
  779. hp:=new(pinputfile,init(path+_d,_n,_e));
  780. end;
  781. hp^.reset;
  782. if ioresult=0 then
  783. begin
  784. current_module^.current_inputfile^.bufpos:=inputpointer;
  785. hp^.next:=current_module^.current_inputfile;
  786. current_module^.current_inputfile:=hp;
  787. current_module^.sourcefiles.register_file(hp);
  788. inputbuffer:=current_module^.current_inputfile^.buf;
  789. Message1(scan_u_start_include_file,current_module^.current_inputfile^.name^);
  790. reload;
  791. { we have read the }
  792. { comment end }
  793. dec_comment_level;
  794. { only warn for over one => incompatible with BP }
  795. if (comment_level>1) then
  796. Message1(scan_w_comment_level,tostr(comment_level));
  797. end
  798. else
  799. Message1(scan_f_cannot_open_includefile,_d+_n+_e);
  800. end;
  801. end
  802. { conditional compiling ? }
  803. else if Is_Conditional(hs) then
  804. begin
  805. while true do
  806. begin
  807. if hs='ENDIF' then
  808. begin
  809. { we can always accept an ELSE }
  810. if assigned(preprocstack) then
  811. begin
  812. Message1(scan_c_endif_found,preprocstack^.name);
  813. if preprocstack^.t=PP_ELSE then
  814. popstack;
  815. end
  816. else
  817. Message(scan_e_endif_without_if);
  818. { now pop the condition }
  819. if assigned(preprocstack) then
  820. begin
  821. { we only use $ifdef in the stack }
  822. if (preprocstack^.t=PP_IFDEF) then
  823. popstack
  824. else
  825. Message(scan_e_too_much_endifs);
  826. end
  827. else
  828. Message(scan_e_endif_without_if);
  829. end
  830. else if hs='IFDEF' then
  831. begin
  832. skipspace;
  833. hs:=read_string;
  834. mac:=pmacrosym(macros^.search(hs));
  835. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  836. { the block before must be accepted }
  837. { the symbole must be exist and be defined }
  838. (
  839. (preprocstack=nil) or
  840. preprocstack^.accept
  841. ) and
  842. assigned(mac) and
  843. mac^.defined,
  844. preprocstack));
  845. preprocstack^.name:=hs;
  846. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  847. if preprocstack^.accept then
  848. Message2(scan_c_ifdef_found,preprocstack^.name,'accepted')
  849. else
  850. Message2(scan_c_ifdef_found,preprocstack^.name,'rejected');
  851. end
  852. else if hs='IFOPT' then
  853. begin
  854. skipspace;
  855. hs:=read_string;
  856. { !!!! read switch state }
  857. { PP_IFDEF is correct, we doesn't distinguish between }
  858. { ifopt and ifdef }
  859. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  860. { the block before must be accepted }
  861. (
  862. (preprocstack=nil) or
  863. preprocstack^.accept
  864. ) and
  865. { !!!! subject to change: }
  866. false,
  867. preprocstack));
  868. preprocstack^.name:=hs;
  869. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  870. if preprocstack^.accept then
  871. Message2(scan_c_ifopt_found,preprocstack^.name,'accepted')
  872. else
  873. Message2(scan_c_ifopt_found,preprocstack^.name,'rejected');
  874. end
  875. else if hs='IF' then
  876. begin
  877. skipspace;
  878. { start preproc expression scanner }
  879. preproc_token:=read_preproc;
  880. hs:=read_expr;
  881. { PP_IFDEF is correct, we doesn't distinguish between }
  882. { if, ifopt and ifdef }
  883. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  884. { the block before must be accepted }
  885. (
  886. (preprocstack=nil) or
  887. preprocstack^.accept
  888. ) and
  889. (hs<>'0'),
  890. preprocstack));
  891. preprocstack^.name:=hs;
  892. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  893. if preprocstack^.accept then
  894. Message2(scan_c_if_found,preprocstack^.name,'accepted')
  895. else
  896. Message2(scan_c_if_found,preprocstack^.name,'rejected');
  897. end
  898. else if hs='IFNDEF' then
  899. begin
  900. skipspace;
  901. hs:=read_string;
  902. mac:=pmacrosym(macros^.search(hs));
  903. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  904. { the block before must be accepted }
  905. (
  906. (preprocstack=nil) or
  907. preprocstack^.accept
  908. ) and
  909. not(assigned(mac) and
  910. mac^.defined),
  911. preprocstack));
  912. preprocstack^.name:=hs;
  913. preprocstack^.line_nb:=current_module^.current_inputfile^.line_no;
  914. if preprocstack^.accept then
  915. Message2(scan_c_ifndef_found,preprocstack^.name,'accepted')
  916. else
  917. Message2(scan_c_ifndef_found,preprocstack^.name,'rejected');
  918. end
  919. else if hs='ELSE' then
  920. begin
  921. if assigned(preprocstack) then
  922. begin
  923. preprocstack:=new(ppreprocstack,init(PP_ELSE,
  924. { invert }
  925. not(preprocstack^.accept) and
  926. { but only true, if only the ifdef block is }
  927. { not accepted }
  928. (
  929. (preprocstack^.next=nil) or
  930. (preprocstack^.next^.accept)
  931. ),
  932. preprocstack));
  933. preprocstack^.line_nb := current_module^.current_inputfile^.line_no;
  934. preprocstack^.name := preprocstack^.next^.name;
  935. if preprocstack^.accept then
  936. Message2(scan_c_else_found,preprocstack^.name,'accepted')
  937. else
  938. Message2(scan_c_else_found,preprocstack^.name,'rejected');
  939. end
  940. else
  941. Message(scan_e_endif_without_if);
  942. end
  943. else if hs='IFOPT' then
  944. begin
  945. skipspace;
  946. hs:=read_string;
  947. preprocstack:=new(ppreprocstack,init(PP_IFDEF,
  948. false,
  949. preprocstack));
  950. end;
  951. { accept the text ? }
  952. if (preprocstack=nil) or preprocstack^.accept then
  953. break
  954. else
  955. begin
  956. Message(scan_c_skipping_until);
  957. repeat
  958. skip_until_pragma;
  959. hs:=read_string;
  960. until Is_Conditional(hs);
  961. end;
  962. end;
  963. end
  964. else if (hs='WAIT') then
  965. begin
  966. Message(scan_i_press_enter);
  967. readln;
  968. end
  969. else if (hs='INFO') or (hs='MESSAGE') then
  970. begin
  971. skipspace;
  972. Message1(scan_i_user_defined,readmessage);
  973. end
  974. else if hs='NOTE' then
  975. begin
  976. skipspace;
  977. Message1(scan_n_user_defined,readmessage);
  978. end
  979. else if hs='WARNING' then
  980. begin
  981. skipspace;
  982. Message1(scan_w_user_defined,readmessage);
  983. end
  984. else if hs='ERROR' then
  985. begin
  986. skipspace;
  987. Message1(scan_e_user_defined,readmessage);
  988. end
  989. else if (hs='FATALERROR') or (hs='STOP') then
  990. begin
  991. skipspace;
  992. Message1(scan_f_user_defined,readmessage);
  993. end
  994. else if hs='L' then
  995. begin
  996. skipspace;
  997. hs:='';
  998. while not(c in [' ','}',#9,newline,#13]) do
  999. begin
  1000. hs:=hs+c;
  1001. nextchar;
  1002. if c=#26 then Message(scan_f_end_of_file);
  1003. end;
  1004. hs:=FixFileName(hs);
  1005. if not path_absolute(hs) and (current_module^.current_inputfile^.path<>nil) then
  1006. path:=search(hs,current_module^.current_inputfile^.path^+';'+objectsearchpath,found);
  1007. Linker.AddObjectFile(path+hs);
  1008. current_module^.linkofiles.insert(hs);
  1009. end
  1010. else if hs='D' then
  1011. begin
  1012. if current_module^.in_main then
  1013. Message(scan_w_switch_is_global)
  1014. else
  1015. begin
  1016. if c='-' then
  1017. aktswitches:=aktswitches-[cs_debuginfo]
  1018. else
  1019. aktswitches:=aktswitches+[cs_debuginfo];
  1020. end;
  1021. end
  1022. else if hs='R' then
  1023. begin
  1024. if c='-' then
  1025. {exclude(aktswitches,cs_rangechecking) Not yet supported.}
  1026. aktswitches:=aktswitches-[cs_rangechecking]
  1027. else
  1028. {include(aktswitches,cs_rangechecking); Not yet supported.}
  1029. aktswitches:=aktswitches+[cs_rangechecking];
  1030. end
  1031. else if hs='Q' then
  1032. begin
  1033. if c='-' then
  1034. {include(aktswitches,cs_check_overflow) Not yet supported.}
  1035. aktswitches:=aktswitches-[cs_check_overflow]
  1036. else
  1037. {include(aktswitches,cs_check_overflow); Not yet supported.}
  1038. aktswitches:=aktswitches+[cs_check_overflow]
  1039. end
  1040. else if hs='T' then
  1041. begin
  1042. if c='-' then
  1043. aktswitches:=aktswitches-[cs_typed_addresses]
  1044. else
  1045. aktswitches:=aktswitches+[cs_typed_addresses]
  1046. end
  1047. else if hs='V' then
  1048. begin
  1049. if c='-' then
  1050. aktswitches:=aktswitches-[cs_strict_var_strings]
  1051. else
  1052. aktswitches:=aktswitches+[cs_strict_var_strings]
  1053. end
  1054. else if hs='F' then
  1055. begin
  1056. Message(scan_n_far_directive_ignored);
  1057. end
  1058. else if hs='S' then
  1059. begin
  1060. if target_info.target<>target_linux then
  1061. begin
  1062. case c of
  1063. '-' : aktswitches:=aktswitches-[cs_check_stack];
  1064. '+' : aktswitches:=aktswitches+[cs_check_stack];
  1065. else
  1066. Message(scan_w_illegal_switch);
  1067. end;
  1068. end
  1069. else
  1070. begin
  1071. if c in ['+','-'] then
  1072. Message(scan_n_stack_check_global_under_linux)
  1073. else
  1074. Message(scan_w_illegal_switch);
  1075. end;
  1076. end
  1077. else if hs='E' then
  1078. begin
  1079. { This is a global switch which affects all units }
  1080. if ((current_module = main_module) and (main_module^.in_main = false)) then
  1081. begin
  1082. case c of
  1083. '-' : aktswitches:=aktswitches-[cs_fp_emulation];
  1084. '+' : aktswitches:=aktswitches+[cs_fp_emulation];
  1085. else
  1086. Message(scan_w_illegal_switch);
  1087. end;
  1088. end
  1089. else
  1090. Message(scan_w_switch_is_global);
  1091. end
  1092. else if hs='X' then
  1093. begin
  1094. { This is a global switch which only affects the unit/program }
  1095. { being compiled }
  1096. if not (current_module^.in_main) then
  1097. begin
  1098. case c of
  1099. '-' : aktswitches:=aktswitches-[cs_extsyntax];
  1100. '+' : aktswitches:=aktswitches+[cs_extsyntax];
  1101. else
  1102. Message(scan_w_illegal_switch);
  1103. end;
  1104. end
  1105. else
  1106. Message(scan_w_switch_is_global);
  1107. end
  1108. else if hs='LINKLIB' then
  1109. begin
  1110. skipspace;
  1111. hs:=FixFileName(read_string);
  1112. Linker.AddLibraryFile(hs);
  1113. current_module^.linklibfiles.insert(hs);
  1114. end
  1115. {$ifdef i386}
  1116. else if hs='OUTPUT_FORMAT' then
  1117. begin
  1118. { this is a global switch }
  1119. if current_module^.in_main then
  1120. Message(scan_w_switch_is_global)
  1121. else
  1122. begin
  1123. skipspace;
  1124. hs:=upper(read_string);
  1125. if hs='NASM' then
  1126. current_module^.output_format:=of_nasm
  1127. else if hs='MASM' then
  1128. current_module^.output_format:=of_masm
  1129. else if hs='O' then
  1130. current_module^.output_format:=of_o
  1131. else if hs='OBJ' then
  1132. current_module^.output_format:=of_obj
  1133. else
  1134. Message(scan_w_illegal_switch);
  1135. end;
  1136. { for use in globals }
  1137. output_format:=current_module^.output_format;
  1138. end
  1139. {$endif}
  1140. {$ifdef SUPPORT_MMX}
  1141. else if hs='MMX' then
  1142. begin
  1143. if c='-' then
  1144. aktswitches:=aktswitches-[cs_mmx]
  1145. else
  1146. aktswitches:=aktswitches+[cs_mmx];
  1147. end
  1148. else if hs='SATURATION' then
  1149. begin
  1150. if c='-' then
  1151. aktswitches:=aktswitches-[cs_mmx_saturation]
  1152. else
  1153. aktswitches:=aktswitches+[cs_mmx_saturation];
  1154. end
  1155. {$endif SUPPORT_MMX}
  1156. else if hs='DEFINE' then
  1157. begin
  1158. skipspace;
  1159. hs:=read_string;
  1160. mac:=pmacrosym(macros^.search(hs));
  1161. if not assigned(mac) then
  1162. begin
  1163. mac:=new(pmacrosym,init(hs));
  1164. mac^.defined:=true;
  1165. Message1(parser_m_macro_defined,mac^.name);
  1166. macros^.insert(mac);
  1167. end
  1168. else
  1169. begin
  1170. Message1(parser_m_macro_defined,mac^.name);
  1171. mac^.defined:=true;
  1172. { delete old definition }
  1173. if assigned(mac^.buftext) then
  1174. begin
  1175. freemem(mac^.buftext,mac^.buflen);
  1176. mac^.buftext:=nil;
  1177. end;
  1178. end;
  1179. if support_macros then
  1180. begin
  1181. { key words are never substituted }
  1182. hs2:=pattern;
  1183. pattern:=hs;
  1184. if is_keyword(ht) then
  1185. Message(scan_e_keyword_cant_be_a_macro);
  1186. pattern:=hs2;
  1187. skipspace;
  1188. { !!!!!! handle macro params, need we this? }
  1189. { may be a macro? }
  1190. if c=':' then
  1191. begin
  1192. nextchar;
  1193. if c='=' then
  1194. begin
  1195. { first char }
  1196. nextchar;
  1197. macropos:=0;
  1198. while (c<>'}') do
  1199. begin
  1200. macrobuffer^[macropos]:=c;
  1201. { if c=newline then write_line;}
  1202. nextchar;
  1203. if c=#26 then Message(scan_f_end_of_file);
  1204. inc(macropos);
  1205. if macropos>maxmacrolen then
  1206. Message(scan_f_macro_buffer_overflow);
  1207. end;
  1208. { free buffer of macro ?}
  1209. if assigned(mac^.buftext) then
  1210. freemem(mac^.buftext,mac^.buflen);
  1211. { get new mem }
  1212. getmem(mac^.buftext,macropos);
  1213. mac^.buflen:=macropos;
  1214. { copy the text }
  1215. move(macrobuffer^,mac^.buftext^,macropos);
  1216. end;
  1217. end;
  1218. end;
  1219. end
  1220. else if hs='UNDEF' then
  1221. begin
  1222. skipspace;
  1223. hs:=read_string;
  1224. mac:=pmacrosym(macros^.search(hs));
  1225. if not assigned(mac) then
  1226. begin
  1227. mac:=new(pmacrosym,init(hs));
  1228. Message1(parser_m_macro_undefined,mac^.name);
  1229. mac^.defined:=false;
  1230. macros^.insert(mac);
  1231. end
  1232. else
  1233. begin
  1234. Message1(parser_m_macro_undefined,mac^.name);
  1235. mac^.defined:=false;
  1236. { delete old definition }
  1237. if assigned(mac^.buftext) then
  1238. begin
  1239. freemem(mac^.buftext,mac^.buflen);
  1240. mac^.buftext:=nil;
  1241. end;
  1242. end;
  1243. end
  1244. else if hs='PACKRECORDS' then
  1245. begin
  1246. skipspace;
  1247. if upcase(c)='N' then
  1248. begin
  1249. hs:=read_string;
  1250. if hs='NORMAL' then
  1251. aktpackrecords:=2
  1252. else
  1253. Message(scan_w_only_pack_records);
  1254. end
  1255. else
  1256. case read_number of
  1257. 1 : aktpackrecords:=1;
  1258. 2 : aktpackrecords:=2;
  1259. 4 : aktpackrecords:=4;
  1260. else Message(scan_w_only_pack_records);
  1261. end;
  1262. end
  1263. {$ifdef i386}
  1264. else if hs='I386_INTEL' then
  1265. aktasmmode:=I386_INTEL
  1266. else if hs='I386_DIRECT' then
  1267. aktasmmode:=I386_DIRECT
  1268. else if hs='I386_ATT' then
  1269. aktasmmode:=I386_ATT
  1270. {$endif}
  1271. else
  1272. begin
  1273. Message(scan_w_illegal_switch);
  1274. end;
  1275. end;
  1276. procedure src_comment;
  1277. begin
  1278. inc(comment_level);
  1279. { only warn for over one => incompatible with BP }
  1280. if (comment_level>1) then
  1281. Message1(scan_w_comment_level,tostr(comment_level));
  1282. nextchar;
  1283. while true do
  1284. begin
  1285. { handle compiler switches }
  1286. if (comment_level=1) and (c='$') then
  1287. handle_switches;
  1288. { handle_switches can dec comment_level, }
  1289. { if there is an include file }
  1290. while (c<>'}') and (comment_level>0) do
  1291. begin
  1292. if c='{' then
  1293. src_comment
  1294. else
  1295. begin
  1296. if c=#26 then Message(scan_f_end_of_file);
  1297. { if c=newline then write_line;}
  1298. nextchar;
  1299. end;
  1300. end;
  1301. { this is needed for the include files }
  1302. { if there is a end of comment then read it }
  1303. if c='}' then
  1304. begin
  1305. nextchar;
  1306. dec_comment_level;
  1307. { only warn for over one => incompatible with BP }
  1308. if (comment_level>1) then
  1309. Message1(scan_w_comment_level,tostr(comment_level));
  1310. end;
  1311. { checks }{ }
  1312. if c='{' then
  1313. begin
  1314. inc(comment_level);
  1315. { only warn for over one => incompatible with BP }
  1316. if (comment_level>1) then
  1317. Message1(scan_w_comment_level,tostr(comment_level));
  1318. nextchar;
  1319. end
  1320. else
  1321. break;
  1322. end;
  1323. end;
  1324. procedure delphi_comment;
  1325. begin
  1326. { C++/Delphi styled comment }
  1327. inc(comment_level);
  1328. nextchar;
  1329. { this is currently not supported }
  1330. if c='$' then
  1331. Message(scan_e_wrong_styled_switch);
  1332. while c<>newline do
  1333. begin
  1334. if c=#26 then Message(scan_f_end_of_file);
  1335. nextchar;
  1336. end;
  1337. dec(comment_level);
  1338. end;
  1339. const
  1340. yylexcount : longint = 0;
  1341. function yylex : ttoken;
  1342. var
  1343. y : ttoken;
  1344. code : word;
  1345. l : longint;
  1346. hs : string;
  1347. mac : pmacrosym;
  1348. hp : pinputfile;
  1349. hp2 : pchar;
  1350. label
  1351. yylex_exit;
  1352. begin
  1353. { was the last character a point ? }
  1354. { this code is needed because the scanner if there is a 1. found if }
  1355. { this is a floating point number or range like 1..3 }
  1356. if s_point then
  1357. begin
  1358. s_point:=false;
  1359. if c='.' then
  1360. begin
  1361. nextchar;
  1362. yylex:=POINTPOINT;
  1363. goto yylex_exit;
  1364. end;
  1365. yylex:=POINT;
  1366. goto yylex_exit;
  1367. end;
  1368. if c='{' then src_comment;
  1369. skipspace;
  1370. lasttokenpos:=inputpointer-1;
  1371. case c of
  1372. 'A'..'Z','a'..'z','_' :
  1373. begin
  1374. orgpattern:=c;
  1375. nextchar;
  1376. while c in ['A'..'Z','a'..'z','0'..'9','_'] do
  1377. begin
  1378. orgpattern:=orgpattern+c;
  1379. nextchar;
  1380. end;
  1381. pattern:=orgpattern;
  1382. uppervar(pattern);
  1383. if is_keyword(y) then
  1384. yylex:=y
  1385. else
  1386. begin
  1387. { this takes some time ... }
  1388. if support_macros then
  1389. begin
  1390. mac:=pmacrosym(macros^.search(pattern));
  1391. if assigned(mac) and (assigned(mac^.buftext)) then
  1392. begin
  1393. { don't forget the last char }
  1394. dec(inputpointer);
  1395. current_module^.current_inputfile^.bufpos:=inputpointer;
  1396. { this isn't a proper way, but ... }
  1397. hp:=new(pinputfile,init('','Macro '+pattern,''));
  1398. hp^.next:=current_module^.current_inputfile;
  1399. current_module^.current_inputfile:=hp;
  1400. current_module^.sourcefiles.register_file(hp);
  1401. { set an own buffer }
  1402. getmem(hp2,mac^.buflen+1);
  1403. current_module^.current_inputfile^.setbuf(hp2,mac^.buflen+1);
  1404. inputbuffer:=current_module^.current_inputfile^.buf;
  1405. { copy text }
  1406. move(mac^.buftext^,inputbuffer^,mac^.buflen);
  1407. { put end sign }
  1408. inputbuffer[mac^.buflen+1]:=#0;
  1409. { load c }
  1410. c:=inputbuffer[0];
  1411. { point to the next char }
  1412. inputpointer:=1;
  1413. { handle empty macros }
  1414. if c=#0 then reload;
  1415. { play it again ... }
  1416. inc(yylexcount);
  1417. if yylexcount>16 then
  1418. Message(scan_w_macro_deep_ten);
  1419. {$ifdef TP}
  1420. yylex:=yylex;
  1421. {$else}
  1422. yylex:=yylex();
  1423. {$endif}
  1424. { that's all folks }
  1425. dec(yylexcount);
  1426. goto yylex_exit;
  1427. end;
  1428. end;
  1429. yylex:=ID;
  1430. end;
  1431. goto yylex_exit;
  1432. end;
  1433. '$' : begin
  1434. pattern:=c;
  1435. nextchar;
  1436. while ((ord(c)>=ord('0')) and (ord(c)<=ord('9'))) or
  1437. (ord(upcase(c))>=ord('A')) and (ord(upcase(c))<=ord('F')) do
  1438. begin
  1439. pattern:=pattern+c;
  1440. nextchar;
  1441. end;
  1442. yylex:=INTCONST;
  1443. goto yylex_exit;
  1444. end;
  1445. {why ?ifdef FPC}
  1446. { because the tp val doesn't recognize this, }
  1447. { so it's useless in TP versions }
  1448. { it's solved with valint }
  1449. '%' : begin
  1450. pattern:=c;
  1451. nextchar;
  1452. while c in ['0','1'] do
  1453. begin
  1454. pattern:=pattern+c;
  1455. nextchar;
  1456. end;
  1457. yylex:=INTCONST;
  1458. goto yylex_exit;
  1459. end;
  1460. {cond removed endif}
  1461. '0'..'9' : begin
  1462. pattern:=c;
  1463. nextchar;
  1464. while c in ['0'..'9'] do
  1465. begin
  1466. pattern:=pattern+c;
  1467. nextchar;
  1468. end;
  1469. if c in ['.','e','E'] then
  1470. begin
  1471. if c='.' then
  1472. begin
  1473. nextchar;
  1474. if not(c in ['0'..'9']) then
  1475. begin
  1476. s_point:=true;
  1477. yylex:=INTCONST;
  1478. goto yylex_exit;
  1479. end;
  1480. pattern:=pattern+'.';
  1481. while c in ['0'..'9'] do
  1482. begin
  1483. pattern:=pattern+c;
  1484. nextchar;
  1485. end;
  1486. end;
  1487. if upcase(c)='E' then
  1488. begin
  1489. pattern:=pattern+'E';
  1490. nextchar;
  1491. if c in ['-','+'] then
  1492. begin
  1493. pattern:=pattern+c;
  1494. nextchar;
  1495. end;
  1496. if not(c in ['0'..'9']) then
  1497. Message(scan_f_illegal_char);
  1498. while c in ['0'..'9'] do
  1499. begin
  1500. pattern:=pattern+c;
  1501. nextchar;
  1502. end;
  1503. end;
  1504. yylex:=REALNUMBER;
  1505. goto yylex_exit;
  1506. end;
  1507. yylex:=INTCONST;
  1508. goto yylex_exit;
  1509. end;
  1510. ';' : begin
  1511. nextchar;
  1512. yylex:=SEMICOLON;
  1513. exit;
  1514. end;
  1515. '[' : begin
  1516. nextchar;
  1517. yylex:=LECKKLAMMER;
  1518. goto yylex_exit;
  1519. end;
  1520. ']' : begin
  1521. nextchar;
  1522. yylex:=RECKKLAMMER;
  1523. goto yylex_exit;
  1524. end;
  1525. '(' : begin
  1526. nextchar;
  1527. if c='*' then
  1528. begin
  1529. inc(comment_level);
  1530. nextchar;
  1531. while true do
  1532. begin
  1533. { this is currently not supported }
  1534. if c='$' then
  1535. Message(scan_e_wrong_styled_switch);
  1536. repeat
  1537. while c<>'*' do
  1538. begin
  1539. if c=#26 then Message(scan_f_end_of_file);
  1540. { if c=newline then write_line;}
  1541. nextchar;
  1542. end;
  1543. if c=#26 then Message(scan_f_end_of_file);
  1544. {if c=newline then write_line;}
  1545. nextchar;
  1546. until c=')';
  1547. dec(comment_level);
  1548. nextchar;
  1549. { check for *)(* }
  1550. if c='(' then
  1551. begin
  1552. nextchar;
  1553. if c<>'*' then
  1554. begin
  1555. yylex:=LKLAMMER;
  1556. goto yylex_exit;
  1557. end;
  1558. inc(comment_level);
  1559. nextchar;
  1560. end
  1561. else
  1562. begin
  1563. {$ifndef TP}
  1564. yylex:=yylex();
  1565. {$else TP}
  1566. yylex:=yylex;
  1567. {$endif TP}
  1568. goto yylex_exit;
  1569. end;
  1570. end;
  1571. end;
  1572. yylex:=LKLAMMER;
  1573. goto yylex_exit;
  1574. end;
  1575. ')' : begin
  1576. nextchar;
  1577. yylex:=RKLAMMER;
  1578. goto yylex_exit;
  1579. end;
  1580. '+' : begin
  1581. nextchar;
  1582. if (c='=') and c_like_operators then
  1583. begin
  1584. nextchar;
  1585. yylex:=_PLUSASN;
  1586. goto yylex_exit;
  1587. end
  1588. else
  1589. begin
  1590. yylex:=PLUS;
  1591. goto yylex_exit;
  1592. end;
  1593. end;
  1594. '-' : begin
  1595. nextchar;
  1596. if (c='=') and c_like_operators then
  1597. begin
  1598. nextchar;
  1599. yylex:=_MINUSASN;
  1600. goto yylex_exit;
  1601. end
  1602. else
  1603. begin
  1604. yylex:=MINUS;
  1605. goto yylex_exit;
  1606. end;
  1607. end;
  1608. ':' : begin
  1609. nextchar;
  1610. if c='=' then
  1611. begin
  1612. nextchar;
  1613. yylex:=ASSIGNMENT;
  1614. goto yylex_exit;
  1615. end
  1616. else
  1617. begin
  1618. yylex:=COLON;
  1619. goto yylex_exit;
  1620. end;
  1621. end;
  1622. '*' : begin
  1623. nextchar;
  1624. if (c='=') and c_like_operators then
  1625. begin
  1626. nextchar;
  1627. yylex:=_STARASN;
  1628. goto yylex_exit;
  1629. end
  1630. else
  1631. begin
  1632. yylex:=STAR;
  1633. goto yylex_exit;
  1634. end;
  1635. end;
  1636. '/' : begin
  1637. nextchar;
  1638. if (c='=') and c_like_operators then
  1639. begin
  1640. nextchar;
  1641. yylex:=_SLASHASN;
  1642. goto yylex_exit;
  1643. end
  1644. else if (c='/') then
  1645. begin
  1646. delphi_comment;
  1647. {$ifndef TP}
  1648. yylex:=yylex();
  1649. {$else TP}
  1650. yylex:=yylex;
  1651. {$endif TP}
  1652. goto yylex_exit;
  1653. end
  1654. else
  1655. begin
  1656. yylex:=SLASH;
  1657. goto yylex_exit;
  1658. end;
  1659. end;
  1660. '=' : begin
  1661. nextchar;
  1662. yylex:=EQUAL;
  1663. goto yylex_exit;
  1664. end;
  1665. '.' : begin
  1666. nextchar;
  1667. if c='.' then
  1668. begin
  1669. nextchar;
  1670. yylex:=POINTPOINT;
  1671. goto yylex_exit;
  1672. end
  1673. else
  1674. yylex:=POINT;
  1675. goto yylex_exit;
  1676. end;
  1677. '@' : begin
  1678. nextchar;
  1679. if c='@' then
  1680. begin
  1681. nextchar;
  1682. yylex:=DOUBLEADDR;
  1683. end
  1684. else
  1685. yylex:=KLAMMERAFFE;
  1686. goto yylex_exit;
  1687. end;
  1688. ',' : begin
  1689. nextchar;
  1690. yylex:=COMMA;
  1691. exit;
  1692. end;
  1693. '''','#','^' :
  1694. begin
  1695. if c='^' then
  1696. begin
  1697. nextchar;
  1698. c:=upcase(c);
  1699. if not(parse_types) and (c in ['A'..'Z']) then
  1700. begin
  1701. pattern:=chr(ord(c)-64);
  1702. nextchar;
  1703. end
  1704. else
  1705. begin
  1706. yylex:=CARET;
  1707. goto yylex_exit;
  1708. end;
  1709. end
  1710. else pattern:='';
  1711. while true do
  1712. case c of
  1713. '#' :
  1714. begin
  1715. hs:='';
  1716. nextchar;
  1717. if c='$' then
  1718. begin
  1719. hs:='$';
  1720. nextchar;
  1721. while c in (['0'..'9','a'..'f','A'..'F']) do
  1722. begin
  1723. hs:=hs+upcase(c);
  1724. nextchar;
  1725. end;
  1726. end
  1727. else
  1728. { FPC supports binary constants }
  1729. { %10101 evalutes to 37 }
  1730. if c='%' then
  1731. begin
  1732. nextchar;
  1733. while c in ['0','1'] do
  1734. begin
  1735. hs:=hs+upcase(c);
  1736. nextchar;
  1737. end;
  1738. end
  1739. else
  1740. begin
  1741. while (ord(c)>=ord('0')) and (ord(c)<=ord('9')) do
  1742. begin
  1743. hs:=hs+c;
  1744. nextchar;
  1745. end;
  1746. end;
  1747. valint(hs,l,code);
  1748. if (code<>0) or (l<0) or (l>255) then
  1749. Message(scan_e_illegal_char_const);
  1750. pattern:=pattern+chr(l);
  1751. end;
  1752. '''' :
  1753. begin
  1754. repeat
  1755. nextchar;
  1756. case c of
  1757. #26 : begin
  1758. Message(scan_f_end_of_file);
  1759. break;
  1760. end;
  1761. #13,
  1762. newline : begin
  1763. Message(scan_f_string_exceeds_line);
  1764. break;
  1765. end;
  1766. '''' : begin
  1767. nextchar;
  1768. if c<>'''' then
  1769. break;
  1770. end;
  1771. end;
  1772. pattern:=pattern+c;
  1773. until false;
  1774. end;
  1775. '^' : begin
  1776. nextchar;
  1777. c:=upcase(c);
  1778. if c in ['A'..'Z'] then
  1779. pattern:=pattern+chr(ord(c)-64)
  1780. else Message(scan_f_illegal_char);
  1781. nextchar;
  1782. end;
  1783. else break;
  1784. end;
  1785. { strings with length 1 become const chars }
  1786. if length(pattern)=1 then
  1787. yylex:=CCHAR
  1788. else yylex:=CSTRING;
  1789. goto yylex_exit;
  1790. end;
  1791. '>' : begin
  1792. nextchar;
  1793. if c='=' then
  1794. begin
  1795. nextchar;
  1796. yylex:=GTE;
  1797. goto yylex_exit;
  1798. end
  1799. else if c='>' then
  1800. begin
  1801. nextchar;
  1802. yylex:=_SHR;
  1803. goto yylex_exit;
  1804. end
  1805. else if c='<' then
  1806. begin
  1807. nextchar;
  1808. { >< is for a symetric diff for sets }
  1809. yylex:=SYMDIF;
  1810. goto yylex_exit;
  1811. end
  1812. else
  1813. begin
  1814. yylex:=GT;
  1815. goto yylex_exit;
  1816. end;
  1817. end;
  1818. '<' : begin
  1819. nextchar;
  1820. if c='>' then
  1821. begin
  1822. nextchar;
  1823. yylex:=UNEQUAL;
  1824. goto yylex_exit;
  1825. end
  1826. else if c='=' then
  1827. begin
  1828. nextchar;
  1829. yylex:=LTE;
  1830. goto yylex_exit;
  1831. end
  1832. else if c='<' then
  1833. begin
  1834. nextchar;
  1835. yylex:=_SHL;
  1836. goto yylex_exit;
  1837. end
  1838. else
  1839. begin
  1840. yylex:=LT;
  1841. goto yylex_exit;
  1842. end;
  1843. end;
  1844. #26 : begin
  1845. yylex:=_EOF;
  1846. goto yylex_exit;
  1847. end;
  1848. else
  1849. begin
  1850. update_line;
  1851. Message(scan_f_illegal_char);
  1852. end;
  1853. end;
  1854. yylex_exit :
  1855. update_line;
  1856. end;
  1857. const last_asmgetchar_was_a_comment : boolean = false;
  1858. function asmgetchar : char;
  1859. begin
  1860. if c='{' then
  1861. begin
  1862. src_comment;
  1863. { a comment is a seperator }
  1864. asmgetchar:=';';
  1865. last_asmgetchar_was_a_comment:=true;
  1866. end
  1867. else
  1868. begin
  1869. update_line;
  1870. if last_asmgetchar_was_a_comment then
  1871. begin
  1872. last_asmgetchar_was_a_comment:=false;
  1873. asmgetchar:=c;
  1874. exit;
  1875. end;
  1876. nextchar;
  1877. asmgetchar:=c;
  1878. if c='/' then
  1879. begin
  1880. nextchar;
  1881. if c='/' then
  1882. begin
  1883. delphi_comment;
  1884. asmgetchar:=c;
  1885. end
  1886. else
  1887. begin
  1888. last_asmgetchar_was_a_comment:=true;
  1889. asmgetchar:='/';
  1890. end;
  1891. end;
  1892. end;
  1893. end;
  1894. procedure initscanner(const fn: string);
  1895. var
  1896. d:dirstr;
  1897. n:namestr;
  1898. e:extstr;
  1899. begin
  1900. fsplit(fn,d,n,e);
  1901. current_module^.current_inputfile:=new(pinputfile,init(d,n,e));
  1902. current_module^.current_inputfile^.reset;
  1903. current_module^.sourcefiles.register_file(current_module^.current_inputfile);
  1904. if ioresult<>0 then
  1905. Message(scan_f_cannot_open_input);
  1906. inputbuffer:=current_module^.current_inputfile^.buf;
  1907. preprocstack:=nil;
  1908. reload;
  1909. comment_level:=0;
  1910. lasttokenpos:=0;
  1911. lastlinepointer:=0;
  1912. s_point:=false;
  1913. end;
  1914. procedure donescanner(compiled_at_higher_level : boolean);
  1915. var
  1916. st : string;
  1917. begin
  1918. if not (compiled_at_higher_level) and assigned(preprocstack) then
  1919. begin
  1920. if preprocstack^.t=PP_IFDEF then
  1921. st:='$IF(N)(DEF)'
  1922. else
  1923. st:='$ELSE';
  1924. Message3(scan_e_endif_expected,st,preprocstack^.name,tostr(preprocstack^.line_nb));
  1925. end;
  1926. end;
  1927. end.
  1928. {
  1929. $Log$
  1930. Revision 1.1 1998-03-25 11:18:15 root
  1931. Initial revision
  1932. Revision 1.43 1998/03/24 21:48:34 florian
  1933. * just a couple of fixes applied:
  1934. - problem with fixed16 solved
  1935. - internalerror 10005 problem fixed
  1936. - patch for assembler reading
  1937. - small optimizer fix
  1938. - mem is now supported
  1939. Revision 1.42 1998/03/10 17:19:29 peter
  1940. * fixed bug0108
  1941. * better linebreak scanning (concentrated in nextchar(), it supports
  1942. #10, #13, #10#13, #13#10
  1943. Revision 1.41 1998/03/10 16:27:45 pierre
  1944. * better line info in stabs debug
  1945. * symtabletype and lexlevel separated into two fields of tsymtable
  1946. + ifdef MAKELIB for direct library output, not complete
  1947. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1948. working
  1949. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1950. working
  1951. Revision 1.40 1998/03/10 01:17:27 peter
  1952. * all files have the same header
  1953. * messages are fully implemented, EXTDEBUG uses Comment()
  1954. + AG... files for the Assembler generation
  1955. Revision 1.39 1998/03/09 12:58:14 peter
  1956. * FWait warning is only showed for Go32V2 and $E+
  1957. * opcode tables moved to i386.pas/m68k.pas to reduce circular uses (and
  1958. for m68k the same tables are removed)
  1959. + $E for i386
  1960. Revision 1.38 1998/03/06 00:52:52 peter
  1961. * replaced all old messages from errore.msg, only ExtDebug and some
  1962. Comment() calls are left
  1963. * fixed options.pas
  1964. Revision 1.37 1998/03/04 17:34:06 michael
  1965. + Changed ifdef FPK to ifdef FPC
  1966. Revision 1.36 1998/03/03 22:38:34 peter
  1967. * the last 3 files
  1968. Revision 1.35 1998/03/02 01:49:26 peter
  1969. * renamed target_DOS to target_GO32V1
  1970. + new verbose system, merged old errors and verbose units into one new
  1971. verbose.pas, so errors.pas is obsolete
  1972. Revision 1.34 1998/02/26 11:57:16 daniel
  1973. * New assembler optimizations commented out, because of bugs.
  1974. * Use of dir-/name- and extstr.
  1975. Revision 1.33 1998/02/22 23:03:32 peter
  1976. * renamed msource->mainsource and name->unitname
  1977. * optimized filename handling, filename is not seperate anymore with
  1978. path+name+ext, this saves stackspace and a lot of fsplit()'s
  1979. * recompiling of some units in libraries fixed
  1980. * shared libraries are working again
  1981. + $LINKLIB <lib> to support automatic linking to libraries
  1982. + libraries are saved/read from the ppufile, also allows more libraries
  1983. per ppufile
  1984. Revision 1.32 1998/02/17 21:20:59 peter
  1985. + Script unit
  1986. + __EXIT is called again to exit a program
  1987. - target_info.link/assembler calls
  1988. * linking works again for dos
  1989. * optimized a few filehandling functions
  1990. * fixed stabs generation for procedures
  1991. Revision 1.31 1998/02/16 12:51:44 michael
  1992. + Implemented linker object
  1993. Revision 1.30 1998/02/13 10:35:45 daniel
  1994. * Made Motorola version compilable.
  1995. * Fixed optimizer
  1996. Revision 1.29 1998/02/12 17:19:25 florian
  1997. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1998. also that aktswitches isn't a pointer)
  1999. Revision 1.28 1998/02/12 11:50:44 daniel
  2000. Yes! Finally! After three retries, my patch!
  2001. Changes:
  2002. Complete rewrite of psub.pas.
  2003. Added support for DLL's.
  2004. Compiler requires less memory.
  2005. Platform units for each platform.
  2006. Revision 1.27 1998/02/07 09:39:27 florian
  2007. * correct handling of in_main
  2008. + $D,$T,$X,$V like tp
  2009. Revision 1.26 1998/02/05 22:27:06 florian
  2010. * small problems fixed: remake3 should now work
  2011. Revision 1.25 1998/02/03 22:13:35 florian
  2012. * clean up
  2013. Revision 1.24 1998/02/02 23:42:38 florian
  2014. * data is now dword aligned per default else the stack ajustements are useless
  2015. + $wait directive: stops compiling til return is presseed (a message is
  2016. also written, useful to give the user a change to notice a message
  2017. Revision 1.23 1998/02/02 13:13:28 pierre
  2018. * line_count transfered to tinputfile, to avoid crosscounting
  2019. Revision 1.22 1998/01/30 17:30:10 pierre
  2020. + better line counting mechanism
  2021. line count updated only when important tokens are read
  2022. (not for comment , ; )
  2023. Revision 1.21 1998/01/26 19:09:52 peter
  2024. * fixed EOF in open string constant reading
  2025. Revision 1.20 1998/01/22 08:56:55 peter
  2026. * Fixed string exceeds end of line problem (#13 is not a linux
  2027. linebreak)
  2028. Revision 1.19 1998/01/20 18:18:46 peter
  2029. * fixed skip_until_pragma, bug0044 and the compiler recompile good
  2030. Revision 1.18 1998/01/20 16:30:17 pierre
  2031. * bug with braces in log from Peter removed
  2032. Revision 1.17 1998/01/20 15:14:33 peter
  2033. * fixes bug 44 with multiple $'s between skipped $IFDEF and $ENDIF
  2034. Revision 1.16 1998/01/13 16:16:06 pierre
  2035. * bug in interdependent units handling
  2036. - primary unit was not in loaded_units list
  2037. - current_module^.symtable was assigned too early
  2038. - donescanner must not call error if the compilation
  2039. of the unit was done at a higher level.
  2040. Revision 1.15 1998/01/09 23:08:34 florian
  2041. + C++/Delphi styled //-comments
  2042. * some bugs in Delphi object model fixed
  2043. + override directive
  2044. Revision 1.14 1998/01/09 18:01:17 florian
  2045. * VIRTUAL isn't anymore a common keyword
  2046. + DYNAMIC is equal to VIRTUAL
  2047. Revision 1.13 1998/01/09 13:39:57 florian
  2048. * public, protected and private aren't anymore key words
  2049. + published is equal to public
  2050. Revision 1.12 1997/12/12 13:28:41 florian
  2051. + version 0.99.0
  2052. * all WASM options changed into MASM
  2053. + -O2 for Pentium II optimizations
  2054. Revision 1.11 1997/12/10 23:07:30 florian
  2055. * bugs fixed: 12,38 (also m68k),39,40,41
  2056. + warning if a system unit is without -Us compiled
  2057. + warning if a method is virtual and private (was an error)
  2058. * some indentions changed
  2059. + factor does a better error recovering (omit some crashes)
  2060. + problem with @type(x) removed (crashed the compiler)
  2061. Revision 1.10 1997/12/09 14:09:15 carl
  2062. * bugfix of Runerror 216 when reading a null character (such as trying to
  2063. compile a binary file)
  2064. Revision 1.9 1997/12/08 11:51:12 pierre
  2065. * corrected some buggy code in hexadecimal number reading
  2066. Revision 1.8 1997/12/05 14:22:20 daniel
  2067. * Did some source code beutification.
  2068. Revision 1.7 1997/12/03 13:43:14 carl
  2069. + OUTPUT_FORMAT switch is processor specific to i386.
  2070. Revision 1.6 1997/12/02 16:00:55 carl
  2071. * bugfix of include files - now gives out a fatalerror if not found,
  2072. otherwise would create invalid pointer operations everywhere.
  2073. * bugfix of $i+xyz now the $i+/- switch is correctly recognized as io
  2074. checking and ont an include directive.
  2075. Revision 1.5 1997/11/28 18:14:48 pierre
  2076. working version with several bug fixes
  2077. Revision 1.4 1997/11/28 14:26:26 florian
  2078. Fixed some bugs
  2079. Revision 1.3 1997/11/27 17:47:14 carl
  2080. * fixed bug with assem switches and m68k.
  2081. Revision 1.2 1997/11/27 17:40:48 carl
  2082. + assem type scanning switches for intel targets.
  2083. Revision 1.1.1.1 1997/11/27 08:33:01 michael
  2084. FPC Compiler CVS start
  2085. Pre-CVS log:
  2086. CEC Carl-Eric Codere
  2087. FK Florian Klaempfl
  2088. PM Pierre Muller
  2089. + feature added
  2090. - removed
  2091. * bug fixed or changed
  2092. History:
  2093. 6th september 1997:
  2094. + added support for global switches (i.e $X and $E (for m68k)) (CEC)
  2095. 1st october 1997:
  2096. + added $ifopt as dummy which is always rejected (FK)
  2097. 13th october 1997:
  2098. * user defined message are now written via the errors unit
  2099. and exterror (FK)
  2100. + compiler switch $INFO added, does the same like $MESSAGE,
  2101. the text is written via comment(v_info,...) (FK)
  2102. + $STOP and $FATALERROR added: they are equivalent, the
  2103. following message is written and the compiler stops (FK)
  2104. - write_c, no more necessary (FK)
  2105. 14th october 1997:
  2106. + wrong line counting corrected: <comment start> $I test
  2107. <comment end>
  2108. (FK)
  2109. 17th october 1997:
  2110. + support of $if expr (FK)
  2111. * $define a=1234 to a:=1234 (FK)
  2112. + -So allows now <comment start> <comment start> <comment end>
  2113. as comment (preocedure dec_comment_level) (FK)
  2114. 22th october 1997:
  2115. + $NOTE (FK)
  2116. 9th november 1997:
  2117. + added updating of line_no in asmgetchar. (CEC)
  2118. 14th november 1997:
  2119. * fixed problem with asm line counting. (CEC)
  2120. 17th november 1997:
  2121. + kommentar renamed src_comment and kommentarebene renamed comment_level (PM)
  2122. }