FoxCompiler.Mod 21 KB

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