BenjaminKowarsh.txt 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. On the Maintenance of Classic Modula-2 Compilers
  2. Benjamin Kowarsch, Modula-2 Software Foundation
  3. arXiv:1809.07080v1 [cs.PL] 19 Sep 2018
  4. September 2018 (arXiv.org preprint)
  5. Abstract
  6. The classic Modula-2 language was specified in [Wir78] by N.Wirth at ETH Zürich in
  7. 1978. The last revision [Wir88] was published in 1988. Many computer science books of that
  8. era used Modula-2 in programming examples. Many of these are still valuable resources in
  9. computer science education today. To compile and run the examples therein, it is essential
  10. to have compilers available that follow the classic Modula-2 language definition and run on
  11. modern computer hardware and operating systems. Although most Modula-2 compilers of
  12. that era have disappeared, a few have since been re-released under open source licenses.
  13. Whilst the original authors have long ceased work on these compilers, new maintainers have
  14. stepped in. This paper gives recommendations for maintenance on classic Modula-2 compil-
  15. ers while balancing the aim to modernise with the need to maintain the capability to compile
  16. programming examples in the literature with minimal effort. Nevertheless, the principles,
  17. methods and conclusions presented are adaptable to maintenance on other languages.
  18. 1Methodology
  19. 1.1Design Principles
  20. The following design principles strongly influenced the recommendations in this paper:
  21. 1.1.1
  22. Single Syntax Principle (SSP)
  23. There should be one and only one syntax form to express any given concept [Dij78].
  24. 1.1.2
  25. Literate Syntax Principle (LSP)
  26. Syntax should be chosen for readability and comprehensibility by a human reader [Knu84].
  27. 1.1.3
  28. Consistency of Syntax Principle (COSP)
  29. Syntax should be consistent. Analogous concepts should be expressed by analogous syntax.
  30. 1.1.4
  31. Principle of Least Astonishment (POLA)
  32. Of any number of possible syntax forms or semantics, the one likely to cause the least astonish-
  33. ment for a human reader should be chosen and the alternatives should be discarded [Geo87].
  34. 1.1.5
  35. Single Responsibility Principle (SRP)
  36. Units of decomposition, such as modules, classes, procedures and functions should have a single
  37. focus and purpose [Mar09].
  38. 1.1.6
  39. Principle of Information Hiding (POIH)
  40. Implementation specific details should always be hidden, public access should be denied [Par72].
  41. 1.1.7
  42. Safety Perimeter Principle (SPP)
  43. Facilities that undermine the safety otherwise safeguarded within the language should be segre-
  44. gated from other facilities [Wir88, ch.29]. Their use should require an explicit expression of intent
  45. by the author and be syntactically recognisable so as to alert the author, maintainer and reader
  46. of the possible implications. This applies and extends the principle of least privilege [Sal74].
  47. 1On the Maintenance of Classic Modula-2 Compilers
  48. 1.2
  49. 2
  50. Maintenance Objectives
  51. The primary objectives for the recommendations in this paper are:
  52. (1) to remove facilities that are harmful, outdated or violate any of [1.1]
  53. (2) to resolve ambiguities in [Wir88] and incompatibilities between implementations
  54. (3) to maintain the capability to compile programming examples in the literature with
  55. minimal effort
  56. 1.2.1
  57. Weighing Objectives by Impact
  58. The objectives given above may from case to case conflict with one another. Which objective
  59. should be given preference in the event of a conflict depends on the following factors:
  60. (1) the severity of the offending facility
  61. (2) the estimated frequency of use of the offending facility
  62. (3) the effort to update sources impacted by change or removal of the offending facility
  63. The greater the severity of an offending facility, the stronger is the case for change or removal;
  64. the lower the estimated frequency of use and the less the effort to update impacted sources, the
  65. stronger the case for change or removal. In the event that the estimated frequency of use is
  66. high and the effort to update impacted sources is significant, deprecation is recommended.
  67. 1.3
  68. Mitigation Methods
  69. Terms of mitigation methods used in this paper have well defined meanings:
  70. 1.3.1
  71. Warning
  72. A warning should be issued for each and every use of the offending facility.
  73. 1.3.2
  74. Change
  75. The offending facility should be replaced with a proposed alternative.
  76. 1.3.3
  77. Deprecation
  78. A compiler switch to enable and disable the offending facility should be provided and it should
  79. be disabled by default. When it is enabled, a deprecation warning should be isued for each and
  80. every use of the offending facility.
  81. 1.3.4
  82. Removal
  83. Support for the offending facility should be removed altogether.
  84. From an educational perspective, the availability of offending facilities promotes bad habits.
  85. Replacement or removal is therefore generally preferable to warning or deprecation.
  86. 1.3.5
  87. Transformation
  88. To be used in combination with any of change, deprecation or removal. A conversion program
  89. should be provided that transforms source code that uses offending facilities into semantically
  90. equivalent source code that complies with the recommendations given in this paper.
  91. 2Lexis
  92. 2.1Octal Literals
  93. Support for octal literals should be removed.
  94. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  95. 2.1.1
  96. 3
  97. Rationale
  98. The use of octal numbers has long been outdated. Further, the B and C suffixes used to denote
  99. octal literals are also legal digits within hexadecimal literals, which is confusing to human readers
  100. of the source code as it violates POLA [1.1.4] and it unnecessarily complicates lexing.
  101. 2.1.2
  102. Substitution
  103. The built-in CHR() function can be used instead without penalty as it is evaluated at compile time
  104. for constant arguments. The function accepts decimal and hexadecimal arguments. Code that
  105. uses the CHR() function instead of octal literals can always be compiled on any classic Modula-2
  106. compiler, regardless of whether octal literals are recognised or not.
  107. 2.1.3
  108. Backwards Compatibility
  109. Preferably, transformation should be used to replace all occurences of octal literals in existing
  110. Modula-2 sources. Alternatively, octal literals could be deprecated instead.
  111. 2.2
  112. Synonym Symbols
  113. Support for synonym symbols <>, & and ˜ should be removed.
  114. 2.2.1
  115. Rationale
  116. The availability of alternative symbols violates SSP (1.1.1) and they are are notably absent
  117. from the grammar in [Wir88, pp.156-157].
  118. The inequality operator symbol # is preferable to its synonym <> because it resembles the
  119. mathematical inequality symbol 6= and as a single character symbol it simplifies lexing. Reserved
  120. words AND and NOT are preferable to their respective synonyms & and ˜ because of consistency:
  121. While there are synonyms for AND and NOT, there is none for OR. Although | could have been used
  122. to denote OR, it is already used to separate case labels and would have caused ambiguity.
  123. 2.2.2
  124. Substitution
  125. Symbol # can be used in place of <>, while AND can be used in place of & and NOT in place of ˜.
  126. 2.2.3
  127. Backwards Compatibility
  128. Preferably, transformation should be used to replace all occurences of synonym symbols in
  129. existing Modula-2 sources. Alternatively, synonym symbols could be deprecated instead.
  130. 2.3
  131. Non-Semantic Compiler Directives
  132. Whilst compiler directives are implementation defined, the delimiters of non-semantic compiler
  133. directives should not be. They should be denoted by an opening (*$ and a closing *) delimiter.
  134. 2.3.1
  135. Rationale
  136. Although [Wir88, p.18] mentions (* and *) as delimiters for both comments and directives, it
  137. does not specify their use in any normative manner. Some compiler implementors have taken
  138. this to mean that the delimiters are implementation defined. Several compilers still in use today
  139. do not follow the convention, for example the venerable MOCKA compiler [EV94].
  140. As a result, source code with compiler directives is often not portable across different im-
  141. plementations. This is unfortunate, because non-semantic directives can safely be ignored in
  142. the event that they are not supported. Even where an implementation issues warnings about
  143. unrecognised directives, to be able to identify a directive as such in the first place, a common
  144. delimiter convention needs to be followed across implementations.
  145. 2.3.2
  146. Backwards Compatibility
  147. Non-compliant directives within existing source code should be replaceable with minimal effort
  148. using regular expressions and a filter program such as sed or awk.
  149. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  150. 2.4
  151. 4
  152. Semantic Compiler Directives
  153. Semantic compiler directives should not be denoted by the same delimiters used for non-semantic
  154. compiler directives.
  155. 2.4.1
  156. Rationale
  157. Whilst non-semantic compiler directives can safely be ignored, semantic compiler directives can-
  158. not. A semantic compiler directive that is not supported by an implementation must be reported
  159. as an error. Consequently, an implementation needs to be able to distinguish between semantic
  160. and non-semantic directives. In order to do so, different delimiters must be used.
  161. 2.4.2
  162. Substitution
  163. Some Modula-2 compilers have used a % prefix to denote compiler directives, in particular for
  164. conditional compilation, for example the MOCKA compiler [EV94]. We recommend to follow
  165. that convention to denote non-semantic compiler directives if any are provided. The % symbol is
  166. not otherwise used in the language.
  167. 2.4.3
  168. Backwards Compatibility
  169. Non-compliant directives within existing source code should be replaceable with minimal effort
  170. using regular expressions and a filter program such as sed or awk.
  171. 3Syntax
  172. 3.1Multi-Dimensional Arrays
  173. Inconsistent definition or declaration of multi-dimensional arrays should trigger warnings.
  174. 3.1.1
  175. Rationale
  176. [Wir88, p.138] specifies alternative syntax forms for multi-dimensional array type declaration:
  177. TYPE Matrix = ARRAY [0 .. Cols], [0 .. Rows] OF REAL;
  178. is an abbreviation of and thus equivalent to
  179. TYPE Matrix = ARRAY [0 .. Cols] OF ARRAY [0 .. Rows] OF REAL;
  180. The availability of alternative syntax forms violates SSP [1.1.1] and COSP [1.1.3]. The more
  181. dimensions an array type has, the more preferable the abbreviated form becomes. However, it is
  182. more effort to remove or deprecate the long form. The impact of removal or deprecation on
  183. existing sources with multi-dimensional arrays would likely be high. It is less effort and sufficient
  184. to modify an implementation to detect and warn about mixed use in any given compilation unit.
  185. 3.1.2
  186. Backwards Compatibility
  187. The proposed mitigation does not impact the compatibility of legacy sources.
  188. 3.2
  189. Local Modules
  190. Local Modules should be deprecated.
  191. 3.2.1
  192. Rationale
  193. If there is sufficient reason to delegate certain responsibilities of a library module to a local
  194. module, then there is also sufficient reason to delegate those responsibilities to a separate library
  195. module. There is no reason why a local module should be chosen over a separate library.
  196. Furthermore, a local module within a program or library module unnecessarily increases the
  197. line count of the module and thus reduces its readabililty and maintainability. It runs counter
  198. to the very rationale of decomposing source code into separate modules in the first place.
  199. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  200. 5
  201. Finally, a test environment for testing a local module must necessarily be provided within
  202. the hosting module. This further increases clutter and poses the question whether to release the
  203. module with or without the embedded test environment. By contrast, a proper library module
  204. can be imported into any number of lexically independent test environments.
  205. 3.2.2
  206. Substitution
  207. Local modules should be removed from their enclosing module and provided as proper library
  208. modules with their own definition and implementation parts.
  209. 3.2.3
  210. Backwards Compatibility
  211. Backwards compatibility can be provided via compiler switch.
  212. 3.2.4
  213. Private-Use Aspect
  214. The private-use aspect of local modules is lost when they are removed from their host modules
  215. and converted into library modules. However, this aspect is useful when the local module’s API is
  216. considered unstable and subject to frequent changes. A satisfactory solution can be implemented
  217. easily by introducing a non-semantic compiler directive that specifies a library’s intended client
  218. modules and causes the compiler to issue warnings whenever such a library is imported by a
  219. module other than its designated client modules. An example is given below:
  220. DEFINITION MODULE PrivateLib; (*$CLIENTS=FooLib, BarLib, BazLib*)
  221. (∗ ATTENTION !!! This module is intended for private use only.
  222. ∗ Its API is subject to frequent change without prior notice.
  223. ∗ The compiler will issue a warning when it is imported from
  224. ∗ any other than the designated client modules. ∗)
  225. ···
  226. END PrivateLib.
  227. 3.3
  228. Unary Minus
  229. Unary minus should only be permitted before a factor.
  230. simpleExpression :=
  231. ( ’+’ )? term ( addOp term )* | ’-’ factor
  232. ;
  233. instead of
  234. simpleExpression :=
  235. ( ’+’ | ’-’ )? term ( addOp term )*
  236. ;
  237. 3.3.1
  238. Rationale
  239. [Wir88] does not state the scope of the unary minus operator other than through the grammar.
  240. An expression of the form
  241. − a ∗ b + c
  242. could be interpreted mathematically correct
  243. (−a) ∗ b + c
  244. or grammatically correct
  245. −(a ∗ b + c)
  246. The former interpretation conforms to mathematical convention. The latter can be deduced
  247. from the grammar in [Wir88, pp.156-157] and is intended to be the correct interpretation1 .
  248. 1 The author obtained clarification on the precedence of unary minus from Prof. Wirth by email.
  249. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  250. 6
  251. However, this violates POLA [1.1.4] and some implementations therefore follow the mathemat-
  252. ically correct interpretation, for example the ACK compiler [Jac85] and the MOCKA compiler
  253. [EV94]. Requiring a factor after a unary minus forces the use of parentheses whenever there is
  254. more than one factor to follow which makes programmer intent explicit.
  255. 3.3.2
  256. Backwards Compatibility
  257. Unary minus is an infrequently used operation. When it is used, it is usually in a form that
  258. is compliant with the syntax proposed in this paper. In the unlikely event that it is not in
  259. a compliant form, the source code is ambiguous and needed to be fixed anyway. It may well
  260. have been written for and tested with a compiler that uses a different interpretation than the
  261. compiler now used to compile the sources. The proposed mitigation will thereby help identify
  262. any non-compliant occurrences which can then be corrected with minimal effort.
  263. 4Pervasives
  264. 4.1Conversion
  265. Pervasive function VAL() should be changed to cover all numeric conversions and numeric conver-
  266. sions only. Pervasive functions FLOAT() and TRUNC() should then be deprecated. Any additional
  267. non-standard conversion functions such as INT(), CARD() and LFLOAT() should be removed.
  268. 4.1.1
  269. Rationale
  270. [Wir88, p.150] specifies pevasive conversion function VAL() which covers all possible use cases for
  271. safe type conversion between whole number types. There is no reason why VAL() could not also
  272. cover all possible use cases for conversions between whole and real number types. By contrast,
  273. CHR() and ORD() are not conversion functions2 and they should not be duplicated by VAL().
  274. Duplication violates SSP [1.1.1].
  275. Furthermore, function FLOAT() is confusingly named since the type it converts to is REAL and
  276. there is no type FLOAT. [Wir88] does not specify how real number types are to be implemented.
  277. They need not be implemented as floating point numbers but could be implemented as binary
  278. coded decimals, for instance. The naming of FLOAT() is thus misleading and violates COSP [1.1.3]
  279. and POLA [1.1.4].
  280. Finally, function TRUNC() violates SRP [1.1.5] as it represents both a conversion function and
  281. the mathematical function trunc(x). Its name is misleading as it does not suggest conversion,
  282. violating POLA [1.1.4]. Conversion should be the responsibility of function VAL() and truncation
  283. the responsibility of a math function trunc() to be provided in a library such as MathLib and
  284. return the same type as its argument, it should not perform any type conversion.
  285. 4.1.2
  286. Substitution
  287. Once function VAL() has been extended to provide type conversion between whole and real
  288. number types, any invocation of functions FLOAT() and TRUNC() within existing source code may
  289. be safely replaced with an invocation of VAL().
  290. 4.1.3
  291. Backwards Compatibility
  292. Backwards compatibility can be provided via compiler switch.
  293. 4.1.4
  294. Implementation
  295. It should be noted that function VAL() is not generally implemented as a single function, nor
  296. should it be. Instead, it is usually and preferably implemented as a built-in macro, resolved
  297. at compile time to a function internal to the compiler that is specific to the source and target
  298. types of its arguments, since the types are known at compile time. VAL() thereby simplifies the
  299. user interface without incurring the penalty of increasing the complexity of its implementation.
  300. The specific conversion functions need to be implemented within the compiler anyway, but they
  301. should not be individually exposed in the user interface.
  302. 2 CHR() performs a lookup while ORD() returns a property.
  303. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  304. 5Semantics
  305. 5.1Exported Variables
  306. 7
  307. Variables defined in definition parts should be exported read-only.
  308. 5.1.1
  309. Rationale
  310. Allowing a client module to write to imported variables violates POIH [1.1.6]. And indeed,
  311. [Wir88, p.88] explicitly states that “imported variables should be treated as ‘read-only’ objects”.
  312. 5.1.2
  313. Substitution
  314. A setter procedure can be defined and exported by the same module if needed.
  315. DEFINITION MODULE Foo;
  316. VAR bar : Bar; (∗ read−only ∗)
  317. PROCEDURE SetBar ( value : Bar );
  318. END Foo.
  319. 5.1.3
  320. Backwards Compatibility
  321. Considering that Wirth explicitly stated to treat imported variables as “read-only” objects, noone
  322. should have written any code that treats them as mutable objects. Unfortunately, there will be
  323. code written by careless programmers who didn’t follow his advice. The cautious maintainer may
  324. therefore consider providing a compiler switch to enable and disable write-access to imported
  325. variables, which should then be disabled by default.
  326. 5.2
  327. Pointer Variables
  328. All pointer variables should be initialised to NIL and deallocation should reset them to NIL.
  329. 5.2.1
  330. Rationale
  331. The two primary paradigms of Modula-2 are (a) program decomposition through data encapsu-
  332. lation and information hiding, and (b) reliability through type safety. Opaque pointer types are
  333. the primary instrument through which the former is achieved. The ability to test whether an
  334. opaque pointer type has been allocated or deallocated is central to achieving the latter.
  335. 5.2.2
  336. Backwards Compatibility
  337. The proposed mitigation does not impact the compatibility of legacy sources.
  338. 5.3
  339. Unsafe Facilities
  340. Any facility that bypasses the type safety provided by the language should be disabled by default.
  341. 5.3.1
  342. Unsafe Facilities provided by SYSTEM
  343. [Wir88, p.121] defines pseudo-module SYSTEM as a container for unsafe facilities. The facilities
  344. provided therein are only enabled by import. This is desirable as it sensitises programmers to
  345. the fact that the facilities are unsafe and thereby discourages their use.
  346. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  347. 5.3.2
  348. 8
  349. Unsafe Facilities NOT provided by SYSTEM
  350. Unfortunately, not all unsafe facilities are provided through pseudo-module SYSTEM. Two unsafe
  351. facilities are provided in the language core and are enabled by default without import:
  352. (1) Unsafe type transfers [Wir88, p.119], also known as type casts
  353. (2) Records with variant parts [Wir88, p.71, p.138], also known as variant records
  354. This is a violation of SPP [1.1.7] and given its implications for program safety it is unacceptable.
  355. In order to mitigate this situation, support for type casts and variant records should be disabled
  356. by default and require enabling by compiler switch.
  357. 5.3.3
  358. Ideal World Scenario
  359. In an ideal world, the type cast syntax would be replaced with a CAST() function provided by
  360. SYSTEM as in ISO Modula-2 [JTC96], and variant records with type safe extensible records as
  361. in Oberon [Wir90]. However, this would constitute a substantial language revision and as such
  362. go beyond the scope of the maintenance aspect of this paper. It would also run counter to the
  363. objective to allow the compilation of programming examples in the literature with minimal effort.
  364. 6Language Extensions
  365. 6.1Availability
  366. All language extensions should be disabled by default and only enabled by compiler switch.
  367. 6.1.1
  368. Rationale
  369. Disabling language extensions by default aids and promotes writing of portable source code.
  370. 6.2
  371. Smallest Addressable Unit
  372. Under no circumstances should any implementation change the definition of type SYSTEM.WORD.
  373. However, an implementation targeting an architecture where the smallest addressable storage
  374. unit is eight bits wide should provide an alias type BYTE in module SYSTEM as follows:
  375. TYPE BYTE = WORD;
  376. 6.2.1
  377. Rationale
  378. [Wir88, p.153] specifies SYSTEM.WORD as the smallest addressable unit3 . Whilst the report permits
  379. provision of additional facilities in SYSTEM, it does not permit alterations of SYSTEM facilities
  380. specified in the report.
  381. It would thus be permissible to provide an additional type SYSTEM.MACHINEWORD that represents
  382. a machine word larger than the smallest addressable unit, but it is not permissible to change
  383. SYSTEM.WORD to represent a machine word that is not the smallest addressable unit.
  384. 6.3
  385. Foreign Identifiers
  386. An implementation that provides a means to interface to foreign APIs, should also allow the
  387. use of foreign identifiers. Such an identifier may contain one or more dollar $ and/or lowline
  388. _ characters. The use of foreign identifiers for other purposes should be discouraged. Support
  389. should be disabled by default and enabled by compiler switch when needed.
  390. To avoid any collission with name mangled symbols generated by the Modula-2 compiler, no
  391. consecutive and no trailing dollar signs should be permitted; no leading, no consecutive and no
  392. trailing lowlines should be permitted. Further, dollar signs and lowlines should not be permitted
  393. within module identifiers.
  394. 3 When the first report on Modula-2 was written it was still common to call the smallest addressable storage
  395. unit a word. Since then the terminology has changed and it has become common to use the term byte instead.
  396. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  397. 6.3.1
  398. 9
  399. Rationale
  400. Operating system APIs and other foreign APIs often include variables and procedures with
  401. identifiers that include dollar $ (predominantly on the VMS operating system) and lowline _
  402. (predominantly on Unix systems and C APIs in general).
  403. 6.4
  404. Foreign Definition Modules
  405. An implementation that provides a means to interface to foreign APIs, should use a non-semantic
  406. compiler directive to mark a definition module as a foreign definition module.
  407. 6.4.1
  408. Rationale
  409. [Wir88] does not mention foreign definition modules. As a result, implementors have invented
  410. their own syntax to mark a definition module as foreign, and this varies between implementations.
  411. However, the corresponding implementation could in principle be done in Modula-2. The
  412. marking of a definition module as foreign does not alter its semantics. Consequently, any such
  413. marking constitutes de-facto a non-semantic compiler directive.
  414. 6.4.2
  415. Proposed Syntax
  416. The directive should be placed after the module header, its proposed syntax is as follows:
  417. ffiPragma :=
  418. ’(*$’ ffiPragmaKey ’=’ ’"’ foreignAPI ’"’ ’*)’
  419. ;
  420. ffiPragmaKey :=
  421. ’F’ | /* if implementation uses single-letter keys */
  422. ’FFI’ /* if implementation uses multi-letter keys */
  423. ;
  424. foreignAPI :=
  425. ’ASM’ | ’C’ | ’Fortran’ | ’Pascal’ | ...
  426. ;
  427. 7Miscellaneous
  428. 7.1Filename Suffixes
  429. Modula-2 implementations should only recognise input files with suffixes def and mod.
  430. 7.1.1
  431. Rationale
  432. Neither [Wir78] nor [Wir88] mention filename suffixes for Modula-2 source files. A de-facto
  433. standard has been established by the compilers distributed by ETH Zürich: Suffix def is used
  434. for definition module files and suffix mod for implementation and program module files.
  435. The absence of any mentioning of filename suffixes in [Wir78] and [Wir88] has been taken by
  436. some implementors as an invitation to define their own non-standard filename suffixes.
  437. The use of non-standard suffixes leads to unnecessary effort when compiling sources across dif-
  438. ferent implementations. Moreover, it has led to conflicts with other notations in and inconsistent
  439. support for Modula-2 by various text editors and source code renderers.
  440. 7.2
  441. Pre-Revision Compilers
  442. An implementation that follows the original monograph [Wir78] or the second edition [Wir83]
  443. should be updated to follow the third [Wir85] or, preferably the fourth [Wir88] edition.
  444. 7.2.1
  445. Rationale
  446. Prior to [Wir85] a definition module was required to have an export list. This was unnecessary
  447. duplication since the purpose of a definition module is to export all its contents.
  448. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial useOn the Maintenance of Classic Modula-2 Compilers
  449. 10
  450. Definitions
  451. API
  452. Application programming interface.
  453. compiler directive
  454. A directive within the source to instruct a language processor how to process the input.
  455. ETH
  456. Eidgenössisch Technische Hochschule – Swiss Federal Institute of Technology.
  457. foreign API
  458. An API implemented in a language other than Modula-2.
  459. foreign definition module
  460. A definition module that specifies an interface to a foreign API .
  461. foreign identifier
  462. An identifier of a foreign API.
  463. non-semantic compiler directive
  464. A compiler directive that does not alter the semantics of the source code.
  465. offending facility
  466. A language facility that is (a) outdated, harmful or bad habit forming in general,
  467. or (b) violates any of the design principles in section 1.1 in particular.
  468. semantic compiler directive
  469. A compiler directive that alters the semantics of the source code.
  470. References
  471. [Dij78]Edsger W. Dijkstra. On the GREEN Language submitted to the DoD.
  472. E.W.Dijkstra Archive, originally circulated privately, 1978.
  473. [EV94]H. Emmelmann and J. Vollmer. GMD Modula-2 System MOCKA User Manual, 1994.
  474. [Geo87] James Geoffrey. The Tao of Programming. InfoBooks, 1987.
  475. [Jac85] Ceriel J.H. Jacobs. The ACK Modula-2 Compiler, 1985.
  476. [JTC96] ISO/IEC JTC1/SC22/WG13. Information Technology – Programming Languages –
  477. Part 1: Modula-2, Base Language. International Standard 10514-1, ISO/IEC, 1996.
  478. [Knu84] Donald E. Knuth. Literate Programming. The Computer Journal, 27(2), 1984.
  479. [Mar09] Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship.
  480. Prentice Hall, 2009.
  481. [Par72] David L. Parnas. On the Criteria to be Used in Decomposing Systems into Modules.
  482. Comunications of the ACM, 15(12), 1972.
  483. [Sal74]
  484. Jerome H. Saltzer. The Protection of Information in Computer Systems.
  485. Comunications of the ACM, 17(7), 1974.
  486. [Wir78] Niklaus Wirth. Modula-2. Technical report, ETH Zürich, 1978.
  487. [Wir83] Niklaus Wirth. Programming in Modula-2. Springer, Heidelberg, 2nd edition, 1983.
  488. [Wir85] Niklaus Wirth. Programming in Modula-2. Springer, Heidelberg, 3rd edition, 1985.
  489. [Wir88] Niklaus Wirth. Programming in Modula-2. Springer, Heidelberg, 4th edition, 1988.
  490. [Wir90] Niklaus Wirth. Oberon Language Report. Technical report, ETH Zürich, 1990.
  491. Copyright c 2018 Benjamin Kowarsch – arXiv.org preprint for non-commercial use