compiler.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This unit is the interface of the compiler which can be used by
  5. external programs to link in the compiler
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. {
  19. possible compiler switches:
  20. -----------------------------------------------------------------
  21. TP to compile the compiler with Turbo or Borland Pascal
  22. I386 generate a compiler for the Intel i386+
  23. M68K generate a compiler for the M68000
  24. GDB support of the GNU Debugger
  25. EXTDEBUG some extra debug code is executed
  26. SUPPORT_MMX only i386: releases the compiler switch
  27. MMX which allows the compiler to generate
  28. MMX instructions
  29. EXTERN_MSG Don't compile the msgfiles in the compiler, always
  30. use external messagefiles
  31. NOAG386INT no Intel Assembler output
  32. NOAG386NSM no NASM output
  33. -----------------------------------------------------------------
  34. }
  35. {$ifdef FPC}
  36. { One of Alpha, I386 or M68K must be defined }
  37. {$UNDEF CPUOK}
  38. {$ifdef I386}
  39. {$define CPUOK}
  40. {$endif}
  41. {$ifdef M68K}
  42. {$ifndef CPUOK}
  43. {$DEFINE CPUOK}
  44. {$else}
  45. {$fatal cannot define two CPU switches}
  46. {$endif}
  47. {$endif}
  48. {$ifdef alpha}
  49. {$ifndef CPUOK}
  50. {$DEFINE CPUOK}
  51. {$else}
  52. {$fatal cannot define two CPU switches}
  53. {$endif}
  54. {$endif}
  55. {$ifdef powerpc}
  56. {$ifndef CPUOK}
  57. {$DEFINE CPUOK}
  58. {$else}
  59. {$fatal cannot define two CPU switches}
  60. {$endif}
  61. {$endif}
  62. {$ifndef CPUOK}
  63. {$fatal One of the switches I386, Alpha, PowerPC or M68K must be defined}
  64. {$endif}
  65. {$ifdef support_mmx}
  66. {$ifndef i386}
  67. {$fatal I386 switch must be on for MMX support}
  68. {$endif i386}
  69. {$endif support_mmx}
  70. {$endif}
  71. unit compiler;
  72. interface
  73. { Use exception catching so the compiler goes futher after a Stop }
  74. {$ifdef i386}
  75. {$define USEEXCEPT}
  76. {$endif}
  77. {$ifdef TP}
  78. {$ifdef DPMI}
  79. {$undef USEEXCEPT}
  80. {$endif}
  81. {$endif}
  82. uses
  83. {$ifdef fpc}
  84. {$ifdef GO32V2}
  85. emu387,
  86. { dpmiexcp, }
  87. {$endif GO32V2}
  88. {$ifdef LINUX}
  89. catch,
  90. {$endif LINUX}
  91. {$endif}
  92. {$ifdef USEEXCEPT}
  93. tpexcept,
  94. {$endif USEEXCEPT}
  95. {$ifdef BrowserLog}
  96. browlog,
  97. {$endif BrowserLog}
  98. {$ifdef BrowserCol}
  99. browcol,
  100. {$endif BrowserCol}
  101. {$ifdef Delphi}
  102. dmisc,
  103. {$else Delphi}
  104. dos,
  105. {$endif Delphi}
  106. verbose,comphook,systems,
  107. cobjects,globals,options,parser,symtable,link,import,export,tokens;
  108. function Compile(const cmd:string):longint;
  109. Const
  110. { do we need to link }
  111. IsExe : boolean = false;
  112. implementation
  113. uses
  114. cpubase;
  115. var
  116. CompilerInitedAfterArgs,
  117. CompilerInited : boolean;
  118. olddo_stop : tstopprocedure;
  119. {$ifdef USEEXCEPT}
  120. procedure RecoverStop;{$ifndef FPC}far;{$endif}
  121. begin
  122. if recoverpospointer<>nil then
  123. LongJmp(recoverpospointer^,1)
  124. else
  125. Do_Halt(1);
  126. end;
  127. {$endif USEEXCEPT}
  128. {****************************************************************************
  129. Compiler
  130. ****************************************************************************}
  131. procedure DoneCompiler;
  132. begin
  133. if not CompilerInited then
  134. exit;
  135. { Free compiler if args are read }
  136. {$ifdef BrowserLog}
  137. DoneBrowserLog;
  138. {$endif BrowserLog}
  139. {$ifdef BrowserCol}
  140. DoneBrowserCol;
  141. {$endif BrowserCol}
  142. if CompilerInitedAfterArgs then
  143. begin
  144. CompilerInitedAfterArgs:=false;
  145. doneparser;
  146. DoneImport;
  147. DoneExport;
  148. DoneLinker;
  149. DoneCpu;
  150. end;
  151. { Free memory for the others }
  152. CompilerInited:=false;
  153. DoneSymtable;
  154. DoneGlobals;
  155. donetokens;
  156. {$ifdef USEEXCEPT}
  157. recoverpospointer:=nil;
  158. longjump_used:=false;
  159. {$endif USEEXCEPT}
  160. end;
  161. procedure InitCompiler(const cmd:string);
  162. begin
  163. if CompilerInited then
  164. DoneCompiler;
  165. { inits which need to be done before the arguments are parsed }
  166. InitSystems;
  167. InitVerbose;
  168. {$ifdef BrowserLog}
  169. InitBrowserLog;
  170. {$endif BrowserLog}
  171. {$ifdef BrowserCol}
  172. InitBrowserCol;
  173. {$endif BrowserCol}
  174. InitGlobals;
  175. inittokens;
  176. InitSymtable;
  177. CompilerInited:=true;
  178. { read the arguments }
  179. read_arguments(cmd);
  180. { inits which depend on arguments }
  181. initparser;
  182. InitImport;
  183. InitExport;
  184. InitLinker;
  185. InitCpu;
  186. CompilerInitedAfterArgs:=true;
  187. end;
  188. procedure minimal_stop;{$ifndef fpc}far;{$endif}
  189. begin
  190. DoneCompiler;
  191. olddo_stop;
  192. end;
  193. function Compile(const cmd:string):longint;
  194. procedure writepathlist(w:tmsgconst;l:TSearchPathList);
  195. var
  196. hp : pstringqueueitem;
  197. begin
  198. hp:=l.first;
  199. while assigned(hp) do
  200. begin
  201. Message1(w,hp^.data^);
  202. hp:=hp^.next;
  203. end;
  204. end;
  205. function getrealtime : real;
  206. var
  207. h,m,s,s100 : word;
  208. begin
  209. gettime(h,m,s,s100);
  210. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  211. end;
  212. var
  213. starttime : real;
  214. {$ifdef USEEXCEPT}
  215. recoverpos : jmp_buf;
  216. {$endif}
  217. begin
  218. olddo_stop:=do_stop;
  219. {$ifdef TP}
  220. do_stop:=minimal_stop;
  221. {$else TP}
  222. do_stop:=@minimal_stop;
  223. {$endif TP}
  224. { Initialize the compiler }
  225. InitCompiler(cmd);
  226. { show some info }
  227. Message1(general_t_compilername,FixFileName(paramstr(0)));
  228. Message1(general_d_sourceos,source_os.name);
  229. Message1(general_i_targetos,target_os.name);
  230. Message1(general_t_exepath,exepath);
  231. WritePathList(general_t_unitpath,unitsearchpath);
  232. WritePathList(general_t_includepath,includesearchpath);
  233. WritePathList(general_t_librarypath,librarysearchpath);
  234. WritePathList(general_t_objectpath,objectsearchpath);
  235. {$ifdef TP}
  236. {$ifndef Delphi}
  237. Comment(V_Info,'Memory: '+tostr(MemAvail)+' Bytes Free');
  238. {$endif Delphi}
  239. {$endif}
  240. {$ifdef USEEXCEPT}
  241. if setjmp(recoverpos)=0 then
  242. begin
  243. recoverpospointer:=@recoverpos;
  244. {$ifdef TP}
  245. do_stop:=recoverstop;
  246. {$else TP}
  247. do_stop:=@recoverstop;
  248. {$endif TP}
  249. {$endif USEEXCEPT}
  250. starttime:=getrealtime;
  251. if parapreprocess then
  252. parser.preprocess(inputdir+inputfile+inputextension)
  253. else
  254. parser.compile(inputdir+inputfile+inputextension,false);
  255. if status.errorcount=0 then
  256. begin
  257. starttime:=getrealtime-starttime;
  258. if starttime<0 then
  259. starttime:=starttime+3600.0*24.0;
  260. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  261. '.'+tostr(trunc(frac(starttime)*10)));
  262. end;
  263. {$ifdef USEEXCEPT}
  264. end;
  265. {$endif USEEXCEPT}
  266. { Stop is always called, so we come here when a program is compiled or not }
  267. do_stop:=olddo_stop;
  268. { Stop the compiler, frees also memory }
  269. { no message possible after this !! }
  270. DoneCompiler;
  271. { Set the return value if an error has occurred }
  272. if status.errorcount=0 then
  273. Compile:=0
  274. else
  275. Compile:=1;
  276. DoneVerbose;
  277. {$ifdef EXTDEBUG}
  278. {$ifdef FPC}
  279. Writeln('Memory Lost = '+tostr(system.HeapSize-MemAvail-EntryMemUsed));
  280. {$endif FPC}
  281. {$ifndef newcg}
  282. Writeln('Repetitive firstpass = '+tostr(firstpass_several)+'/'+tostr(total_of_firstpass));
  283. {$endif newcg}
  284. {$endif EXTDEBUG}
  285. {$ifdef fixLeaksOnError}
  286. {$ifdef tp}
  287. do_stop;
  288. {$else tp}
  289. do_stop();
  290. {$endif tp}
  291. {$endif fixLeaksOnError}
  292. end;
  293. end.
  294. {
  295. $Log$
  296. Revision 1.43 2000-01-11 16:53:24 jonas
  297. + call do_stop at the end of compile()
  298. Revision 1.42 2000/01/07 01:14:23 peter
  299. * updated copyright to 2000
  300. Revision 1.41 1999/12/02 17:34:34 peter
  301. * preprocessor support. But it fails on the caret in type blocks
  302. Revision 1.40 1999/11/18 13:43:48 pierre
  303. + IsExe global var needed for IDE
  304. Revision 1.39 1999/11/12 11:03:50 peter
  305. * searchpaths changed to stringqueue object
  306. Revision 1.38 1999/11/09 23:47:53 pierre
  307. + minimal_stop to avoid memory loss with -iTO switch
  308. Revision 1.37 1999/11/06 14:34:20 peter
  309. * truncated log to 20 revs
  310. Revision 1.36 1999/10/12 21:20:41 florian
  311. * new codegenerator compiles again
  312. Revision 1.35 1999/09/28 19:48:45 florian
  313. * bug 617 fixed
  314. Revision 1.34 1999/09/16 23:05:52 florian
  315. * m68k compiler is again compilable (only gas writer, no assembler reader)
  316. Revision 1.33 1999/09/07 15:10:04 pierre
  317. * use do_halt instead of halt
  318. Revision 1.32 1999/09/02 18:47:44 daniel
  319. * Could not compile with TP, some arrays moved to heap
  320. * NOAG386BIN default for TP
  321. * AG386* files were not compatible with TP, fixed.
  322. Revision 1.31 1999/08/20 10:17:01 michael
  323. + Patch from pierre
  324. Revision 1.30 1999/08/11 17:26:31 peter
  325. * tlinker object is now inherited for win32 and dos
  326. * postprocessexecutable is now a method of tlinker
  327. Revision 1.29 1999/08/09 22:13:43 peter
  328. * fixed writing of lost memory which should be after donecompiler
  329. Revision 1.28 1999/08/04 13:02:40 jonas
  330. * all tokens now start with an underscore
  331. * PowerPC compiles!!
  332. Revision 1.27 1999/08/02 21:28:56 florian
  333. * the main branch psub.pas is now used for
  334. newcg compiler
  335. Revision 1.26 1999/08/02 20:46:57 michael
  336. * Alpha aware switch detection
  337. Revision 1.25 1999/07/18 14:47:22 florian
  338. * bug 487 fixed, (inc(<property>) isn't allowed)
  339. * more fixes to compile with Delphi
  340. Revision 1.24 1999/07/18 10:19:48 florian
  341. * made it compilable with Dlephi 4 again
  342. + fixed problem with large stack allocations on win32
  343. Revision 1.23 1999/06/22 16:24:41 pierre
  344. * local browser stuff corrected
  345. Revision 1.22 1999/05/17 14:24:32 pierre
  346. * DoneCompiler called later to prevent accessing invalid data
  347. Revision 1.21 1999/05/04 21:44:39 florian
  348. * changes to compile it with Delphi 4.0
  349. Revision 1.20 1999/04/21 09:43:33 peter
  350. * storenumber works
  351. * fixed some typos in double_checksum
  352. + incompatible types type1 and type2 message (with storenumber)
  353. Revision 1.19 1999/03/09 11:52:06 pierre
  354. * compilation after a failure longjumped directly to end
  355. Revision 1.18 1999/02/26 00:48:16 peter
  356. * assembler writers fixed for ag386bin
  357. Revision 1.17 1999/01/12 14:25:25 peter
  358. + BrowserLog for browser.log generation
  359. + BrowserCol for browser info in TCollections
  360. * released all other UseBrowser
  361. }