ML/I
ML/1 is a powerful general-purpose macro processor.
Typical uses of ML/1 include:
- editing, modifying, correcting, or reformatting text files
- translating source code from one programming language to another
- acting as a source-code preprocessor to allow the user to add new syntactic forms to an existing programming language
- supporting program source-code parameterization
In 1984, Robert D. Eager, one of Peter Brown's colleagues at the University of Kent, rewrote ML/I, first in BCPL in 1981, and later in C in 1984, which increased its portability.
- Note that Peter Brown's original name for the language was ML/I, where the last character is the Roman numeral "I", not the Arabic numeral "1". Most subsequent implementations however have been called ML/1.
That version is available for multiple platforms via the ML/1 web site, http://www.ml1.org.uk. The ML/1 web site provides further information about ML/1, as well as documentation.
Although the total number of ML/1 users in the world is small, there are ML/1 users all over the world, and Bob has corresponded with ML/1 users in the United States, Canada, Australia, New Zealand, Germany, Holland, and India.
In a 1976 paper, Andrew S. Tanenbaum describes using ML/I as a compiler-compiler.
Overview
ML/I accepts input in completely free form, treating data as a stream of bytes rather than a series of lines or records. It does not require any particular flag to indicate a macro expansion, which makes it particularly useful for processing arbitrary text. Replacements of text can be simple or complex.ML/I was used to implement several items of portable software, including itself. It was originally written in a special descriptive language, then mapped into a suitable language for each target system. This mapping was done using ML/I itself. There were two different forms of this descriptive language; high level and low level.
After this mapping ML/I was often used to implement SIL's for the new generation of 16-bit architecture minicomputers.
How ML/1 works
In the most basic terms, here's how ML/1 works.- The user supplies ML/1 with a file containing input text.
- In another file the user supplies a set of ML/1 macros. The macros tell the ML/1 interpreter what insertions, deletions, expansions, translations and other modifications the user wants made to the input text.
- When ML/1 is run on the input text, ML/1 follows the instructions in the ML/1 macros, changes the text, and writes out a new file containing the modified text.
Distinctive features of ML/1
There are several ways in which ML/1 is more powerful than simple "scan and replace" utilities.ML/1 does not process text on a character-string by character-string basis; it processes text on a word by word basis. For many applications, it is extremely useful to be able to process a text as a sequence of atoms rather than a sequence of characters. Suppose, for example, that we wish to translate a program from a programming language that has a DO... END syntax, into a language that has a BEGIN... END syntax. We therefore wish to replace "DO" with "BEGIN". If we do the replacement with an ordinary scan-and-replace utility, all occurrences of the string "DO" will be changed to "BEGIN", including any "DO"s that are embedded in words such as "DOCUMENT". With ML/1, in contrast, this will not happen because the string "DO" will trigger text-replacement only when it occurs as a word.
ML/1, rather than operating on a line-by-line basis, recognizes patterns of text that can be quite complex, nested, with multiple delimiters, and spanning many lines. ML/1 can, for instance, process a pattern such as the common programming language IF... THEN... ELSE... ENDIF structure that spans multiple lines, and contains embedded text that itself may include a nested IF... THEN... ELSE... ENDIF structure.
ML/1 can recognize embedded comments and literal quotations, and protect them from alteration. Ordinary scan-and-replace utilities change strings indiscriminately, whether they occur in the program text as a keyword or variable name, embedded in a comment, or in a quoted literal.
In order to deal with such complicated patterns, ML/1 needs to be a programming language in its own right. Like other programming languages, ML/1 supports variables and assignment statements, GOTOs and labels, IF... THEN tests and loops. These features give ML/1 an unusual degree of power and flexibility.