FoxCompiler.Mod 21 KB

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