parser.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. This unit does the parsing process
  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. {$ifdef tp}
  19. {$E+,N+,D+,F+}
  20. {$endif}
  21. unit parser;
  22. interface
  23. procedure compile(const filename:string;compile_system:boolean);
  24. procedure initparser;
  25. implementation
  26. uses
  27. dos,cobjects,globals,scanner,systems,symtable,tree,aasm,
  28. types,strings,pass_1,hcodegen,files,verbose,script,import,gendef
  29. {$ifdef i386}
  30. { ,i386
  31. ,cgi386
  32. ,cgai386
  33. ,tgeni386
  34. ,aopt386}
  35. {$endif i386}
  36. {$ifdef m68k}
  37. ,m68k
  38. ,cg68k
  39. ,tgen68k
  40. ,cga68k
  41. {$endif m68k}
  42. { parser units }
  43. ,pbase,pmodules,pdecl,psystem,
  44. { assembling & linking }
  45. assemble,
  46. link;
  47. procedure initparser;
  48. begin
  49. forwardsallowed:=false;
  50. { ^M means a string or a char, because we don't parse a }
  51. { type declaration }
  52. ignore_equal:=false;
  53. { we didn't parse a object or class declaration }
  54. { and no function header }
  55. testcurobject:=0;
  56. { create error defintion }
  57. generrordef:=new(perrordef,init);
  58. symtablestack:=nil;
  59. { a long time, this was forgotten }
  60. aktprocsym:=nil;
  61. current_module:=nil;
  62. loaded_units.init;
  63. usedunits.init;
  64. end;
  65. { moved out to save stack }
  66. var
  67. addparam : string;
  68. procedure compile(const filename:string;compile_system:boolean);
  69. var
  70. hp : pmodule;
  71. { some variables to save the compiler state }
  72. oldtoken : ttoken;
  73. oldtokenpos : tfileposinfo;
  74. oldpattern : stringid;
  75. oldpreprocstack : ppreprocstack;
  76. oldorgpattern,oldprocprefix : string;
  77. old_block_type : tblock_type;
  78. oldinputbuffer,
  79. oldinputpointer : pchar;
  80. olds_point,oldparse_only : boolean;
  81. oldc : char;
  82. oldcomment_level : word;
  83. oldnextlabelnr : longint;
  84. oldmacros,oldrefsymtable,oldsymtablestack : psymtable;
  85. oldimports,oldexports,oldresource,oldrttilist,
  86. oldbsssegment,olddatasegment,oldcodesegment,
  87. oldexprasmlist,olddebuglist,
  88. oldinternals,oldexternals,oldconsts : paasmoutput;
  89. oldswitches : tcswitches;
  90. oldpackrecords : word;
  91. oldoutputformat : tasm;
  92. oldoptprocessor : tprocessors;
  93. oldasmmode : tasmmode;
  94. procedure def_macro(const s : string);
  95. var
  96. mac : pmacrosym;
  97. begin
  98. mac:=pmacrosym(macros^.search(s));
  99. if mac=nil then
  100. begin
  101. mac:=new(pmacrosym,init(s));
  102. Message1(parser_m_macro_defined,mac^.name);
  103. macros^.insert(mac);
  104. end;
  105. mac^.defined:=true;
  106. end;
  107. procedure set_macro(const s : string;value : string);
  108. var
  109. mac : pmacrosym;
  110. begin
  111. mac:=pmacrosym(macros^.search(s));
  112. if mac=nil then
  113. begin
  114. mac:=new(pmacrosym,init(s));
  115. macros^.insert(mac);
  116. end
  117. else
  118. begin
  119. if assigned(mac^.buftext) then
  120. freemem(mac^.buftext,mac^.buflen);
  121. end;
  122. Message2(parser_m_macro_set_to,mac^.name,value);
  123. mac^.buflen:=length(value);
  124. getmem(mac^.buftext,mac^.buflen);
  125. move(value[1],mac^.buftext^,mac^.buflen);
  126. mac^.defined:=true;
  127. end;
  128. procedure define_macros;
  129. var
  130. hp : pstring_item;
  131. begin
  132. hp:=pstring_item(initdefines.first);
  133. while assigned(hp) do
  134. begin
  135. def_macro(hp^.str^);
  136. hp:=pstring_item(hp^.next);
  137. end;
  138. { set macros for version checking }
  139. set_macro('FPC_VERSION',version_nr);
  140. set_macro('FPC_RELEASE',release_nr);
  141. set_macro('FPC_PATCH',patch_nr);
  142. end;
  143. label
  144. done;
  145. begin {compile}
  146. inc(compile_level);
  147. { save old state }
  148. { save symtable state }
  149. oldsymtablestack:=symtablestack;
  150. symtablestack:=nil;
  151. oldrefsymtable:=refsymtable;
  152. refsymtable:=nil;
  153. oldprocprefix:=procprefix;
  154. { a long time, this was only in init_parser
  155. but it should be reset to zero for each module }
  156. aktprocsym:=nil;
  157. { first, we assume a program }
  158. if not(assigned(current_module)) then
  159. begin
  160. current_module:=new(pmodule,init(filename,false));
  161. main_module:=current_module;
  162. end;
  163. { save scanner state }
  164. oldmacros:=macros;
  165. oldpattern:=pattern;
  166. oldtoken:=token;
  167. oldtokenpos:=tokenpos;
  168. oldorgpattern:=orgpattern;
  169. old_block_type:=block_type;
  170. oldpreprocstack:=preprocstack;
  171. oldinputbuffer:=inputbuffer;
  172. oldinputpointer:=inputpointer;
  173. olds_point:=s_point;
  174. oldc:=c;
  175. oldcomment_level:=comment_level;
  176. oldnextlabelnr:=nextlabelnr;
  177. oldparse_only:=parse_only;
  178. { save assembler lists }
  179. olddatasegment:=datasegment;
  180. oldbsssegment:=bsssegment;
  181. oldcodesegment:=codesegment;
  182. olddebuglist:=debuglist;
  183. oldexternals:=externals;
  184. oldinternals:=internals;
  185. oldconsts:=consts;
  186. oldrttilist:=rttilist;
  187. oldexprasmlist:=exprasmlist;
  188. oldimports:=importssection;
  189. oldexports:=exportssection;
  190. oldresource:=resourcesection;
  191. { save the current state }
  192. oldswitches:=aktswitches;
  193. oldpackrecords:=aktpackrecords;
  194. oldoutputformat:=aktoutputformat;
  195. oldoptprocessor:=aktoptprocessor;
  196. oldasmmode:=aktasmmode;
  197. Message1(parser_i_compiling,filename);
  198. InitScanner(filename);
  199. { Load current state from the init values }
  200. aktswitches:=initswitches;
  201. aktpackrecords:=initpackrecords;
  202. aktoutputformat:=initoutputformat;
  203. aktoptprocessor:=initoptprocessor;
  204. aktasmmode:=initasmmode;
  205. { we need this to make the system unit }
  206. if compile_system then
  207. aktswitches:=aktswitches+[cs_compilesystem];
  208. { macros }
  209. macros:=new(psymtable,init(macrosymtable));
  210. macros^.name:=stringdup('Conditionals for '+filename);
  211. define_macros;
  212. { startup scanner }
  213. token:=yylex;
  214. { init code generator for a new module }
  215. codegen_newmodule;
  216. {$ifdef GDB}
  217. reset_gdb_info;
  218. {$endif GDB}
  219. { global switches are read, so further changes aren't allowed }
  220. current_module^.in_main:=true;
  221. { open assembler response }
  222. if (compile_level=1) then
  223. AsmRes.Init('ppas');
  224. { if the current file isn't a system unit }
  225. { the the system unit will be loaded }
  226. if not(cs_compilesystem in aktswitches) then
  227. begin
  228. { should be done in unit system (changing the field system_unit)
  229. FK
  230. }
  231. hp:=loadunit(upper(target_info.system_unit),true,true);
  232. systemunit:=hp^.symtable;
  233. make_ref:=false;
  234. readconstdefs;
  235. { we could try to overload caret by default }
  236. symtablestack:=systemunit;
  237. { if POWER is defined in the RTL then use it for starstar overloading }
  238. getsym('POWER',false);
  239. if assigned(srsym) and (srsym^.typ=procsym) and
  240. (overloaded_operators[STARSTAR]=nil) then
  241. overloaded_operators[STARSTAR]:=pprocsym(srsym);
  242. make_ref:=true;
  243. end
  244. else
  245. begin
  246. createconstdefs;
  247. systemunit:=nil;
  248. end;
  249. registerdef:=true;
  250. make_ref:=true;
  251. { current return type is void }
  252. procinfo.retdef:=voiddef;
  253. { reset lexical level }
  254. lexlevel:=0;
  255. { parse source }
  256. if (token=_UNIT) or (compile_level>1) then
  257. begin
  258. current_module^.is_unit:=true;
  259. { If the compile level > 1 we get a nice "unit expected" error
  260. message if we are trying to use a program as unit.}
  261. proc_unit;
  262. if current_module^.compiled then
  263. goto done;
  264. end
  265. else
  266. begin
  267. proc_program(token=_LIBRARY);
  268. end;
  269. if status.errorcount=0 then
  270. begin
  271. if current_module^.uses_imports then
  272. importlib^.generatelib;
  273. GenerateAsm(filename);
  274. if (cs_smartlink in aktswitches) then
  275. begin
  276. Linker.SetLibName(current_module^.libfilename^);
  277. Linker.MakeStaticLibrary(SmartLinkPath(FileName),SmartLinkFilesCnt);
  278. end;
  279. { add the files for the linker from current_module, this must be
  280. after the makestaticlibrary, because it will add the library
  281. name (PFV) }
  282. addlinkerfiles(current_module);
  283. { Check linking => we are at first level in compile }
  284. if (compile_level=1) then
  285. begin
  286. if gendeffile then
  287. deffile.writefile;
  288. if (not current_module^.is_unit) then
  289. begin
  290. if (cs_no_linking in initswitches) then
  291. externlink:=true;
  292. if Linker.ExeName='' then
  293. Linker.SetExeName(FileName);
  294. Linker.MakeExecutable;
  295. end;
  296. end;
  297. end
  298. else
  299. Message1(unit_f_errors_in_unit,tostr(status.errorcount));
  300. done:
  301. { clear memory }
  302. {$ifdef Splitheap}
  303. if testsplit then
  304. begin
  305. { temp heap should be empty after that !!!}
  306. codegen_donemodule;
  307. Releasetempheap;
  308. end;
  309. {$endif Splitheap}
  310. { restore old state, close trees }
  311. if dispose_asm_lists then
  312. codegen_donemodule;
  313. {$ifdef GDB}
  314. reset_gdb_info;
  315. {$endif GDB}
  316. { restore symtable state }
  317. {$ifdef UseBrowser}
  318. if (compile_level>1) then
  319. { we want to keep the current symtablestack }
  320. {$endif UseBrowser}
  321. begin
  322. refsymtable:=oldrefsymtable;
  323. symtablestack:=oldsymtablestack;
  324. end;
  325. procprefix:=oldprocprefix;
  326. { close the inputfiles }
  327. {$ifdef UseBrowser}
  328. { we need the names for the browser ! }
  329. current_module^.sourcefiles.close_all;
  330. {$else UseBrowser}
  331. current_module^.sourcefiles.done;
  332. {$endif not UseBrowser}
  333. { restore scanner state }
  334. pattern:=oldpattern;
  335. token:=oldtoken;
  336. tokenpos:=oldtokenpos;
  337. orgpattern:=oldorgpattern;
  338. block_type:=old_block_type;
  339. { call donescanner before restoring preprocstack, because }
  340. { donescanner tests for a empty preprocstack }
  341. { and can also check for unused macros }
  342. donescanner(current_module^.compiled);
  343. dispose(macros,done);
  344. macros:=oldmacros;
  345. { restore scanner }
  346. preprocstack:=oldpreprocstack;
  347. inputbuffer:=oldinputbuffer;
  348. inputpointer:=oldinputpointer;
  349. s_point:=olds_point;
  350. c:=oldc;
  351. comment_level:=oldcomment_level;
  352. nextlabelnr:=oldnextlabelnr;
  353. parse_only:=oldparse_only;
  354. { restore asmlists }
  355. exprasmlist:=oldexprasmlist;
  356. datasegment:=olddatasegment;
  357. bsssegment:=oldbsssegment;
  358. codesegment:=oldcodesegment;
  359. consts:=oldconsts;
  360. debuglist:=olddebuglist;
  361. externals:=oldexternals;
  362. internals:=oldinternals;
  363. importssection:=oldimports;
  364. exportssection:=oldexports;
  365. resourcesection:=oldresource;
  366. { restore current state }
  367. aktswitches:=oldswitches;
  368. aktpackrecords:=oldpackrecords;
  369. aktoutputformat:=oldoutputformat;
  370. aktoptprocessor:=oldoptprocessor;
  371. aktasmmode:=oldasmmode;
  372. if (compile_level=1) then
  373. begin
  374. if (not AsmRes.Empty) then
  375. begin
  376. Message1(exec_i_closing_script,AsmRes.Fn);
  377. AsmRes.WriteToDisk;
  378. end;
  379. end;
  380. dec(compile_level);
  381. end;
  382. end.
  383. {
  384. $Log$
  385. Revision 1.21 1998-06-04 23:51:49 peter
  386. * m68k compiles
  387. + .def file creation moved to gendef.pas so it could also be used
  388. for win32
  389. Revision 1.20 1998/06/03 22:48:55 peter
  390. + wordbool,longbool
  391. * rename bis,von -> high,low
  392. * moved some systemunit loading/creating to psystem.pas
  393. Revision 1.19 1998/05/27 19:45:04 peter
  394. * symtable.pas splitted into includefiles
  395. * symtable adapted for $ifdef NEWPPU
  396. Revision 1.18 1998/05/23 01:21:15 peter
  397. + aktasmmode, aktoptprocessor, aktoutputformat
  398. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  399. + $LIBNAME to set the library name where the unit will be put in
  400. * splitted cgi386 a bit (codeseg to large for bp7)
  401. * nasm, tasm works again. nasm moved to ag386nsm.pas
  402. Revision 1.17 1998/05/20 09:42:34 pierre
  403. + UseTokenInfo now default
  404. * unit in interface uses and implementation uses gives error now
  405. * only one error for unknown symbol (uses lastsymknown boolean)
  406. the problem came from the label code !
  407. + first inlined procedures and function work
  408. (warning there might be allowed cases were the result is still wrong !!)
  409. * UseBrower updated gives a global list of all position of all used symbols
  410. with switch -gb
  411. Revision 1.16 1998/05/12 10:47:00 peter
  412. * moved printstatus to verb_def
  413. + V_Normal which is between V_Error and V_Warning and doesn't have a
  414. prefix like error: warning: and is included in V_Default
  415. * fixed some messages
  416. * first time parameter scan is only for -v and -T
  417. - removed old style messages
  418. Revision 1.15 1998/05/11 13:07:54 peter
  419. + $ifdef NEWPPU for the new ppuformat
  420. + $define GDB not longer required
  421. * removed all warnings and stripped some log comments
  422. * no findfirst/findnext anymore to remove smartlink *.o files
  423. Revision 1.14 1998/05/06 18:36:53 peter
  424. * tai_section extended with code,data,bss sections and enumerated type
  425. * ident 'compiled by FPC' moved to pmodules
  426. * small fix for smartlink
  427. Revision 1.13 1998/05/06 08:38:42 pierre
  428. * better position info with UseTokenInfo
  429. UseTokenInfo greatly simplified
  430. + added check for changed tree after first time firstpass
  431. (if we could remove all the cases were it happen
  432. we could skip all firstpass if firstpasscount > 1)
  433. Only with ExtDebug
  434. Revision 1.12 1998/05/04 17:54:28 peter
  435. + smartlinking works (only case jumptable left todo)
  436. * redesign of systems.pas to support assemblers and linkers
  437. + Unitname is now also in the PPU-file, increased version to 14
  438. Revision 1.11 1998/05/01 16:38:45 florian
  439. * handling of private and protected fixed
  440. + change_keywords_to_tp implemented to remove
  441. keywords which aren't supported by tp
  442. * break and continue are now symbols of the system unit
  443. + widestring, longstring and ansistring type released
  444. Revision 1.10 1998/05/01 07:43:56 florian
  445. + basics for rtti implemented
  446. + switch $m (generate rtti for published sections)
  447. Revision 1.9 1998/04/30 15:59:40 pierre
  448. * GDB works again better :
  449. correct type info in one pass
  450. + UseTokenInfo for better source position
  451. * fixed one remaining bug in scanner for line counts
  452. * several little fixes
  453. Revision 1.8 1998/04/29 10:33:55 pierre
  454. + added some code for ansistring (not complete nor working yet)
  455. * corrected operator overloading
  456. * corrected nasm output
  457. + started inline procedures
  458. + added starstarn : use ** for exponentiation (^ gave problems)
  459. + started UseTokenInfo cond to get accurate positions
  460. Revision 1.7 1998/04/27 23:10:28 peter
  461. + new scanner
  462. * $makelib -> if smartlink
  463. * small filename fixes pmodule.setfilename
  464. * moved import from files.pas -> import.pas
  465. Revision 1.6 1998/04/21 10:16:48 peter
  466. * patches from strasbourg
  467. * objects is not used anymore in the fpc compiled version
  468. Revision 1.5 1998/04/10 14:41:43 peter
  469. * removed some Hints
  470. * small speed optimization for AsmLn
  471. Revision 1.4 1998/04/08 16:58:03 pierre
  472. * several bugfixes
  473. ADD ADC and AND are also sign extended
  474. nasm output OK (program still crashes at end
  475. and creates wrong assembler files !!)
  476. procsym types sym in tdef removed !!
  477. Revision 1.3 1998/04/07 22:45:04 florian
  478. * bug0092, bug0115 and bug0121 fixed
  479. + packed object/class/array
  480. }