CompilerInterface.Mod 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. MODULE CompilerInterface; (** AUTHOR "staubesv"; PURPOSE "Generic compiler interface"; *)
  2. (**
  3. * The idea of this module is to make it possible for client applications to use multiple different compilers.
  4. * Compiler can be retrieve by name, file extension of filename.
  5. *)
  6. IMPORT
  7. KernelLog, Streams, Commands, Strings, Texts, Diagnostics;
  8. CONST
  9. ModuleName = "CompilerInterface";
  10. TYPE
  11. Name* = ARRAY 16 OF CHAR;
  12. Description* = ARRAY 128 OF CHAR;
  13. FileExtension* = ARRAY 16 OF CHAR;
  14. CompileTextProc* = PROCEDURE {DELEGATE} (t : Texts.Text; CONST source: ARRAY OF CHAR; pos: LONGINT; CONST pc,opt: ARRAY OF CHAR;
  15. log: Streams.Writer; diagnostics : Diagnostics.Diagnostics; VAR error: BOOLEAN);
  16. TYPE
  17. Compiler* = OBJECT
  18. VAR
  19. name- : Name;
  20. description- : Description;
  21. fileExtension- : FileExtension;
  22. compileText : CompileTextProc;
  23. next : Compiler;
  24. PROCEDURE CompileText*(t : Texts.Text; CONST source: ARRAY OF CHAR; pos: LONGINT; CONST pc,opt: ARRAY OF CHAR;
  25. log: Streams.Writer; diagnostics : Diagnostics.Diagnostics; VAR error: BOOLEAN);
  26. VAR
  27. trap : BOOLEAN;
  28. BEGIN
  29. trap := FALSE;
  30. IF (compileText # NIL) THEN
  31. compileText(t, source, pos, pc, opt, log, diagnostics, error);
  32. ELSIF (diagnostics # NIL) THEN
  33. diagnostics.Error(source, Streams.Invalid, "Text compile procedure not set");
  34. END;
  35. FINALLY
  36. IF trap THEN (* trap will be set in case a trap occurs in the block above *)
  37. error := TRUE;
  38. diagnostics.Error(source, Streams.Invalid, "COMPILER TRAPPED");
  39. log.String("COMPILER TRAPPED!!!"); log.Update;
  40. END;
  41. END CompileText;
  42. PROCEDURE Show(out : Streams.Writer);
  43. BEGIN
  44. out.String(name);
  45. out.String(" ("); out.String(description); out.String(") ");
  46. out.String("File Extension: "); out.String(fileExtension);
  47. out.Ln;
  48. END Show;
  49. PROCEDURE &Init*(
  50. CONST name : Name;
  51. CONST description : Description;
  52. CONST fileExtension : FileExtension;
  53. compileText : CompileTextProc
  54. );
  55. BEGIN
  56. SELF.name := name; SELF.description := description; SELF.fileExtension := fileExtension;
  57. SELF.compileText := compileText;
  58. END Init;
  59. END Compiler;
  60. VAR
  61. compilers : Compiler;
  62. PROCEDURE FindCompilerByName(CONST name : ARRAY OF CHAR) : Compiler;
  63. VAR c : Compiler;
  64. BEGIN
  65. c := compilers;
  66. WHILE (c # NIL) & (c.name # name) DO c := c.next; END;
  67. RETURN c;
  68. END FindCompilerByName;
  69. (** Get compiler object for a specific file extension. Returns NIL if no appropriate compiler found. *)
  70. PROCEDURE GetCompiler*(fileExtension : FileExtension) : Compiler;
  71. VAR c : Compiler;
  72. BEGIN {EXCLUSIVE}
  73. Strings.UpperCase(fileExtension);
  74. c := compilers;
  75. WHILE (c # NIL) & (c.fileExtension # fileExtension) DO c := c.next; END;
  76. RETURN c;
  77. END GetCompiler;
  78. PROCEDURE GetCompilerByName*(CONST name : ARRAY OF CHAR) : Compiler;
  79. BEGIN {EXCLUSIVE}
  80. RETURN FindCompilerByName(name);
  81. END GetCompilerByName;
  82. (** Get compiler object for a filename. A compiler is appropriate for a given file name
  83. if the file extension the compiler requires is part of the filename, e.g. Module.Mod.Bak for the file extension .Mod
  84. Returns NIL if no appropriate compiler found *)
  85. PROCEDURE GetCompilerByFilename*(filename : ARRAY OF CHAR) : Compiler;
  86. VAR c : Compiler; pos : LONGINT;
  87. BEGIN {EXCLUSIVE}
  88. Strings.UpperCase(filename);
  89. c := compilers;
  90. LOOP
  91. IF (c = NIL) THEN EXIT; END;
  92. pos := Strings.Pos(c.fileExtension, filename);
  93. IF (pos > 0) & (filename[pos-1] = ".") THEN
  94. EXIT;
  95. END;
  96. c := c.next;
  97. END;
  98. RETURN c;
  99. END GetCompilerByFilename;
  100. (** Show all registered compilers *)
  101. PROCEDURE Show*(context : Commands.Context);
  102. VAR c : Compiler;
  103. BEGIN {EXCLUSIVE}
  104. IF (compilers = NIL) THEN
  105. context.out.String("No compilers registered."); context.out.Ln;
  106. ELSE
  107. c := compilers;
  108. WHILE (c # NIL) DO c.Show(context.out); c := c.next; END;
  109. END;
  110. END Show;
  111. (** Register a compiler. The name of the compiler must be unique. *)
  112. PROCEDURE Register*(
  113. CONST name : Name;
  114. CONST description : Description;
  115. fileExtension : FileExtension;
  116. compileText : CompileTextProc);
  117. VAR
  118. c : Compiler;
  119. BEGIN {EXCLUSIVE}
  120. ASSERT(compileText # NIL);
  121. c := FindCompilerByName(name);
  122. IF (c = NIL) THEN
  123. Strings.UpperCase(fileExtension);
  124. NEW(c, name, description, fileExtension, compileText);
  125. c.next := compilers; compilers := c;
  126. ELSE
  127. KernelLog.Enter;
  128. KernelLog.String(ModuleName); KernelLog.String(": Cannot register compiler '");
  129. KernelLog.String(name); KernelLog.String("': Name is already in use.");
  130. KernelLog.Exit;
  131. END;
  132. END Register;
  133. (** Unregister a compiler *)
  134. PROCEDURE Unregister*(CONST name : Name);
  135. VAR prev : Compiler;
  136. BEGIN {EXCLUSIVE}
  137. IF (compilers = NIL) THEN RETURN; END;
  138. IF (compilers.name = name) THEN
  139. compilers := compilers.next;
  140. ELSE
  141. prev := compilers;
  142. WHILE(prev.next # NIL) & (prev.next.name # name) DO prev := prev.next; END;
  143. IF (prev.next # NIL) THEN
  144. prev.next := prev.next.next;
  145. END;
  146. END;
  147. END Unregister;
  148. BEGIN
  149. compilers := NIL;
  150. END CompilerInterface.
  151. CompilerInterface.Show ~
  152. System.Free CompilerInterface ~