pmodules.pas 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Florian Klaempfl
  4. Handles the parsing and loading of the modules (ppufiles)
  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 pmodules;
  19. interface
  20. uses
  21. dos,strings,
  22. cobjects,globals,scanner,symtable,aasm,tree,pass_1,
  23. types,hcodegen,files,verbose,systems,link,assemble
  24. {$ifdef GDB}
  25. ,gdb
  26. {$endif GDB}
  27. {$ifdef NEWPPU}
  28. ,ppu
  29. {$endif}
  30. { parser specific stuff }
  31. ,pbase,pdecl,pstatmnt,psub
  32. { processor specific stuff }
  33. {$ifdef i386}
  34. ,i386
  35. ,cgai386
  36. ,tgeni386
  37. ,cgi386
  38. ,aopt386
  39. {$endif}
  40. {$ifdef m68k}
  41. ,m68k
  42. ,cga68k
  43. ,tgen68k
  44. ,cg68k
  45. {$endif}
  46. ;
  47. procedure addlinkerfiles(hp:pmodule);
  48. function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
  49. procedure proc_unit;
  50. procedure proc_program(islibrary : boolean);
  51. implementation
  52. uses
  53. parser;
  54. {$I innr.inc}
  55. procedure addlinkerfiles(hp:pmodule);
  56. begin
  57. with hp^ do
  58. begin
  59. while not linkofiles.empty do
  60. Linker.AddObject(linkofiles.Get);
  61. while not linksharedlibs.empty do
  62. Linker.AddSharedLibrary(linksharedlibs.Get);
  63. while not linkstaticlibs.empty do
  64. Linker.AddStaticLibrary(linkstaticlibs.Get);
  65. end;
  66. end;
  67. procedure insertsegment;
  68. begin
  69. {Insert Ident of the compiler}
  70. if (not (cs_smartlink in aktswitches))
  71. {$ifndef EXTDEBUG}
  72. and (not current_module^.is_unit)
  73. {$endif}
  74. then
  75. begin
  76. datasegment^.insert(new(pai_align,init(4)));
  77. datasegment^.insert(new(pai_string,init('FPC '+version_string+' for '+target_string+' - '+target_info.short_name)));
  78. end;
  79. { Insert start and end of sections }
  80. codesegment^.insert(new(pai_section,init(sec_code)));
  81. codesegment^.concat(new(pai_section,init(sec_none)));
  82. datasegment^.insert(new(pai_section,init(sec_data)));
  83. datasegment^.concat(new(pai_section,init(sec_none)));
  84. bsssegment^.insert(new(pai_section,init(sec_bss)));
  85. bsssegment^.concat(new(pai_section,init(sec_none)));
  86. consts^.insert(new(pai_asm_comment,init('Constants')));
  87. consts^.insert(new(pai_section,init(sec_data)));
  88. consts^.concat(new(pai_section,init(sec_none)));
  89. end;
  90. procedure insertheap;
  91. begin
  92. if (cs_smartlink in aktswitches) then
  93. begin
  94. bsssegment^.concat(new(pai_cut,init));
  95. datasegment^.concat(new(pai_cut,init));
  96. end;
  97. { On the Macintosh Classic M68k Architecture
  98. The Heap variable is simply a POINTER to the
  99. real HEAP. The HEAP must be set up by the RTL
  100. and must store the pointer in this value.
  101. On OS/2 the heap is also intialized by the RTL. We do
  102. not output a pointer }
  103. case target_info.target of
  104. target_OS2 : ;
  105. target_Mac68K : bsssegment^.concat(new(pai_datablock,init_global('HEAP',4)));
  106. else
  107. bsssegment^.concat(new(pai_datablock,init_global('HEAP',heapsize)));
  108. end;
  109. datasegment^.concat(new(pai_symbol,init_global('HEAPSIZE')));
  110. datasegment^.concat(new(pai_const,init_32bit(heapsize)));
  111. end;
  112. procedure inserttargetspecific;
  113. var
  114. i : longint;
  115. begin
  116. case target_info.target of
  117. target_GO32V2 : begin
  118. { stacksize can be specified }
  119. datasegment^.concat(new(pai_symbol,init_global('__stklen')));
  120. datasegment^.concat(new(pai_const,init_32bit(stacksize)));
  121. end;
  122. target_WIN32 : begin
  123. { generate the last entry for the imports directory }
  124. if not(assigned(importssection)) then
  125. importssection:=new(paasmoutput,init);
  126. { $3 ensure that it is the last entry, all other entries }
  127. { are written to $2 }
  128. importssection^.concat(new(pai_section,init_idata(3)));
  129. for i:=1 to 5 do
  130. importssection^.concat(new(pai_const,init_32bit(0)));
  131. end;
  132. end;
  133. end;
  134. { all intern procedures for system unit }
  135. procedure insertinternsyms(p : psymtable);
  136. begin
  137. p^.insert(new(psyssym,init('CONCAT',in_concat_x)));
  138. p^.insert(new(psyssym,init('WRITE',in_write_x)));
  139. p^.insert(new(psyssym,init('WRITELN',in_writeln_x)));
  140. p^.insert(new(psyssym,init('ASSIGNED',in_assigned_x)));
  141. p^.insert(new(psyssym,init('READ',in_read_x)));
  142. p^.insert(new(psyssym,init('READLN',in_readln_x)));
  143. p^.insert(new(psyssym,init('OFS',in_ofs_x)));
  144. p^.insert(new(psyssym,init('SIZEOF',in_sizeof_x)));
  145. p^.insert(new(psyssym,init('TYPEOF',in_typeof_x)));
  146. p^.insert(new(psyssym,init('LOW',in_low_x)));
  147. p^.insert(new(psyssym,init('HIGH',in_high_x)));
  148. p^.insert(new(psyssym,init('SEG',in_seg_x)));
  149. p^.insert(new(psyssym,init('ORD',in_ord_x)));
  150. p^.insert(new(psyssym,init('PRED',in_pred_x)));
  151. p^.insert(new(psyssym,init('SUCC',in_succ_x)));
  152. p^.insert(new(psyssym,init('EXCLUDE',in_exclude_x_y)));
  153. p^.insert(new(psyssym,init('INCLUDE',in_include_x_y)));
  154. p^.insert(new(psyssym,init('BREAK',in_break)));
  155. p^.insert(new(psyssym,init('CONTINUE',in_continue)));
  156. { for testing purpose }
  157. p^.insert(new(psyssym,init('DECI',in_dec_x)));
  158. p^.insert(new(psyssym,init('INCI',in_inc_x)));
  159. p^.insert(new(psyssym,init('STR',in_str_x_string)));
  160. end;
  161. { all the types inserted into the system unit }
  162. procedure insert_intern_types(p : psymtable);
  163. {$ifdef GDB}
  164. var
  165. { several defs to simulate more or less C++ objects for GDB }
  166. vmtdef : precdef;
  167. pvmtdef : ppointerdef;
  168. vmtarraydef : parraydef;
  169. vmtsymtable : psymtable;
  170. {$endif GDB}
  171. begin
  172. p^.insert(new(ptypesym,init('longint',s32bitdef)));
  173. p^.insert(new(ptypesym,init('ulong',u32bitdef)));
  174. p^.insert(new(ptypesym,init('void',voiddef)));
  175. p^.insert(new(ptypesym,init('char',cchardef)));
  176. {$ifdef i386}
  177. p^.insert(new(ptypesym,init('s64real',c64floatdef)));
  178. {$endif i386}
  179. p^.insert(new(ptypesym,init('s80real',s80floatdef)));
  180. p^.insert(new(ptypesym,init('cs32fixed',s32fixeddef)));
  181. p^.insert(new(ptypesym,init('byte',u8bitdef)));
  182. p^.insert(new(ptypesym,init('string',cstringdef)));
  183. p^.insert(new(ptypesym,init('longstring',clongstringdef)));
  184. p^.insert(new(ptypesym,init('ansistring',cansistringdef)));
  185. p^.insert(new(ptypesym,init('widestring',cwidestringdef)));
  186. p^.insert(new(ptypesym,init('word',u16bitdef)));
  187. p^.insert(new(ptypesym,init('boolean',booldef)));
  188. p^.insert(new(ptypesym,init('void_pointer',voidpointerdef)));
  189. p^.insert(new(ptypesym,init('file',cfiledef)));
  190. {$ifdef i386}
  191. p^.insert(new(ptypesym,init('REAL',new(pfloatdef,init(s64real)))));
  192. p^.insert(new(ptypesym,init('COMP',new(pfloatdef,init(s64bit)))));
  193. p^.insert(new(ptypesym,init('EXTENDED',new(pfloatdef,init(s80real)))));
  194. {$endif}
  195. {$ifdef m68k}
  196. { internal definitions }
  197. p^.insert(new(ptypesym,init('s32real',c64floatdef)));
  198. { mappings... }
  199. p^.insert(new(ptypesym,init('REAL',new(pfloatdef,init(s32real)))));
  200. if (cs_fp_emulation) in aktswitches then
  201. p^.insert(new(ptypesym,init('DOUBLE',new(pfloatdef,init(s32real)))))
  202. else
  203. p^.insert(new(ptypesym,init('DOUBLE',new(pfloatdef,init(s64real)))));
  204. { p^.insert(new(ptypesym,init('COMP',new(pfloatdef,init(s32real)))));}
  205. if (cs_fp_emulation) in aktswitches then
  206. p^.insert(new(ptypesym,init('EXTENDED',new(pfloatdef,init(s32real)))))
  207. else
  208. p^.insert(new(ptypesym,init('EXTENDED',new(pfloatdef,init(s80real)))));
  209. {$endif}
  210. p^.insert(new(ptypesym,init('SINGLE',new(pfloatdef,init(s32real)))));
  211. p^.insert(new(ptypesym,init('POINTER',new(ppointerdef,init(voiddef)))));
  212. p^.insert(new(ptypesym,init('STRING',cstringdef)));
  213. p^.insert(new(ptypesym,init('LONGSTRING',clongstringdef)));
  214. p^.insert(new(ptypesym,init('ANSISTRING',cansistringdef)));
  215. p^.insert(new(ptypesym,init('WIDESTRING',cwidestringdef)));
  216. p^.insert(new(ptypesym,init('BOOLEAN',new(porddef,init(bool8bit,0,1)))));
  217. p^.insert(new(ptypesym,init('CHAR',new(porddef,init(uchar,0,255)))));
  218. p^.insert(new(ptypesym,init('TEXT',new(pfiledef,init(ft_text,nil)))));
  219. p^.insert(new(ptypesym,init('CARDINAL',new(porddef,init(u32bit,0,$ffffffff)))));
  220. p^.insert(new(ptypesym,init('FIXED',new(pfloatdef,init(f32bit)))));
  221. p^.insert(new(ptypesym,init('FIXED16',new(pfloatdef,init(f16bit)))));
  222. p^.insert(new(ptypesym,init('TYPEDFILE',new(pfiledef,init(ft_typed,voiddef)))));
  223. { !!!!!
  224. p^.insert(new(ptypesym,init('COMP',new(porddef,init(s64bit,0,0)))));
  225. p^.insert(new(ptypesym,init('SINGLE',new(porddef,init(s32real,0,0)))));
  226. p^.insert(new(ptypesym,init('EXTENDED',new(porddef,init(s80real,0,0)))));
  227. p^.insert(new(ptypesym,init('FILE',new(pfiledef,init(ft_untyped,nil)))));
  228. }
  229. { Add a type for virtual method tables in lowercase }
  230. { so it isn't reachable! }
  231. {$ifdef GDB}
  232. vmtsymtable:=new(psymtable,init(recordsymtable));
  233. vmtdef:=new(precdef,init(vmtsymtable));
  234. pvmtdef:=new(ppointerdef,init(vmtdef));
  235. vmtsymtable^.insert(new(pvarsym,init('parent',pvmtdef)));
  236. vmtsymtable^.insert(new(pvarsym,init('length',globaldef('longint'))));
  237. vmtsymtable^.insert(new(pvarsym,init('mlength',globaldef('longint'))));
  238. vmtarraydef:=new(parraydef,init(0,1,s32bitdef));
  239. vmtarraydef^.definition := voidpointerdef;
  240. vmtsymtable^.insert(new(pvarsym,init('__pfn',vmtarraydef)));
  241. p^.insert(new(ptypesym,init('__vtbl_ptr_type',vmtdef)));
  242. p^.insert(new(ptypesym,init('pvmt',pvmtdef)));
  243. vmtarraydef:=new(parraydef,init(0,1,s32bitdef));
  244. vmtarraydef^.definition := pvmtdef;
  245. p^.insert(new(ptypesym,init('vtblarray',vmtarraydef)));
  246. {$endif GDB}
  247. insertinternsyms(p);
  248. end;
  249. procedure load_ppu(oldhp,hp : pmodule;compile_system : boolean);
  250. var
  251. loaded_unit : pmodule;
  252. b : byte;
  253. checksum,
  254. {$ifndef NEWPPU}
  255. count,
  256. {$endif NEWPPU}
  257. nextmapentry : longint;
  258. hs : string;
  259. begin
  260. { init the map }
  261. new(hp^.map);
  262. nextmapentry:=1;
  263. {$ifdef NEWPPU}
  264. { load the used units from interface }
  265. b:=hp^.ppufile^.readentry;
  266. if b=ibloadunit_int then
  267. begin
  268. while not hp^.ppufile^.endofentry do
  269. begin
  270. hs:=hp^.ppufile^.getstring;
  271. checksum:=hp^.ppufile^.getlongint;
  272. loaded_unit:=loadunit(hs,false,false);
  273. if hp^.compiled then
  274. exit;
  275. { if the crc of a used unit is the same as written to the
  276. PPU file, we needn't to recompile the current unit }
  277. if (loaded_unit^.crc<>checksum) then
  278. begin
  279. { we have to compile the current unit remove stuff which isn't
  280. needed }
  281. { forget the map }
  282. dispose(hp^.map);
  283. hp^.map:=nil;
  284. { remove the ppufile }
  285. dispose(hp^.ppufile,done);
  286. hp^.ppufile:=nil;
  287. { recompile or give an fatal error }
  288. if not(hp^.sources_avail) then
  289. Message1(unit_f_cant_compile_unit,hp^.modulename^)
  290. else
  291. begin
  292. {$ifdef TEST_TEMPCLOSE}
  293. if assigned(oldhp^.current_inputfile) then
  294. oldhp^.current_inputfile^.tempclose;
  295. {$endif TEST_TEMPCLOSE}
  296. compile(hp^.mainsource^,compile_system);
  297. {$ifdef TEST_TEMPCLOSE}
  298. if not oldhp^.compiled then
  299. oldhp^.current_inputfile^.tempreopen;
  300. {$endif TEST_TEMPCLOSE}
  301. end;
  302. exit;
  303. end;
  304. { setup the map entry for deref }
  305. hp^.map^[nextmapentry]:=loaded_unit^.symtable;
  306. inc(nextmapentry);
  307. if nextmapentry>maxunits then
  308. Message(unit_f_too_much_units);
  309. end;
  310. { ok, now load the unit }
  311. hp^.symtable:=new(punitsymtable,load(hp));
  312. { if this is the system unit insert the intern symbols }
  313. make_ref:=false;
  314. if compile_system then
  315. insertinternsyms(psymtable(hp^.symtable));
  316. make_ref:=true;
  317. end;
  318. { now only read the implementation part }
  319. hp^.in_implementation:=true;
  320. { load the used units from implementation }
  321. b:=hp^.ppufile^.readentry;
  322. if b=ibloadunit_imp then
  323. begin
  324. while not hp^.ppufile^.endofentry do
  325. begin
  326. hs:=hp^.ppufile^.getstring;
  327. checksum:=hp^.ppufile^.getlongint;
  328. loaded_unit:=loadunit(hs,false,false);
  329. if hp^.compiled then
  330. exit;
  331. end;
  332. end;
  333. {$ifdef NEWPPU}
  334. { The next entry should be an ibendimplementation }
  335. b:=hp^.ppufile^.readentry;
  336. if b <> ibendimplementation then
  337. Message1(unit_f_ppu_invalid_entry,tostr(b));
  338. { The next entry should be an ibend }
  339. b:=hp^.ppufile^.readentry;
  340. if b <> ibend then
  341. Message1(unit_f_ppu_invalid_entry,tostr(b));
  342. {$endif}
  343. hp^.ppufile^.close;
  344. {! dispose(hp^.ppufile,done);}
  345. {$else}
  346. { load the used units from interface }
  347. hp^.ppufile^.read_data(b,1,count);
  348. while (b=ibloadunit) do
  349. begin
  350. { read unit name }
  351. hp^.ppufile^.read_data(hs[0],1,count);
  352. hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
  353. hp^.ppufile^.read_data(checksum,4,count);
  354. loaded_unit:=loadunit(hs,false,false);
  355. if hp^.compiled then
  356. exit;
  357. { if the crc of a used unit is the same as }
  358. { written to the PPU file, we needn't to }
  359. { recompile the current unit }
  360. if (loaded_unit^.crc<>checksum) then
  361. begin
  362. { we have to compile the current unit }
  363. { remove stuff which isn't needed }
  364. { forget the map }
  365. dispose(hp^.map);
  366. hp^.map:=nil;
  367. hp^.ppufile^.close;
  368. dispose(hp^.ppufile,done);
  369. hp^.ppufile:=nil;
  370. if not(hp^.sources_avail) then
  371. Message1(unit_f_cant_compile_unit,hp^.modulename^)
  372. else
  373. begin
  374. {$ifdef TEST_TEMPCLOSE}
  375. if assigned(oldhp^.current_inputfile) then
  376. oldhp^.current_inputfile^.tempclose;
  377. {$endif TEST_TEMPCLOSE}
  378. compile(hp^.mainsource^,compile_system);
  379. {$ifdef TEST_TEMPCLOSE}
  380. if not oldhp^.compiled then
  381. oldhp^.current_inputfile^.tempreopen;
  382. {$endif TEST_TEMPCLOSE}
  383. end;
  384. exit;
  385. end;
  386. { setup the map entry for deref }
  387. hp^.map^[nextmapentry]:=loaded_unit^.symtable;
  388. inc(nextmapentry);
  389. if nextmapentry>maxunits then
  390. Message(unit_f_too_much_units);
  391. { read until ibend }
  392. hp^.ppufile^.read_data(b,1,count);
  393. end;
  394. { ok, now load the unit }
  395. hp^.symtable:=new(punitsymtable,load(hp));
  396. { if this is the system unit insert the intern }
  397. { symbols }
  398. make_ref:=false;
  399. if compile_system then
  400. insertinternsyms(psymtable(hp^.symtable));
  401. make_ref:=true;
  402. { now only read the implementation part }
  403. hp^.in_implementation:=true;
  404. { load the used units from implementation }
  405. hp^.ppufile^.read_data(b,1,count);
  406. while (b<>ibend) and (b=ibloadunit) do
  407. begin
  408. { read unit name }
  409. hp^.ppufile^.read_data(hs[0],1,count);
  410. hp^.ppufile^.read_data(hs[1],byte(hs[0]),count);
  411. hp^.ppufile^.read_data(checksum,4,count);
  412. loaded_unit:=loadunit(hs,false,false);
  413. if hp^.compiled then exit;
  414. { if the crc of a used unit is the same as }
  415. { written to the PPU file, we needn't to }
  416. { recompile the current unit }
  417. { but for the implementation part }
  418. { the written crc is false, because }
  419. { not defined when writing the ppufile !! }
  420. (* if {(loaded_unit^.crc<>checksum) or}
  421. (do_build and loaded_unit^.sources_avail) then
  422. begin
  423. { we have to compile the current unit }
  424. { remove stuff which isn't needed }
  425. { forget the map }
  426. dispose(hp^.map);
  427. hp^.map:=nil;
  428. hp^.ppufile^.close;
  429. dispose(hp^.ppufile,done);
  430. hp^.ppufile:=nil;
  431. if not(hp^.sources_avail) then
  432. Message1(unit_f_cant_compile_unit,hp^.unitname^)
  433. else
  434. begin
  435. {ifdef TEST_TEMPCLOSE}
  436. oldhp^.current_inputfile^.tempclose;
  437. {endif TEST_TEMPCLOSE}
  438. compile(hp^.mainsource^,compile_system);
  439. {ifdef TEST_TEMPCLOSE}
  440. oldhp^.current_inputfile^.tempclose;
  441. {endif TEST_TEMPCLOSE}
  442. end;
  443. exit;
  444. end; *)
  445. { read until ibend }
  446. hp^.ppufile^.read_data(b,1,count);
  447. end;
  448. hp^.ppufile^.close;
  449. {$endif}
  450. dispose(hp^.map);
  451. hp^.map:=nil;
  452. end;
  453. function loadunit(const s : string;compile_system, in_uses : boolean) : pmodule;
  454. var
  455. st : punitsymtable;
  456. old_current_module,hp,nextmodule : pmodule;
  457. pu : pused_unit;
  458. hs : pstring;
  459. begin
  460. old_current_module:=current_module;
  461. { be sure not to mix lines from different files }
  462. { update_line; }
  463. { unit not found }
  464. st:=nil;
  465. { search all loaded units }
  466. hp:=pmodule(loaded_units.first);
  467. while assigned(hp) do
  468. begin
  469. if hp^.modulename^=s then
  470. begin
  471. { the unit is already registered }
  472. { and this means that the unit }
  473. { is already compiled }
  474. { else there is a cyclic unit use }
  475. if assigned(hp^.symtable) then
  476. st:=punitsymtable(hp^.symtable)
  477. else
  478. begin
  479. { recompile the unit ? }
  480. if (not current_module^.in_implementation) and (hp^.in_implementation) then
  481. Message(unit_f_circular_unit_reference);
  482. end;
  483. break;
  484. end;
  485. { the next unit }
  486. hp:=pmodule(hp^.next);
  487. end;
  488. { no error and the unit isn't loaded }
  489. if not(assigned(hp)) and (st=nil) then
  490. begin
  491. { generates a new unit info record }
  492. hp:=new(pmodule,init(s,true));
  493. { now we can register the unit }
  494. loaded_units.insert(hp);
  495. current_module:=hp;
  496. { force build ? }
  497. if (hp^.do_compile) or (hp^.sources_avail and do_build) then
  498. begin
  499. { we needn't the ppufile }
  500. if assigned(hp^.ppufile) then
  501. begin
  502. dispose(hp^.ppufile,done);
  503. hp^.ppufile:=nil;
  504. end;
  505. if not(hp^.sources_avail) then
  506. Message1(unit_f_cant_compile_unit,hp^.modulename^)
  507. else
  508. begin
  509. {$ifdef TEST_TEMPCLOSE}
  510. if assigned(old_current_module^.current_inputfile) then
  511. old_current_module^.current_inputfile^.tempclose;
  512. {$endif TEST_TEMPCLOSE}
  513. compile(hp^.mainsource^,compile_system);
  514. {$ifdef TEST_TEMPCLOSE}
  515. if not old_current_module^.compiled then
  516. old_current_module^.current_inputfile^.tempreopen;
  517. {$endif TEST_TEMPCLOSE}
  518. end;
  519. end
  520. else
  521. begin
  522. { only reassemble ? }
  523. if (hp^.do_assemble) then
  524. OnlyAsm(hp^.asmfilename^);
  525. { we should know there the PPU file else it's an error and
  526. we can't load the unit }
  527. {$ifdef NEWPPU}
  528. { if hp^.ppufile^.name^<>'' then}
  529. {$else}
  530. if hp^.ppufile^.name^<>'' then
  531. {$endif}
  532. load_ppu(old_current_module,hp,compile_system);
  533. { add the files for the linker }
  534. addlinkerfiles(hp);
  535. end;
  536. { register the unit _once_ }
  537. usedunits.concat(new(pused_unit,init(hp,0)));
  538. { the unit is written, so we can set the symtable type }
  539. { to unitsymtable, else we get some dupid errors }
  540. { this is not the right place because of the }
  541. { ready label }
  542. { psymtable(hp^.symtable)^.symtabletype:=unitsymtable; }
  543. { placed at this end of proc_unit }
  544. psymtable(hp^.symtable)^.unitid:=0;
  545. { reset the unitnumbers for the other units }
  546. pu:=pused_unit(old_current_module^.used_units.first);
  547. while assigned(pu) do
  548. begin
  549. psymtable(pu^.u^.symtable)^.unitid:=pu^.unitid;
  550. pu:=pused_unit(pu^.next);
  551. end;
  552. end
  553. else
  554. if assigned(hp) and (st=nil) then
  555. begin
  556. { we have to compile the unit again, but it is already inserted !!}
  557. { we may have problem with the lost symtable !! }
  558. current_module:=hp;
  559. { we must preserve the unit chain }
  560. nextmodule:=pmodule(hp^.next);
  561. { we have to cleanup a little }
  562. hp^.special_done;
  563. new(hs);
  564. hs^:=hp^.mainsource^;
  565. hp^.init(hs^,true);
  566. dispose(hs);
  567. { we must preserve the unit chain }
  568. hp^.next:=nextmodule;
  569. if assigned(hp^.ppufile) then
  570. load_ppu(old_current_module,hp,compile_system)
  571. else
  572. begin
  573. {$ifdef UseBrowser}
  574. { here we need to remove the names ! }
  575. hp^.sourcefiles.done;
  576. hp^.sourcefiles.init;
  577. {$endif not UseBrowser}
  578. {$ifdef TEST_TEMPCLOSE}
  579. if assigned(old_current_module^.current_inputfile) then
  580. old_current_module^.current_inputfile^.tempclose;
  581. {$endif TEST_TEMPCLOSE}
  582. Message1(parser_d_compiling_second_time,hp^.mainsource^);
  583. compile(hp^.mainsource^,compile_system);
  584. {$ifdef TEST_TEMPCLOSE}
  585. if not old_current_module^.compiled then
  586. old_current_module^.current_inputfile^.tempreopen;
  587. {$endif TEST_TEMPCLOSE}
  588. end;
  589. current_module^.compiled:=true;
  590. end;
  591. { set the old module }
  592. current_module:=old_current_module;
  593. { the current module uses the unit hp }
  594. current_module^.used_units.concat(new(pused_unit,init(hp,0)));
  595. pused_unit(current_module^.used_units.last)^.in_uses:=in_uses;
  596. if in_uses and not current_module^.in_implementation then
  597. pused_unit(current_module^.used_units.last)^.in_interface:=true;
  598. loadunit:=hp;
  599. end;
  600. procedure loadunits;
  601. var
  602. s : stringid;
  603. hp : pused_unit;
  604. hp2 : pmodule;
  605. hp3 : psymtable;
  606. oldprocsym:Pprocsym;
  607. begin
  608. oldprocsym:=aktprocsym;
  609. consume(_USES);
  610. {$ifdef DEBUG}
  611. test_symtablestack;
  612. {$endif DEBUG}
  613. repeat
  614. s:=pattern;
  615. consume(ID);
  616. hp2:=loadunit(s,false,true);
  617. if current_module^.compiled then
  618. exit;
  619. refsymtable^.insert(new(punitsym,init(s,hp2^.symtable)));
  620. if token=COMMA then
  621. begin
  622. pattern:='';
  623. consume(COMMA);
  624. end
  625. else
  626. break;
  627. until false;
  628. consume(SEMICOLON);
  629. { now insert the units in the symtablestack }
  630. hp:=pused_unit(current_module^.used_units.first);
  631. { set the symtable to systemunit so it gets reorderd correctly }
  632. symtablestack:=systemunit;
  633. while assigned(hp) do
  634. begin
  635. {$IfDef GDB}
  636. if (cs_debuginfo in aktswitches) and
  637. not hp^.is_stab_written then
  638. begin
  639. punitsymtable(hp^.u^.symtable)^.concattypestabto(debuglist);
  640. hp^.is_stab_written:=true;
  641. hp^.unitid:=psymtable(hp^.u^.symtable)^.unitid;
  642. end;
  643. {$EndIf GDB}
  644. if hp^.in_uses then
  645. begin
  646. hp3:=symtablestack;
  647. while assigned(hp3) do
  648. begin
  649. { insert units only once ! }
  650. if hp^.u^.symtable=hp3 then
  651. break;
  652. hp3:=hp3^.next;
  653. { unit isn't inserted }
  654. if hp3=nil then
  655. begin
  656. psymtable(hp^.u^.symtable)^.next:=symtablestack;
  657. symtablestack:=psymtable(hp^.u^.symtable);
  658. {$ifdef CHAINPROCSYMS}
  659. symtablestack^.chainprocsyms;
  660. {$endif CHAINPROCSYMS}
  661. {$ifdef DEBUG}
  662. test_symtablestack;
  663. {$endif DEBUG}
  664. end;
  665. end;
  666. end;
  667. hp:=pused_unit(hp^.next);
  668. end;
  669. aktprocsym:=oldprocsym;
  670. end;
  671. procedure parse_implementation_uses(symt:Psymtable);
  672. var
  673. old_module_in_implementation : boolean;
  674. begin
  675. if token=_USES then
  676. begin
  677. old_module_in_implementation:=module_in_implementation;
  678. module_in_implementation:=true;
  679. current_module^.in_implementation:=true;
  680. symt^.symtabletype:=unitsymtable;
  681. loadunits;
  682. symt^.symtabletype:=globalsymtable;
  683. {$ifdef DEBUG}
  684. test_symtablestack;
  685. {$endif DEBUG}
  686. module_in_implementation:=old_module_in_implementation;
  687. end;
  688. end;
  689. procedure proc_unit;
  690. var
  691. { unitname : stringid; }
  692. names:Tstringcontainer;
  693. p : psymtable;
  694. unitst : punitsymtable;
  695. pu : pused_unit;
  696. s1,s2 : ^string; {Saves stack space}
  697. begin
  698. consume(_UNIT);
  699. if token=ID then
  700. begin
  701. { create filenames and unit name }
  702. current_module^.SetFileName(current_module^.current_inputfile^.path^,current_module^.current_inputfile^.name^);
  703. stringdispose(current_module^.modulename);
  704. current_module^.modulename:=stringdup(upper(pattern));
  705. { check for system unit }
  706. new(s1);
  707. new(s2);
  708. s1^:=upper(target_info.system_unit);
  709. s2^:=upper(current_module^.current_inputfile^.name^);
  710. if (cs_compilesystem in aktswitches) then
  711. begin
  712. if (cs_check_unit_name in aktswitches) and
  713. ((length(current_module^.modulename^)>8) or
  714. (current_module^.modulename^<>s1^) or
  715. (current_module^.modulename^<>s2^)) then
  716. Message1(unit_e_illegal_unit_name,s1^);
  717. end
  718. else
  719. if (current_module^.modulename^=s1^) then
  720. Message(unit_w_switch_us_missed);
  721. dispose(s2);
  722. dispose(s1);
  723. { Add Object File }
  724. if (cs_smartlink in aktswitches) then
  725. current_module^.linkstaticlibs.insert(current_module^.libfilename^)
  726. else
  727. current_module^.linkofiles.insert(current_module^.objfilename^);
  728. end;
  729. consume(ID);
  730. consume(SEMICOLON);
  731. consume(_INTERFACE);
  732. { this should be placed after uses !!}
  733. {$ifndef UseNiceNames}
  734. procprefix:='_'+current_module^.modulename^+'$$';
  735. {$else UseNiceNames}
  736. procprefix:='_'+tostr(length(current_module^.unitname^))+lowercase(current_module^.unitname^)+'_';
  737. {$endif UseNiceNames}
  738. parse_only:=true;
  739. { generate now the global symboltable }
  740. p:=new(punitsymtable,init(globalsymtable,current_module^.modulename^));
  741. refsymtable:=p;
  742. unitst:=punitsymtable(p);
  743. { the unit name must be usable as a unit specifier }
  744. { inside the unit itself (PM) }
  745. { this also forbids to have another symbol }
  746. { with the same name as the unit }
  747. refsymtable^.insert(new(punitsym,init(current_module^.modulename^,unitst)));
  748. { set the symbol table for the current unit }
  749. { this must be set later for interdependency }
  750. { current_module^.symtable:=psymtable(p); }
  751. { a unit compiled at command line must be inside the loaded_unit list }
  752. if (compile_level=1) then
  753. begin
  754. loaded_units.insert(current_module);
  755. if cs_unit_to_lib in initswitches then
  756. begin
  757. current_module^.flags:=current_module^.flags or uf_in_library;
  758. if cs_shared_lib in initswitches then
  759. current_module^.flags:=current_module^.flags or uf_shared_library;
  760. end;
  761. end;
  762. { insert qualifier for the system unit (allows system.writeln) }
  763. if not(cs_compilesystem in aktswitches) then
  764. begin
  765. { insert the system unit }
  766. { it is allways the first }
  767. systemunit^.next:=nil;
  768. symtablestack:=systemunit;
  769. refsymtable^.insert(new(punitsym,init('SYSTEM',systemunit)));
  770. if token=_USES then
  771. begin
  772. unitst^.symtabletype:=unitsymtable;
  773. loadunits;
  774. { has it been compiled at a higher level ?}
  775. if current_module^.compiled then
  776. exit;
  777. unitst^.symtabletype:=globalsymtable;
  778. end;
  779. { ... but insert the symbol table later }
  780. p^.next:=symtablestack;
  781. symtablestack:=p;
  782. end
  783. else
  784. { while compiling a system unit, some types are directly inserted }
  785. begin
  786. p^.next:=symtablestack;
  787. symtablestack:=p;
  788. insert_intern_types(p);
  789. end;
  790. { displaced for inter-dependency considerations }
  791. current_module^.symtable:=psymtable(p);
  792. constsymtable:=symtablestack;
  793. { ... parse the declarations }
  794. read_interface_declarations;
  795. consume(_IMPLEMENTATION);
  796. parse_only:=false;
  797. refsymtable^.number_defs;
  798. {$ifdef GDB}
  799. { add all used definitions even for implementation}
  800. if (cs_debuginfo in aktswitches) then
  801. begin
  802. { all types }
  803. punitsymtable(refsymtable)^.concattypestabto(debuglist);
  804. { and all local symbols}
  805. refsymtable^.concatstabto(debuglist);
  806. end;
  807. {$endif GDB}
  808. { for interdependent units
  809. the crc is included in the ppufile
  810. but it is not known when writing the first ppufile
  811. so I tried to add a fake writing of the ppu
  812. just to get the CRC
  813. but the result is different for the real CRC
  814. it calculates after, I don't know why
  815. Answer:
  816. -------
  817. When reading the interface part, the compiler assumes
  818. that all registers are modified by a procedure
  819. usedinproc:=$ff !
  820. If the definition is read, the compiler determines
  821. the used registers and write the correct value
  822. to usedinproc
  823. only_calculate_crc:=true;
  824. writeunitas(current_module^.current_inputfile^.path^+current_module^.current_inputfile^.name^+
  825. +'.PPS',punitsymtable(symtablestack));
  826. only_calculate_crc:=false;
  827. }
  828. { generates static symbol table }
  829. p:=new(punitsymtable,init(staticsymtable,current_module^.modulename^));
  830. { must be done only after _USES !! (PM)
  831. refsymtable:=p;}
  832. {Generate a procsym.}
  833. aktprocsym:=new(Pprocsym,init(current_module^.modulename^+'_init'));
  834. aktprocsym^.definition:=new(Pprocdef,init);
  835. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or pounitinit;
  836. aktprocsym^.definition^.setmangledname(current_module^.modulename^+'_init');
  837. {The generated procsym has a local symtable. Discard it and turn
  838. it into the static one.}
  839. dispose(aktprocsym^.definition^.localst,done);
  840. aktprocsym^.definition^.localst:=p;
  841. { testing !!!!!!!!! }
  842. { we set the interface part as a unitsymtable }
  843. { for the case we need to compile another unit }
  844. { remove the globalsymtable from the symtable stack }
  845. { to reinsert it after loading the implementation units }
  846. symtablestack:=unitst^.next;
  847. parse_implementation_uses(unitst);
  848. { now we can change refsymtable }
  849. refsymtable:=p;
  850. { but reinsert the global symtable as lasts }
  851. unitst^.next:=symtablestack;
  852. symtablestack:=unitst;
  853. {$ifdef DEBUG}
  854. test_symtablestack;
  855. {$endif DEBUG}
  856. constsymtable:=symtablestack;
  857. {$ifdef Splitheap}
  858. if testsplit then
  859. begin
  860. Split_Heap;
  861. allow_special:=true;
  862. Switch_to_temp_heap;
  863. end;
  864. { it will report all crossings }
  865. allow_special:=false;
  866. {$endif Splitheap}
  867. { set some informations }
  868. procinfo.retdef:=voiddef;
  869. procinfo._class:=nil;
  870. procinfo.call_offset:=8;
  871. { for temporary values }
  872. procinfo.framepointer:=frame_pointer;
  873. { clear flags }
  874. procinfo.flags:=0;
  875. {Reset the codegenerator.}
  876. codegen_newprocedure;
  877. names.init;
  878. names.insert(current_module^.modulename^+'_init');
  879. names.insert('INIT$$'+current_module^.modulename^);
  880. compile_proc_body(names,true,false);
  881. names.done;
  882. codegen_doneprocedure;
  883. consume(POINT);
  884. { size of the static data }
  885. datasize:=symtablestack^.datasize;
  886. { unsed static symbols ? }
  887. symtablestack^.allsymbolsused;
  888. {$ifdef GDB}
  889. { add all used definitions even for implementation}
  890. if (cs_debuginfo in aktswitches) then
  891. begin
  892. { all types }
  893. punitsymtable(symtablestack)^.concattypestabto(debuglist);
  894. { and all local symbols}
  895. symtablestack^.concatstabto(debuglist);
  896. end;
  897. {$endif GDB}
  898. current_module^.in_implementation:=false;
  899. { deletes all symtables generated in the implementation part }
  900. while symtablestack^.symtabletype<>globalsymtable do
  901. dellexlevel;
  902. { tests, if all forwards are resolved }
  903. symtablestack^.check_forwards;
  904. symtablestack^.symtabletype:=unitsymtable;
  905. punitsymtable(symtablestack)^.is_stab_written:=false;
  906. {Write out the unit if the compile was succesfull.}
  907. if status.errorcount=0 then
  908. writeunitas(current_module^.ppufilename^,punitsymtable(symtablestack));
  909. pu:=pused_unit(usedunits.first);
  910. while assigned(pu) do
  911. begin
  912. punitsymtable(pu^.u^.symtable)^.is_stab_written:=false;
  913. pu:=pused_unit(pu^.next);
  914. end;
  915. inc(datasize,symtablestack^.datasize);
  916. { finish asmlist by adding segment starts }
  917. insertsegment;
  918. end;
  919. procedure proc_program(islibrary : boolean);
  920. var
  921. st : psymtable;
  922. names : Tstringcontainer;
  923. begin
  924. { Trying to compile the system unit... }
  925. { if no unit defined... then issue a }
  926. { fatal error (avoids pointer problems)}
  927. { when referencing the non-existant }
  928. { system unit. }
  929. { System Unit should be compiled using proc_unit !! (PFV) }
  930. { if (cs_compilesystem in aktswitches) then
  931. Begin
  932. if token<>_UNIT then
  933. Message1(scan_f_syn_expected,'UNIT');
  934. consume(_UNIT);
  935. end;}
  936. parse_only:=false;
  937. if islibrary then
  938. begin
  939. consume(_LIBRARY);
  940. stringdispose(current_module^.modulename);
  941. current_module^.modulename:=stringdup(pattern);
  942. consume(ID);
  943. consume(SEMICOLON);
  944. end
  945. else
  946. { is there an program head ? }
  947. if token=_PROGRAM then
  948. begin
  949. consume(_PROGRAM);
  950. stringdispose(current_module^.modulename);
  951. current_module^.modulename:=stringdup(pattern);
  952. consume(ID);
  953. if token=LKLAMMER then
  954. begin
  955. consume(LKLAMMER);
  956. idlist;
  957. consume(RKLAMMER);
  958. end;
  959. consume(SEMICOLON);
  960. end;
  961. { insert after the unit symbol tables the static symbol table }
  962. { of the program }
  963. st:=new(punitsymtable,init(staticsymtable,current_module^.modulename^));
  964. {Generate a procsym.}
  965. aktprocsym:=new(Pprocsym,init('main'));
  966. aktprocsym^.definition:=new(Pprocdef,init);
  967. aktprocsym^.definition^.options:=aktprocsym^.definition^.options or poproginit;
  968. aktprocsym^.definition^.setmangledname(target_os.Cprefix+'main');
  969. {The localst is a local symtable. Change it into the static
  970. symtable.}
  971. dispose(aktprocsym^.definition^.localst,done);
  972. aktprocsym^.definition^.localst:=st;
  973. refsymtable:=st;
  974. { necessary for browser }
  975. loaded_units.insert(current_module);
  976. {Insert the symbols of the system unit into the stack of symbol
  977. tables.}
  978. symtablestack:=systemunit;
  979. systemunit^.next:=nil;
  980. refsymtable^.insert(new(punitsym,init('SYSTEM',systemunit)));
  981. {Load the units used by the program we compile.}
  982. if token=_USES then
  983. loadunits;
  984. {Insert the name of the main program into the symbol table.}
  985. if current_module^.modulename^<>'' then
  986. st^.insert(new(pprogramsym,init(current_module^.modulename^)));
  987. { ...is also constsymtable, this is the symtable where }
  988. { the elements of enumeration types are inserted }
  989. constsymtable:=st;
  990. { set some informations about the main program }
  991. with procinfo do
  992. begin
  993. retdef:=voiddef;
  994. _class:=nil;
  995. call_offset:=8;
  996. framepointer:=frame_pointer;
  997. flags:=0;
  998. end;
  999. procprefix:='';
  1000. in_except_block:=false;
  1001. codegen_newprocedure;
  1002. {The program intialization needs an alias, so it can be called
  1003. from the bootstrap code.}
  1004. names.init;
  1005. names.insert('program_init');
  1006. names.insert('PASCALMAIN');
  1007. names.insert(target_os.cprefix+'main');
  1008. compile_proc_body(names,true,false);
  1009. names.done;
  1010. codegen_doneprocedure;
  1011. consume(POINT);
  1012. if (cs_smartlink in aktswitches) then
  1013. current_module^.linkstaticlibs.insert(current_module^.libfilename^)
  1014. else
  1015. current_module^.linkofiles.insert(current_module^.objfilename^);
  1016. insertheap;
  1017. inserttargetspecific;
  1018. datasize:=symtablestack^.datasize;
  1019. { finish asmlist by adding segment starts }
  1020. insertsegment;
  1021. end;
  1022. end.
  1023. {
  1024. $Log$
  1025. Revision 1.17 1998-05-28 14:40:25 peter
  1026. * fixes for newppu, remake3 works now with it
  1027. Revision 1.16 1998/05/27 19:45:06 peter
  1028. * symtable.pas splitted into includefiles
  1029. * symtable adapted for $ifdef NEWPPU
  1030. Revision 1.15 1998/05/23 01:21:22 peter
  1031. + aktasmmode, aktoptprocessor, aktoutputformat
  1032. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  1033. + $LIBNAME to set the library name where the unit will be put in
  1034. * splitted cgi386 a bit (codeseg to large for bp7)
  1035. * nasm, tasm works again. nasm moved to ag386nsm.pas
  1036. Revision 1.14 1998/05/20 09:42:35 pierre
  1037. + UseTokenInfo now default
  1038. * unit in interface uses and implementation uses gives error now
  1039. * only one error for unknown symbol (uses lastsymknown boolean)
  1040. the problem came from the label code !
  1041. + first inlined procedures and function work
  1042. (warning there might be allowed cases were the result is still wrong !!)
  1043. * UseBrower updated gives a global list of all position of all used symbols
  1044. with switch -gb
  1045. Revision 1.13 1998/05/12 10:47:00 peter
  1046. * moved printstatus to verb_def
  1047. + V_Normal which is between V_Error and V_Warning and doesn't have a
  1048. prefix like error: warning: and is included in V_Default
  1049. * fixed some messages
  1050. * first time parameter scan is only for -v and -T
  1051. - removed old style messages
  1052. Revision 1.12 1998/05/11 13:07:56 peter
  1053. + $ifdef NEWPPU for the new ppuformat
  1054. + $define GDB not longer required
  1055. * removed all warnings and stripped some log comments
  1056. * no findfirst/findnext anymore to remove smartlink *.o files
  1057. Revision 1.11 1998/05/06 18:36:53 peter
  1058. * tai_section extended with code,data,bss sections and enumerated type
  1059. * ident 'compiled by FPC' moved to pmodules
  1060. * small fix for smartlink
  1061. Revision 1.10 1998/05/04 17:54:28 peter
  1062. + smartlinking works (only case jumptable left todo)
  1063. * redesign of systems.pas to support assemblers and linkers
  1064. + Unitname is now also in the PPU-file, increased version to 14
  1065. Revision 1.9 1998/05/01 16:38:45 florian
  1066. * handling of private and protected fixed
  1067. + change_keywords_to_tp implemented to remove
  1068. keywords which aren't supported by tp
  1069. * break and continue are now symbols of the system unit
  1070. + widestring, longstring and ansistring type released
  1071. Revision 1.8 1998/04/30 15:59:41 pierre
  1072. * GDB works again better :
  1073. correct type info in one pass
  1074. + UseTokenInfo for better source position
  1075. * fixed one remaining bug in scanner for line counts
  1076. * several little fixes
  1077. Revision 1.7 1998/04/29 10:33:59 pierre
  1078. + added some code for ansistring (not complete nor working yet)
  1079. * corrected operator overloading
  1080. * corrected nasm output
  1081. + started inline procedures
  1082. + added starstarn : use ** for exponentiation (^ gave problems)
  1083. + started UseTokenInfo cond to get accurate positions
  1084. Revision 1.6 1998/04/27 23:10:28 peter
  1085. + new scanner
  1086. * $makelib -> if smartlink
  1087. * small filename fixes pmodule.setfilename
  1088. * moved import from files.pas -> import.pas
  1089. Revision 1.5 1998/04/14 23:27:03 florian
  1090. + exclude/include with constant second parameter added
  1091. Revision 1.4 1998/04/10 14:41:43 peter
  1092. * removed some Hints
  1093. * small speed optimization for AsmLn
  1094. Revision 1.3 1998/04/03 09:51:00 daniel
  1095. * Fixed heap allocation for OS/2.
  1096. }