Compiler.Mod 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. MODULE Compiler; (** AUTHOR "fof & fn"; PURPOSE "Oberon Compiler Command Interface"; **)
  2. (* (c) fof ETH Zürich, 2008 *)
  3. IMPORT
  4. Basic := FoxBasic, Scanner := FoxScanner, Parser := FoxParser,
  5. SemanticChecker := FoxSemanticChecker, SyntaxTree := FoxSyntaxTree, Formats := FoxFormats,
  6. Streams, Commands,Diagnostics, Options, Kernel, Printout := FoxPrintout, Backend := FoxBackend,Strings, Global := FoxGlobal,
  7. Frontend := FoxFrontend, Files, Machine;
  8. CONST
  9. (* flags *)
  10. Print* = 0;
  11. Silent* = 1;
  12. Check* = 2;
  13. TraceError* = 3;
  14. Info* = 4;
  15. FindPC* = 5;
  16. Warnings*=7;
  17. ForceModuleBodies*=8;
  18. UseDarwinCCalls*=9; (* use Darwin stack alignment for ext. C procedures *) (*fld*)
  19. SingleModule*=10;
  20. Oberon07*=11;
  21. ChangeCase*=12;
  22. Cooperative*=13;
  23. CellsAreObjects*=14;
  24. UseLineNumbers*=15;
  25. DefaultBackend = "AMD";
  26. DefaultFrontend = "Oberon";
  27. TYPE
  28. SectionName = ARRAY 256 OF CHAR; (*! move *)
  29. CompilerOptions*= RECORD
  30. flags*: SET;
  31. frontend*: Frontend.Frontend;
  32. backend*: Backend.Backend;
  33. symbolFile*: Formats.SymbolFileFormat;
  34. objectFile*: Formats.ObjectFileFormat;
  35. findPC*: SectionName;
  36. documentation*: Backend.Backend;
  37. srcPath, destPath: Files.FileName;
  38. replacements: SemanticChecker.Replacement;
  39. platformCallingConvention: SyntaxTree.CallingConvention;
  40. definitions: Options.Parameter;
  41. END;
  42. PROCEDURE ParseReplacements(CONST filename: ARRAY OF CHAR; VAR replacement: SemanticChecker.Replacement; diagnostics: Diagnostics.Diagnostics): BOOLEAN;
  43. VAR reader: Streams.Reader; r: SemanticChecker.Replacement;
  44. identifier: SyntaxTree.QualifiedIdentifier;
  45. scanner: Scanner.Scanner; parser: Parser.Parser; expression: SyntaxTree.Expression;
  46. BEGIN
  47. replacement := NIL;
  48. reader := Basic.GetFileReader(filename);
  49. IF reader = NIL THEN
  50. diagnostics.Error (filename, Streams.Invalid, "failed to open");
  51. ELSE
  52. scanner := Scanner.NewScanner(filename, reader, 0, diagnostics);
  53. NEW(parser, scanner, diagnostics, "");
  54. REPEAT (* WHILE parser.Peek(Scanner.Identifier) DO*)
  55. identifier := parser.QualifiedIdentifier();
  56. IF parser.Mandatory(Scanner.Equal) THEN
  57. expression := parser.Expression();
  58. NEW(r); identifier.GetName(r.name); r.expression := expression; r.used := FALSE;
  59. r.next := replacement; replacement := r;
  60. END;
  61. WHILE parser.Optional(Scanner.Semicolon) DO END;
  62. UNTIL ~parser.Peek(Scanner.Identifier); (*END;*)
  63. END;
  64. (*done := FALSE;
  65. WHILE reader.GetString(name) & ~done DO
  66. IF reader.GetChar(equal) & (equal = "=") & reader.GetString(value) THEN
  67. NEW(r); r.name := name; r.string := Strings.NewString(value); r.used := FALSE;
  68. r.next := replacement; replacement := r;
  69. ELSE done := TRUE;
  70. END;
  71. END;
  72. *)
  73. RETURN (replacement # NIL)
  74. END ParseReplacements;
  75. PROCEDURE Modules*(CONST source: ARRAY OF CHAR; (* source file name, for debugging and better error reports *)
  76. reader: Streams.Reader; (* reader to read from *)
  77. position: LONGINT; (* starting position in reader *)
  78. diagnostics: Diagnostics.Diagnostics; (* error output and status report *)
  79. log: Streams.Writer;
  80. CONST options: CompilerOptions;
  81. VAR importCache: SyntaxTree.ModuleScope): BOOLEAN;
  82. VAR
  83. module: SyntaxTree.Module;
  84. checker: SemanticChecker.Checker;
  85. warnings: SemanticChecker.Warnings;
  86. printer: Printout.Printer;
  87. system: Global.System;
  88. generatedModule: Formats.GeneratedModule;
  89. split: Strings.StringArray;
  90. sectionOffset: LONGINT;
  91. flags: SET;
  92. backendName: ARRAY 32 OF CHAR;
  93. PROCEDURE FinalMessage(error: BOOLEAN; CONST msg: ARRAY OF CHAR);
  94. VAR message,name: ARRAY 256 OF CHAR;
  95. BEGIN
  96. message := "";
  97. IF module # NIL THEN
  98. Global.GetModuleName(module, message);
  99. END;
  100. Strings.Append (message, msg);
  101. IF error THEN
  102. IF diagnostics # NIL THEN
  103. diagnostics.Error (source, Streams.Invalid, message);
  104. END;
  105. ELSE
  106. IF (log # NIL) & ~(Silent IN options.flags) & ~(FindPC IN options.flags) THEN
  107. log.String("compiling ");
  108. IF source # "" THEN log.String(source); log.String(" => "); END;
  109. log.String(message); log.Ln;
  110. log.Update;
  111. END;
  112. END;
  113. END FinalMessage;
  114. PROCEDURE PrintModule;
  115. VAR print: Streams.Writer;
  116. BEGIN
  117. print := Basic.GetWriter(Basic.GetDebugWriter("Compiler Debug Output"));
  118. IF Info IN options.flags THEN
  119. printer := Printout.NewPrinter(print,Printout.All,Info IN options.flags);
  120. ELSE
  121. printer := Printout.NewPrinter(print,Printout.SourceCode,Info IN options.flags);
  122. END;
  123. print.Ln; printer.Module(module); print.Ln;
  124. print.Update;
  125. END PrintModule;
  126. BEGIN
  127. flags := options.flags;
  128. IF options.findPC # "" THEN EXCL(flags, Warnings) END;
  129. IF TraceError IN options.flags THEN
  130. diagnostics := Basic.GetTracingDiagnostics(diagnostics)
  131. END;
  132. IF options.backend = NIL THEN
  133. system := Global.DefaultSystem()
  134. ELSE
  135. IF Oberon07 IN options.flags THEN options.backend.SetOberon07 END; (* inform the backend about that the Oberon07 mode, it will return the corresponding Sytem object *)
  136. system := options.backend.GetSystem();
  137. END;
  138. system.SetCellsAreObjects(CellsAreObjects IN flags);
  139. system.SetPlatformCallingConvention(options.platformCallingConvention);
  140. IF (options.objectFile # NIL) & (options.objectFile.ForceModuleBodies()) THEN INCL(flags, ForceModuleBodies) END;
  141. options.frontend.Initialize(diagnostics, flags, reader, source, options.definitions, position);
  142. REPEAT
  143. (** first phase: scan and parse **)
  144. module := options.frontend.Parse();
  145. IF options.frontend.Error() THEN
  146. FinalMessage(TRUE," could not be compiled (parser errors).");
  147. RETURN FALSE;
  148. END;
  149. ASSERT(module # NIL);
  150. IF Check IN flags THEN
  151. (** second phase: check and resolve symbols **)
  152. IF (options.symbolFile # NIL) THEN
  153. options.symbolFile.Initialize(diagnostics,system,options.destPath);
  154. END;
  155. IF options.backend # NIL THEN
  156. COPY(options.backend.name, backendName);
  157. ELSE
  158. backendName := "";
  159. END;
  160. checker := SemanticChecker.NewChecker(diagnostics,Info IN flags,UseDarwinCCalls IN flags,Cooperative IN flags,system,options.symbolFile,importCache,backendName);
  161. checker.replacements := options.replacements;
  162. checker.Module(module);
  163. IF checker.error THEN
  164. FinalMessage(TRUE," could not be compiled (checker errors).");
  165. RETURN FALSE
  166. ELSIF Warnings IN flags THEN
  167. warnings := SemanticChecker.NewWarnings(diagnostics);
  168. warnings.Module(module);
  169. END;
  170. IF Print IN flags THEN
  171. IF ChangeCase IN flags THEN module.SetCase(1-module.case) END;
  172. PrintModule;
  173. IF ChangeCase IN flags THEN module.SetCase(1-module.case) END;
  174. END;
  175. (** third phase: generate code, can consist of sub-phases (such as intermediate backend / hardware backend) **)
  176. IF options.backend # NIL THEN
  177. options.backend.Initialize(diagnostics, log, flags, checker, system);
  178. IF options.findPC # "" THEN
  179. split := Strings.Split(options.findPC,":");
  180. IF LEN(split)>1 THEN
  181. Strings.StrToInt(split[1]^,sectionOffset);
  182. options.backend.FindPC(module, split[0]^,sectionOffset);
  183. IF options.backend.error THEN
  184. FinalMessage(TRUE," could not be compiled (backend errors).");
  185. RETURN FALSE
  186. ELSE
  187. RETURN TRUE
  188. END;
  189. END;
  190. END;
  191. generatedModule := options.backend.ProcessSyntaxTreeModule(module);
  192. IF options.backend.error THEN
  193. FinalMessage(TRUE, " could not be compiled (backend errors).");
  194. RETURN FALSE
  195. END;
  196. END;
  197. (** generate symbol file **)
  198. IF (options.symbolFile # NIL) & ~options.symbolFile.Export(module, importCache) THEN
  199. FinalMessage(TRUE, " could not be compiled (symbol File errors).");
  200. RETURN FALSE
  201. END;
  202. (** generate object file **)
  203. IF options.objectFile # NIL THEN
  204. options.objectFile.Initialize(diagnostics);
  205. options.objectFile.SetPath(options.destPath);
  206. IF options.findPC # "" THEN
  207. Strings.StrToInt(options.findPC, sectionOffset);
  208. generatedModule.SetFindPC(sectionOffset);
  209. END;
  210. IF generatedModule = NIL THEN
  211. FinalMessage(TRUE, " could not write object file (nothing generated).");
  212. RETURN FALSE
  213. ELSIF ~options.objectFile.Export(generatedModule,options.symbolFile) THEN
  214. FinalMessage(TRUE, " could not be compiled (object file errors).");
  215. RETURN FALSE
  216. END;
  217. END;
  218. IF options.documentation # NIL THEN
  219. options.documentation.Initialize(diagnostics,log, flags,checker,system);
  220. generatedModule := options.documentation.ProcessSyntaxTreeModule(module);
  221. END;
  222. FinalMessage(FALSE, " done.");
  223. ELSIF Print IN flags THEN
  224. IF ChangeCase IN flags THEN module.SetCase(1-module.case) END;
  225. PrintModule;
  226. FinalMessage(FALSE, " done.")
  227. ELSE
  228. FinalMessage(FALSE, " done.");
  229. END;
  230. UNTIL (SingleModule IN flags) OR options.frontend.Done();
  231. RETURN TRUE;
  232. END Modules;
  233. PROCEDURE GetOptions*(input: Streams.Reader; error:Streams.Writer; diagnostics: Diagnostics.Diagnostics;
  234. VAR compilerOptions: CompilerOptions): BOOLEAN;
  235. VAR options: Options.Options; name: ARRAY 256 OF CHAR; result: BOOLEAN; position: LONGINT;
  236. defaults: Streams.Reader;
  237. parsed: BOOLEAN;
  238. PROCEDURE Error(CONST error: ARRAY OF CHAR);
  239. BEGIN
  240. IF diagnostics # NIL THEN
  241. diagnostics.Error("",Streams.Invalid,error);
  242. END;
  243. END Error;
  244. BEGIN
  245. result := TRUE;
  246. NEW(options);
  247. options.Add("p","platform",Options.String);
  248. options.Add(0X,"showOptions",Options.Flag);
  249. options.Add("l","lineNumbers", Options.Flag);
  250. options.Add(0X,"print",Options.Flag);
  251. options.Add(0X,"Print",Options.Flag);
  252. options.Add(0X,"silent",Options.Flag);
  253. options.Add("c","check",Options.Flag);
  254. options.Add("e","traceError",Options.Flag);
  255. options.Add("I","interface",Options.Flag);
  256. options.Add("i","info",Options.Flag);
  257. options.Add(0X,"oberon07",Options.Flag);
  258. options.Add("b","backend",Options.String);
  259. options.Add("F","frontEnd",Options.String);
  260. options.Add("f","findPC",Options.String);
  261. options.Add(0X,"singleModule",Options.Flag);
  262. options.Add(0X, "symbolFile", Options.String);
  263. options.Add(0X, "objectFile", Options.String);
  264. options.Add("w","warnings", Options.Flag);
  265. options.Add(0X,"darwinHost", Options.Flag);
  266. options.Add(0X,"hardware", Options.String);
  267. options.Add(0X,"documentation", Options.String);
  268. options.Add("S","srcPath", Options.String);
  269. options.Add("D","destPath", Options.String);
  270. options.Add(0X,"replacements", Options.String);
  271. options.Add(0X,"cooperative", Options.Flag);
  272. options.Add(0X,"platformCC",Options.String);
  273. options.Add("d","define",Options.String);
  274. position := input.Pos();
  275. parsed := options.ParseStaged(input, error);
  276. IF options.GetString("platform", name) OR GetDefaultPlatform(name) THEN
  277. defaults := platforms.Get(name);
  278. IF defaults = NIL THEN
  279. error.String("Unknown platform"); error.Ln
  280. ELSE
  281. parsed := options.ParseStaged(defaults, error) & parsed;
  282. input.SetPos(position);
  283. parsed := options.ParseStaged(input, error) & parsed; (* reparse overwrites *)
  284. END;
  285. ELSE
  286. defaults := NIL;
  287. END;
  288. IF options.GetString("b", name) THEN
  289. IF name = "" THEN compilerOptions.backend := NIL
  290. ELSE
  291. compilerOptions.backend := Backend.GetBackendByName(name);
  292. IF (compilerOptions.backend = NIL) THEN
  293. Error("backend could not be installed"); result := FALSE;
  294. END;
  295. END;
  296. ELSE compilerOptions.backend := Backend.GetBackendByName(DefaultBackend);
  297. IF compilerOptions.backend = NIL THEN Error("default backend could not be installed"); result := FALSE END;
  298. END;
  299. IF options.GetString("F", name) THEN
  300. IF name = "" THEN compilerOptions.frontend := NIL
  301. ELSE
  302. compilerOptions.frontend := Frontend.GetFrontendByName(name);
  303. IF (compilerOptions.frontend = NIL) THEN
  304. Error("backend could not be installed"); result := FALSE;
  305. END;
  306. END;
  307. ELSE compilerOptions.frontend := Frontend.GetFrontendByName(DefaultFrontend);
  308. IF compilerOptions.frontend = NIL THEN Error("default frontend could not be installed"); result := FALSE END;
  309. END;
  310. IF options.GetString("objectFile",name) THEN
  311. IF name = "" THEN compilerOptions.objectFile := NIL
  312. ELSE
  313. compilerOptions.objectFile := Formats.GetObjectFileFormat(name);
  314. IF compilerOptions.objectFile = NIL THEN Error("object file format could not be installed"); result := FALSE END;
  315. END;
  316. ELSIF compilerOptions.backend # NIL THEN
  317. compilerOptions.objectFile := compilerOptions.backend.DefaultObjectFileFormat();
  318. END;
  319. IF options.GetString("symbolFile",name) THEN
  320. IF name = "" THEN compilerOptions.symbolFile := NIL
  321. ELSE
  322. compilerOptions.symbolFile := Formats.GetSymbolFileFormat(name);
  323. IF compilerOptions.symbolFile = NIL THEN Error("symbol file format could not be installed"); result := FALSE END;
  324. END;
  325. ELSIF compilerOptions.backend # NIL THEN
  326. compilerOptions.symbolFile := compilerOptions.backend.DefaultSymbolFileFormat();
  327. IF (compilerOptions.symbolFile = NIL) & (compilerOptions.objectFile # NIL) THEN
  328. compilerOptions.symbolFile := compilerOptions.objectFile.DefaultSymbolFileFormat();
  329. END;
  330. ELSIF compilerOptions.objectFile # NIL THEN
  331. compilerOptions.symbolFile := compilerOptions.objectFile.DefaultSymbolFileFormat();
  332. END;
  333. IF options.GetString("documentation", name) THEN
  334. compilerOptions.documentation := Backend.GetBackendByName("Documentation");
  335. IF (compilerOptions.documentation = NIL) THEN
  336. Error("documentation engine could not be installed"); result := FALSE;
  337. END;
  338. ELSE
  339. compilerOptions.documentation := NIL
  340. END;
  341. IF options.GetString("replacements", name) THEN
  342. IF ~ParseReplacements(name, compilerOptions.replacements, diagnostics) THEN
  343. Error("replacement file could not be opened or is empty"); result := FALSE;
  344. END;
  345. ELSE compilerOptions.replacements := NIL
  346. END;
  347. IF compilerOptions.backend # NIL THEN compilerOptions.backend.DefineOptions (options); INCL(compilerOptions.flags,Check); END;
  348. IF compilerOptions.symbolFile # NIL THEN compilerOptions.symbolFile.DefineOptions(options); INCL(compilerOptions.flags,Check) END;
  349. IF compilerOptions.objectFile # NIL THEN compilerOptions.objectFile.DefineOptions(options); INCL(compilerOptions.flags,Check) END;
  350. IF compilerOptions.documentation # NIL THEN compilerOptions.documentation.DefineOptions(options) END;
  351. IF result & ~parsed THEN
  352. options.Clear;
  353. IF defaults # NIL THEN
  354. defaults.SetPos(0);
  355. parsed := options.Parse(defaults, error);
  356. END;
  357. input.SetPos(position);
  358. result := options.Parse(input,error)
  359. END;
  360. IF result THEN
  361. IF options.GetFlag("print") THEN INCL(compilerOptions.flags, Print) END;
  362. IF options.GetFlag("Print") THEN INCL(compilerOptions.flags, Print); INCL(compilerOptions.flags, ChangeCase) END;
  363. IF options.GetFlag("silent") THEN INCL(compilerOptions.flags, Silent) END;
  364. IF options.GetFlag("check") THEN INCL(compilerOptions.flags, Check) END;
  365. IF options.GetFlag("traceError") THEN INCL(compilerOptions.flags, TraceError) END;
  366. IF options.GetFlag("info") THEN INCL(compilerOptions.flags,Info) END;
  367. IF options.GetString("findPC",compilerOptions.findPC) THEN INCL(compilerOptions.flags,FindPC) END;
  368. IF options.GetFlag("warnings") THEN INCL(compilerOptions.flags, Warnings) END;
  369. IF options.GetFlag("darwinHost") THEN INCL(compilerOptions.flags,UseDarwinCCalls) END; (*fld*)
  370. IF options.GetFlag("singleModule") THEN INCL(compilerOptions.flags,SingleModule) END;
  371. IF options.GetFlag("oberon07") THEN INCL(compilerOptions.flags, Oberon07) END;
  372. IF options.GetFlag("cooperative") THEN INCL(compilerOptions.flags, Cooperative) END;
  373. IF options.GetFlag("cellsAreObjects") THEN INCL(compilerOptions.flags, CellsAreObjects) END;
  374. IF ~options.GetString("srcPath", compilerOptions.srcPath) THEN compilerOptions.srcPath := "" END;
  375. IF ~options.GetString("destPath", compilerOptions.destPath) THEN compilerOptions.destPath := "" END;
  376. IF compilerOptions.backend # NIL THEN compilerOptions.backend.GetOptions (options) END;
  377. IF compilerOptions.symbolFile # NIL THEN compilerOptions.symbolFile.GetOptions(options) END;
  378. IF compilerOptions.objectFile # NIL THEN compilerOptions.objectFile.GetOptions(options) END;
  379. IF compilerOptions.documentation # NIL THEN compilerOptions.documentation.GetOptions(options) END;
  380. IF options.GetFlag("lineNumbers") THEN INCL(compilerOptions.flags, UseLineNumbers) END;
  381. IF ~options.GetString("define", compilerOptions.definitions) THEN compilerOptions.definitions := "" END;
  382. IF options.GetString("platformCC", name) THEN
  383. IF name = Global.StringC THEN compilerOptions.platformCallingConvention := SyntaxTree.CCallingConvention
  384. ELSIF name = Global.StringWinAPI THEN compilerOptions.platformCallingConvention := SyntaxTree.WinAPICallingConvention
  385. ELSE
  386. compilerOptions.platformCallingConvention := SyntaxTree.UndefinedCallingConvention
  387. END;
  388. ELSE
  389. compilerOptions.platformCallingConvention := SyntaxTree.UndefinedCallingConvention
  390. END
  391. END;
  392. IF options.GetFlag("showOptions") THEN options.Show(error) END;
  393. RETURN result
  394. END GetOptions;
  395. PROCEDURE Compile*(context : Commands.Context);
  396. VAR
  397. filename, path, file: Files.FileName;
  398. error: BOOLEAN;
  399. diagnostics: Diagnostics.Diagnostics;
  400. time: LONGINT; reader: Streams.Reader;
  401. importCache: SyntaxTree.ModuleScope;
  402. options: CompilerOptions;
  403. replacement: SemanticChecker.Replacement;
  404. name: ARRAY 128 OF CHAR;
  405. BEGIN
  406. error := FALSE;
  407. diagnostics := Basic.GetDiagnostics(context.error);
  408. IF GetOptions(context.arg,context.error,diagnostics,options) THEN
  409. time := Kernel.GetTicks();
  410. WHILE Basic.GetStringParameter(context.arg,filename) & ~error DO
  411. IF options.srcPath # "" THEN
  412. Files.SplitPath(filename, path, file);
  413. IF path = "" THEN Files.JoinPath(options.srcPath, file, filename) END;
  414. END;
  415. reader := Basic.GetFileReader(filename);
  416. IF reader = NIL THEN
  417. diagnostics.Error (filename, Streams.Invalid, "failed to open"); error := TRUE;
  418. ELSE
  419. error := ~Modules(filename, reader, 0, diagnostics,context.out, options, importCache);
  420. END;
  421. context.out.Update;
  422. context.error.Update;
  423. END;
  424. IF Silent IN options.flags THEN
  425. time := Kernel.GetTicks()-time;
  426. context.out.Ln; context.out.String("compiler elapsed ms"); context.out.Int(time,10);
  427. END;
  428. IF ~error THEN
  429. replacement := options.replacements;
  430. WHILE replacement # NIL DO
  431. IF ~replacement.used THEN
  432. name := replacement.name;
  433. diagnostics.Warning(name, Streams.Invalid, " unused replacement.");
  434. END;
  435. replacement := replacement.next;
  436. END;
  437. END;
  438. END;
  439. IF error THEN context.result := -1 ELSE context.result := Commands.Ok END;
  440. END Compile;
  441. PROCEDURE CompileReader*(context: Commands.Context; reader: Streams.Reader);
  442. VAR
  443. filename: ARRAY 256 OF CHAR;
  444. error: BOOLEAN;
  445. diagnostics: Diagnostics.Diagnostics;
  446. importCache: SyntaxTree.ModuleScope;
  447. options: CompilerOptions;
  448. BEGIN
  449. error := FALSE;
  450. diagnostics := Basic.GetDiagnostics(context.error);
  451. IF GetOptions(context.arg,context.error,diagnostics,options) THEN
  452. IF reader = NIL THEN
  453. diagnostics.Error (filename, Streams.Invalid, "failed to open"); error := TRUE;
  454. ELSE
  455. error := ~Modules(filename, reader, 0, diagnostics, context.out, options, importCache);
  456. END;
  457. context.out.Update;
  458. END;
  459. END CompileReader;
  460. VAR
  461. platforms: Options.Defaults;
  462. defaultPlatform: ARRAY 32 OF CHAR;
  463. PROCEDURE DoAddPlatform(CONST name: ARRAY OF CHAR; CONST defaults: ARRAY OF CHAR);
  464. BEGIN
  465. platforms.Add(name, defaults);
  466. END DoAddPlatform;
  467. PROCEDURE ShowDefaults*(context: Commands.Context);
  468. BEGIN
  469. platforms.Show(context.out)
  470. END ShowDefaults;
  471. PROCEDURE AddPlatform*(context: Commands.Context);
  472. VAR name: ARRAY 32 OF CHAR; defaults: ARRAY 1024 OF CHAR;
  473. BEGIN
  474. IF context.arg.GetString(name) & context.arg.GetString(defaults) THEN
  475. DoAddPlatform(name, defaults);
  476. END;
  477. END AddPlatform;
  478. PROCEDURE SetDefaultPlatform*(context: Commands.Context);
  479. VAR name: ARRAY 32 OF CHAR;
  480. BEGIN
  481. IF context.arg.GetString(name) THEN
  482. COPY(name, defaultPlatform);
  483. END;
  484. END SetDefaultPlatform;
  485. PROCEDURE GetDefaultPlatform(VAR name: ARRAY OF CHAR): BOOLEAN;
  486. BEGIN
  487. IF defaultPlatform # "" THEN
  488. COPY(defaultPlatform, name);
  489. RETURN TRUE
  490. ELSE
  491. RETURN FALSE
  492. END
  493. END GetDefaultPlatform;
  494. PROCEDURE SetupDefaults;
  495. VAR extension: Files.FileName;
  496. BEGIN
  497. Machine.GetConfig("ObjectFileExtension", extension);
  498. IF extension = "" THEN
  499. COPY(Machine.DefaultObjectFileExtension, extension)
  500. END;
  501. (* infer platform from default object file extension *)
  502. platforms.Find("objectFileExtension", extension, defaultPlatform);
  503. END SetupDefaults;
  504. BEGIN
  505. NEW(platforms);
  506. (* platform definitions hard coded for the common cases -- maybe (parts of it) should be outsourced to a file ?*)
  507. DoAddPlatform("Bios32","-b=AMD --bits=32 --mergeSections --objectFileExtension=.Gof --symbolFileExtension=.Sym --preciseGC --define=BIOS32,BIOS,NATIVE,I386");
  508. DoAddPlatform("Bios64","-b=AMD --bits=64 --mergeSections --objectFileExtension=.Goff --symbolFileExtension=.Symm --preciseGC --define=BIOS64,BIOS,NATIVE,AMD64");
  509. DoAddPlatform("Win32","-b=AMD --bits=32 --mergeSections --objectFileExtension=.GofW --symbolFileExtension=.SymW --preciseGC --trackLeave --cellsAreObjects --platformCC=WINAPI --define=WIN32,WIN,I386");
  510. DoAddPlatform("Win64","-b=AMD --bits=64 --mergeSections --objectFileExtension=.GofWw --symbolFileExtension=.SymWw --preciseGC --trackLeave --cellsAreObjects --platformCC=WINAPI --define=WIN64,WIN,AMD64");
  511. DoAddPlatform("ARM","-b=ARM --metaData=simple --objectFileExtension=.Goa --symbolFileExtension=.Sya");
  512. DoAddPlatform("Minos","-b=ARM --objectFile=Minos");
  513. DoAddPlatform("TRM","-b=TRM --objectFile=Generic --metaData=simple --objectFileExtension=.GofT --symbolFileExtension=.SymT");
  514. DoAddPlatform("TRMI","-b=TRM --objectFile=Intermediate --metaData=simple --objectFileExtension=.IroT --symbolFileExtension=.IrsT");
  515. DoAddPlatform("ARMA2","-b=ARM --mergeSections");
  516. DoAddPlatform("Linux32","-b=AMD --bits=32 --mergeSections --traceModule=Trace --objectFileExtension=.GofU --symbolFileExtension=.SymU --preciseGC --cellsAreObjects --platformCC=C --define=LINUX32,UNIX32,UNIX,I386");
  517. DoAddPlatform("Linux64","-b=AMD --bits=64 --mergeSections --traceModule=Trace --objectFileExtension=.GofUu --symbolFileExtension=.SymUu --preciseGC --cellsAreObjects --platformCC=C --define=LINUX64,UNIX64,UNIX,AMD64");
  518. SetupDefaults;
  519. END Compiler.