Mary(ID:647/mar017)


Mark Rain, Trondheim, 1972

Machine-oriented language (in modern terms systems development language), a extensible superset of ALGOL68 that enabled explicit direction of machine instruction. "Succinctly, what you write is what you get in MARY". (Rain 1973)

Hidden on the back cover of the manual: MARY HAD A LITTLE LAMB - COERCION IMPOSSIBLE.


Related languages
ALGOL 68 => Mary   Superset
Mary => Mary/2   Evolution of

References:
  • Rain, M. and Holager, P. "Labels in MARY" Norwegian Institute of Technology, Trondheim 1971 view details
  • Rain, M. and Holager, P. "Revised Labels in MARY" Norwegian Institute of Technology, Trondheim 1971 view details
  • Rain, M. and Holager, P. "The Final Word about Labels in MARY" Norwegian Institute of Technology, Trondheim 1971 view details
  • Rain, M. and Holager, P. "The most recent Final Word about Labels in MARY" Norwegian Institute of Technology, Trondheim 1971 view details
  • Digernes, T. " An Implementation Language for the UNIVAC 1108" Thesis, Norwegian Institute of Technology, Trondheim . view details
  • Holager, Per "A consolidation of synchronization primitives" 7(12) (December 1972) pp42-52 view details Abstract: Various facilities for synchronizing parallell, asynchronous processes are reviewed.A new facility, consisting of the data type telegraph, and the operations acquire and release, is presented, and their implementation in the programming language MARY is sketched.The telegraph is a generalization of the Dijkstra semaphore. In addition to the services provided by the semaphore, the telegraph allows data to be passed between processes.


    DOI
          in SIGPLAN Notices 7(12) December 1972 view details
  • Rain, M . "Some Formal Language Aspects of MARY, or Algol X Revisited." Algol Bulletin 34, 1972. view details
          in SIGPLAN Notices 7(12) December 1972 view details
  • Rain, M. "Some formal aspects of MARY or ALGOL X revisited" SINTEF Techn. University of Norway, Trondheim 1972 view details
          in SIGPLAN Notices 7(12) December 1972 view details
  • Rain, M. and Holager, P. "The Present Most Recent Final. Word about Labels in MARY." Machine Oriented Languages Bulletin 1, 1972. view details
          in SIGPLAN Notices 7(12) December 1972 view details
  • Rain, Mark "Storage control in MARY" pp31-39 view details Abstract: Storage areas may be declared in MARY, and data mapped onto those areas may be overlapped in an arbitrary fashion under control of the programmer.  By appropriate overlapping a program may achieve economy of data space while retaining effecient subroutine calling interfaces.  For more complex applications, the standard prelude generator RECURS (stack allocation discipline) or user written storage generators may be involved in a natural fashion from the language.  A system of implicit calls may be constructed by the programmer to aid these storage schemes which require garbage collection or other space recovery techniques.  It is expected that systems programmers will write generator packages for use by other programmers as a prelude construct.  One such library storage system, syntacticly and semanticly similar to the "HEAP" discipline of Algol 68, is supported in our system.  This facility is not an intrinsic part of MARY, but consists solely of declaration forming a user1 prelude.

          in SIGPLAN Notices 7(12) December 1972 view details
  • Gurski, Aaron "Job control languages as machine orientated languages" pp18-23 view details Abstract: Arguments are presented which demonstrate the equivalence of computers (both real and virtual) and programming languages. The machine which job control languages are equivalent to is shown to be a virtual one: operating systems. A suggestion is made that a high level, portable job control language is feasible, and some suggestions as to features of the language are made. DOI Extract: Programming languages as a description of a computer
    Programming languages as a description of a computer
    A complete list of the order codes for a computer and the effect of each order code upon the computer forms a complete description of the functioning of the computer . These order codes constitute a programming language, the assembly language for the machine. For each order code in the machine's hardware, there exists a corresponding order code in the assembly language. Hence, BAL functionally defines the IBM System/360.
    There are those who say that FORTRAN defines the IBM 7094 ; they are not entirely wrong . The arithmetic IF statement in FORTRAn directly reflects the order code in the IBM 7094 that branched to one of three storage locations depending on whether the contents of the accumulator were negative, zero or positive . However, what about FORMATs? The IBM 7094 did not have anything in its hardware that corresponded to FORTRAN's FORMAT statement . Hence, it is not quite correct to say that FORTRAN describes the IBM 7094 . What FORTRAN does describe, however, is a non-existent, i.e. a virtual, computer, which does have things in its virtual hardware that correspond to FORMATs and, indeed, to all other features in FORTRAN . This FORTRAN machine can then be simulated on a real machine . The simulation is easiest when the real and virtual machines are similar, as, for example, in the case of the IBM 7094 . Language features which did not exist in the hardware, such as FORMATs, had to be implemented in terms of software. The same holds true for any other computer that can run FORTRAN programs : the hardware and software together form an °implementation of a virtual machine described by FORTRAN.
    Of course, the above arguments are not only valid for FORTRAN. ALGOL 60 describes an ALGOL machine, i .e . virtual computer that has features that correspond to the features in ALGOL 60 . The Burroughs B 6700 computer is one of many that can run ALGOl programs . However, it is to ALGOL 60 what the IBM 7094 is to FORTRAN . That is, its hardware has a close correspondence to the virtual hardware of the ALGOL computer described by ALGOL 60.
    Extract: Vice versa
    Vice versa
    To invert the previous argument, a list of the order codes for a computer defines a programming language based on those order codes . The simplest such programming language is an assembly - type language, where there is one order code in the language for each order code in the computer's hardware . For example, starting with the IBM System/360, the simplest programming language defined by the machine's hardware is something similar to BAL. The major difference between this simple programming language and BAL is the lack of a macro facility . The defined language may come in several syntactic flavours, without altering the fundamental semantic equivalence between the language and the hardware.
    Examples of such syntactic flavours are (for the IBM System/360):
    GO TO LABEL instead of BC 15,LABEl
    REG6 := A INDEXED BY REG9 instead of L 6,A(9 )
    These variants are fundamentally equivalent, though some of them tend to be more readable than others . Clearly, starting with a virtual computer with virtual hardware that is like the FORTRAN machine mentioned above, the language that the machine will define will be quite similar to FORTRAN . Similarly, a virtual machine like the ALGOL machine defines an ALGOL-like language.
    What all this has to do with job control languages?
    Barron and Jackson have observed that " . . . modern job control languages are akin to programming languages . "1 In particular, they have compared IBM's OS/360 JCL to an assembly language, and ICL's GEORGE 3 command language to an autocode.
    I have previously stated that programming languages describe a computer, in some cases a real computer and in some a virtual computer . What, about job control languages, then? As with other programming languages, the order code of a job control language defines a virtual machine . These order codes usually include : an order code which announces a new job ; an order code which allows the user to execute a program (that program may be a compiler, a utility program, or a user-written program -- all programs are equal, but manufacturers insist that some programs are more equal than others) ; an order code to equate the names of two files ; and an order code to announce the end of a job . These order codes are all commands to various parts of an operating system : the order code announcing a new job is a command to the scheduler ; the order code calling for the execution of a program is a call on both the scheduler and the loader ; the order code to equate the names of two files makes entries into tables for use by the input/output supervisor ; and the order code announcing the end of a job is a command to the scheduler . (The parts of the operating system which are called may well vary from system to system ; however, the examples given are probably not too far from what happens in most modern operating systems) . Hence, the machine that a job control language describes is an operating system . On the overwhelming number of computers in existence today, the operating system is a piece of software, i .e . the operating system is a virtual machine implemented on a real computer.
    Extract: A suggestion for a job control language
    A suggestion for a job control language
    Rain has defined a machine orientated language as one where the " . . . programmer is able to exploit particular characteristics of an implementation (e .g . special hardware instructions) directly from the language ." 2 It is worth nothing that this definition does not restrict the language to only have those constructs that are in the hardware.
    Given that the operating system of a computer is a virtual machine, it is reasonable to talk of a machine orientated job control language . The MARY language has recently demonstrated that a machine orientated language need neither be a low level language nor non-portable . The same thing should hold true for job control languages . Job control languages, which are, after all, machine orientated languages (the machine being a virtual one : the operating system), need not be assembly-like languages (as with IBM's OS/360 JCL) . They need not be autocode-like (as ICL's GEORGE 3 command language) ; there should be a way to design a high level, portable job control language . The problem of designing such a language is equivalent to the problem of designing a high level, portable, machine orientated language for a real computer ; the only difference being that the machine for which the job control language is orientated is a virtual machine.
    Extract: Where to go from here
    Where to go from here
    Basically, it is now time to go to the drawing board and start designing the "job control language to end all job control languages" . Some features which might be desirable for the language are : loops (an extended form of ALGOL 68's loop structure); the ability to name, assign values to, and test variables ; an extension of the two-value logic system to three values (true, false and maybe) ; and, perhaps most important of all, userfriendliness, i .e . reasonable defaults (for example, boolean variables initialised to maybe), readable programs (EXECUTE USERPROGRAM 4 instead of // EXEC PGM=USERPROGRAM4), and other like luxuries that everyone has gotten used to in programming languages but don't have in job control languages.

          in SIGPLAN Notices 8(03) March 1973 view details
  • Rain, M. "Operator Expressions in Mary", view details Abstract: The programming language MARY is a portable machine-oriented language derived from (and a functional superset of) Algol 68. It has a key design criterion which requires that there be a clear and constant relationship between statements in MARY and corresponding emitted machine code. Succinctly, what you write is what you get in MARY. This requirement permits easy machine level programming from the context of, and with all the power of, a quite high level language.
    In practice, this criterion prohibits those constructs which in other languages prevent a simple statement-code mapping, and requires additional constructs which permit easy, high level notation for routine assembler constructions.
    As an example of prohibited constructs, MARY is unlike other high-level languages (with the notable exception of APL) in that it has no operator precedence . All operands are evaluated from left to right, as in Algol 60, and in addition all operations are applied in strict left-to-right order as well, unless overriden by explicit parentheses. This absence of priority requires left-to-right assignment, and monadic operators in suffix notation. Thus Algol 60's :
    I :=-(J*(K+L) )
    becomes in MARY
    K+L'J-= : I
    or, in assembler terms,
    Load K
    Add L
    Mult J
    Complement
    Store to I
    The new constructions required in MARY are various. This paper
    discusses one, the MARY solution to the problem raised in the
    introduction.
          in SIGPLAN Notices 8(01) January 1973 Proceedings of the 1973 SIGPLAN/SIGIR Interface Meeting, Gaithersburg, Md., Nov. 1972 view details
  • Rain, M. and Holager, P. "The present most recent final word about labels in MARY" pp24-32 view details Abstract: MARY has now reduced its unconditional transfer of control mechanism to one construct, GO, and one mode, LABEL . With these two, combined with both Algol-like and range naming positioning of labels, both the power of the arbitrary branch and the clarity of the range exit can be easily obtained. In addition, the label variable (indirect jump) and the parameterized jump of assembly languages are available as
    special cases of the general mechanism. DOI Extract: Introduction
    Introduction
    Labels in Algol-like languages are like the dog who stole the hammer and didn't know what to do with the handle - they just don't seem to fit in anywhere comfortably . BLISS and Algolw have banned labels entirely, resulting in programming and execution overhead in some cases (see Wegner, MOLB 1 .2 .1). Algol 68 has retained labels in a sharply restricted form (a label is not a mode, so REF LABEL and ROW LABEL are not produced), which seems to satisfy nobody . Purists are busy showing that algorithm X can be comfortably (if incomprehensibly) coded without labels, while ex-Fortran programmers the world over produce octopus programs galore.
    History of labels in MARY
    Enter MARY . One author (Rain) had had experience with an Algol with excellent looping facilities (Burroughs B6700 extend Algol), and loathed labels as much as the next man, yet had already found instances where the looping facilities were insufficient to the task . The examples were not so elegant as Wegner's, but they did require either 1) duplication of program statements, or 2) superfluous BOOLEAN variables, or 3) labels.
    For a Machine Oriented Language like MARY, choices 1) and 2) above are eliminated on the grounds of efficiency . Therefore, MARY has labels . However, we wish to avoid octopi, so labels are made (deliberately) slightly annoying to use . This is accomplished by requiring that all labels must be declared (as "LABEL L,Ll,L2,") textually before any occurance in GO's ("GO L") or positioning ("L : IF °--") . While this declaration is not essential to our compiling technique, it was added as a weapon of the psychological warfare practiced by us, the language designers, upon the unsuspecting user.
    At the time when labels were introduced into MARY we were unfamiliar with BLISS . If BLISS with its range-exiting constructs had been available it is possible that MARY would not have had labels of the Algol sort . By the time it became familiar we had discovered that our labels were insufficient in systems programming work.
    Extract: History of labels in MARY
    History of labels in MARY
    Enter MARY . One author (Rain) had had experience with an Algol with excellent looping facilities (Burroughs B6700 extend Algol), and loathed labels as much as the next man, yet had already found instances where the looping facilities were insufficient to the task . The examples were not so elegant as Wegner's, but they did require either 1) duplication of program statements, or 2) superfluous BOOLEAN variables, or 3) labels.
    For a Machine Oriented Language like MARY, choices 1) and 2) above are eliminated on the grounds of efficiency . Therefore, MARY has labels . However, we wish to avoid octopi, so labels are made (deliberately) slightly annoying to use . This is accomplished by requiring that all labels must be declared (as "LABEL L,Ll,L2,") textually before any occurance in GO's ("GO L") or positioning ("L : IF °--") . While this declaration is not essential to our compiling technique, it was added as a weapon of the psychological warfare practiced by us, the language designers, upon the unsuspecting user.
    At the time when labels were introduced into MARY we were unfamiliar with BLISS . If BLISS with its range-exiting constructs had been available it is possible that MARY would not have had labels of the Algol sort . By the time it became familiar we had discovered that our labels were insufficient in systems programming work.
    Extract: Label variables
    Label variables
    An assembly language programmer frequently makes use of a data cell in which a program address has been stored, in order to effect an indirect jump to a label . If the contents of this cell is modified during the course of execution, the cell is logically a label variable, that is, a datum which can take as its value one out of a number of program entry points, or labels.
    Such label variables are routine in assembly coding . High-level languages (with the notable exception of Fortran) force the simulation of a label variable by use of an integer variable and a case statement or switch . Algol 68 and other languages (including MARY) with procedure variables can in some instances also provide the effect by a procedure variable.
    However, the mapping onto case statements or proc variables is quite expensive compared to the simple indirect jump of assembly languages . MARY, as a high level assembler, needed the efficiency but also need some measure of control over the construct . The wild address problem for data is taken care of by the introduction of REF variables (pointers) and rigid mode checking . By analogy, the wild address problem for branches can be taken care of by introducing a 'label' mode and ensuring that objects of that mode only contain values of that mode.
    The mode was called ENTRY, and was a genuine mode
    REF ENTRY,
    ROW ENTRY and so forth were produced . Label constants (ordinary Algol labels) were still declared as before, but the label so declared had a mode of VAL ENTRY, meaning that it was a program position and could not be changed by assignment (see Algol Bulletin 34 for a discussion of VAL) . Normal data declaration rules held for ENTRY data, and they could be used in expressions:
    LABEL L,Ll;
    ENTRY E : = Ll;
    GO L := :E;
    GO Ll := :E;
    L:
    Ll:
    The ' :_ :' operator stores the left hand value into the right hand address, and yields as a result the former right hand value, effecting a register-to-core swap . Thus this code alternates control between the two labels in coroutine fashion.
    Extract: Range exiting constructs
    Range exiting constructs
    ENTRY data proved sufficiently useful that even when the BLISs exiting constructs were available we retained labels in MARY. However, we noticed that, while MARY' s good looping structure eliminated most labels called 'LOOP' or 'BACK', there were still a lot with names like 'XIT' and 'FIN' . Examination showed that the largest use of labels remaining in MARY was to provide branch points at the end of routines . Consequently, we adopted the BLISS routine exiting mechanism,
    RETURN X+Y
    which generates a jump to the end of the procedure, with the expression value 'X+Y' to be yielded as the value of the function. The expression is omitted if the procedure yields VOID, i .e . is typeless.
    This RETURN mechanism follows BLISS in exiting the surrounding procedure, rather than the practice of MARY's nominal parent Algol 68 . Algol 68 has a completer which will cause exit from the surrounding range . However, in all cases for the completer to be useful, it must be followed by a label, and the program must contain a conditional to that label:
    MARY:
    IF A=0 THEN RETURN X+Y FI;
    Algol 68:
    IF A=0 THEN GO L Fl;
    X+Y EXIT
    L:
    because the natural Algol 68 form
    IF A=0 THEN X+Y EXIT Fl
    does not do at all what you think it will . Thus Algol 68 forces the use of extra labels - a serious design flaw.
    Extract: Declared ranges
    Declared ranges
    The introduction of named ranges as advocated by Wegner and implemented by BLISS introduces still another complication in the syntax for control of program flow : one LEAVEs ranges, GOs to labels or ENTRY data, and possibly still RETURNs from procedures . While ranges are a good idea, a plethora of methods for performing the same function is the hallmark of languages which have been built by the million monkey approach . MARY is an integrative, at times elegant language, so we sought a method for reducing this multitude to its essentials. This has been done, and the new MARY performs all functions as before, and some new ones, while lacking the words ENTRY and RETURN . The mechanism is as follows.
    Extract: The generalized LABEL
    The generalized LABEL
    LABEL is now a mode constructor, like REF and ROW . Thus "LABEL INT " and "LABEL VOID" are instances of mode . They define the mode of a datum which names a program position at which a value of the dependent mode ("INT" on "VOID") is expected . That is, whatever preceeds the position of label should yield the dependent mode.
    "LABEL VOID" may be contracted to "LABEL".
    Label variables (the old ENTRY mode) may now be declared in normal fashion:
    LABEL E :=NIL;
    LABEL INT EI :=NIL;
    Label mode data (like other dangerous modes) must be explicitly initialized in the declaration, as " :=NIL" in the example . If this initialization is omitted, as in
    LABEL L;
    it is assumed that the declaration is a contraction of
    LABEL L=SOMEWHERE;
    where the "SOMEWHERE" is indicated by conventional positioning:
    L : IF °- °
    Thus Algol-like labels (the old LABEL declaration) are still declared, or rather forewarned, which it is hoped will still be annoying to the user . Their mode is LABEL and their status is VAL, as indicated by the implied "=" in the declaration.
    This form of declaration results in no code and no data allocation.
    A VAL LABEL declared in this fashion must be initialized by positioning within the scope of the declaration . VAL LABEL's which occupy data space may also be obtained by ordinary identity declarations
    LABEL EEL;
    which does allocate data space and produce code to store "L " into it . This label constant in the data is in fact quite useful on machines (such as ours) with a limited jump addressing range, as well as for conventional uses as part of structures, etc.
    Extract: The generalized range
    The generalized range
    Ranges are introduced by permiting an alternate form of positioning . At the start of any range, a label can be specified in a range position:
    BEGIN
    &R:
    IF °
    where "R" is declared at this point with a mode of VAL LABEl 'of some mode, probably VOID> and is positioned just before the end of the range . Thus the above is equivalent to:
    BEGIN VAL LABEL R;
    IF °
    R : END
    Labels positioned in this way are used in the same manner as LEAVE with declared ranges . No other declaration is required, as we wish to encourage this use . The mode of a label which names a range in this way is VAL LABEL yielding a specified value:
    BEGIN & RI TNT:
    END : I;
    makes "RI" have a mode of VAL LABEL VAL INT. The full syntax of a range positioning is range positioning : range symbol, proposed range denotation identifier option, mode option, position option, position symbol.
    (&XREG :, I)+2
    The identifier, if present, names the range and may be used with GO's (described below) to exit the range . The mode option, if present, specifies that the range is to yield a value of the specified mode, and the identifier has a mode of VAL LABEL VAl . If omitted, the mode yielded by the range (and possessed by the range denotation) is determined by the textually first value given when exiting the range, in empty context. This mechanism is used at present to determine the mode yielded by CASE and IF clauses in MARY, in lieu of the balancing mechanism of Algol 68.
    If the position option is present, all values yielded by the range will be yielded in the given position . Thus will load "I" to "XREG" for later use in the expression . This is useful to obtain special register effeciencies. The range symbol ("&") and the position symbol (" :") are required to eliminate ambiguities.
    Lastly, as the most common ranges to exit are the bodies of procedures and do clauses,MARY specifies that all routine displays automatically declare a range label named "ROUTINE" at the start of the routine body, and all do clauses automatically declare a range label named "LOOP" at the start of the clause. Extract: The generalized Go
    The generalized Go
    The only mechanism for transferring control now is the GO. GO has become an operator, which takes a label as right operand and some value as left operand.
    For example,
    "5 GO RI ; "
    The left operand is evaluated to yield the value to be passed to the position of label . The right operand yields the label to be jumped to . Thus in
    BEGIN & RI:
    IF A=0 THEN 5 GO RI FI;
    10 END= :i
    The "5 GO RI" specifies that control is to be passed to the "END " (indicated by the position of "RI") and the "BEGIN"-"END" closed clause should yield a value of 5 to be stored into "I", if this GO is taken . In this example, the dependent mode (i .e. the mode yielded) is not specified at the declaration of RI, but, at the textually first GO-to-this-label, it is set to the mode of the GO's left hand expression in empty context.
    There are two useful contractions permitted : the left operand may be omitted if it is to yield VOID ("NIL GO" may be replaced by "GO"), and the right operand may be omitted if it specifies exiting the surrounding procedure body ("GO ROUTINE" may be replaced by "GO").
    The omission of a void left operand has been generalized to all operators, so
    OP XYZ(VOID A,VAL INT B) $,
    XYZ(VOID A,VAL REAL B)= ---- $,
    may be invoked as:
    XYZ 5= :i
    XYZ 5 .0= :X;
    and
    Omitting the right operand is equivalent to a monadic operator. Thus the standard prelude declarations for GO are:
    MODE M;
    OP GO(VAL M A,PRIMARY VAL LABEL VAL M B)=$,
    GO(VAL M A)=A GO ROUTINE$;
    Thus all possible combinations are meaningful and useful:
    GO
    exit a typeless procedure
    5 GO
    exit a typed procedure, yielding 5
    GOl
    jump to a label which does not expect a value --
    normal Algol go-to
    5 GOl
    jump to a typed label
    The last example above has been illustrated by exiting from a range which does not yield'VOID . However, it may be applied to regular labels as well . The following is now (but not formerly) legal MARY:
    BEGIn
    VAL LABEL INT LI;
    5 GO LI;
    10 LI : +I= :J;
    END;
    which does what you would expect . This maps, in a natural fashion, the common assembly technique of loading a value into a communication register and then jumping to code which uses that value.
    Extract: Postlude
    Postlude
    Civilizing our labels has been a long, hard fight . Our first internal note on the subject had the very reasonable title "Labels" . Since then, we have had "Revised Labels", "The Final Word about Labels", "The most recent Final Word about Labels " and now the present work.
          in SIGPLAN Notices 8(03) March 1973 view details
  • Conradi, Reidar, and Holager, Per; "MARY Textbook" University of Trondheim, Programming Languages and Compilers Group, RUNIT Report (July 1974). view details
          in SIGPLAN Notices 8(03) March 1973 view details
  • Rain, Mark "Mary Programmer's Reference Manual", R Unit, Trondheim (1974). view details
          in SIGPLAN Notices 8(03) March 1973 view details
  • Russell, Robert D. "Experience in the design, implementation and use of PL-11, a programming language for the PDP-11" pp27-34 view details Extract: INTRODUCTION
    INTRODUCTION
    PL-II is a programming language for the PDP-II
    family of computers designed and implemented as
    part of the OMEGA Project at CERN (the European
    Organization for Nuclear Research). Its purpose
    is to provide an effective tool for both physicists
    and systems programmers to use in building
    real-time data acquisition systems that are online
    to high-energy physics experiments. It is a
    fairly typical member of the PL-class of programming
    languages (44) which are based on the initial
    design of PL360 (41) (see Table i). Each of these
    languages represents a linguistic model of its
    specific machine architecture, thereby providing
    a Systems Implementation Language (SIL) that is
    extremely efficient on its target machine, yet is
    also highly effective for human programmers to
    use. The need for such a tool is obvious on all
    computer systems, but especially on minicomputers,
    where most applications are in fact "systems
    programs". For example, in any data acquisition
    environment the distinction between "user" and
    "operating system" largely disappears--the user's
    prime concern is to handle time-dependent
    sequences of events involving the manipulation
    of special I/O devices through direct status
    checking and data streaming--all functions which
    are usually buried in the operating system of
    conventional computing systems.
    This paper discusses four years of experience
    with PL-II, especially as this relates to the
    general topic of SILs on minicomputers. Extract: Program Development Systems
    Program Development Systems
    In July, 1971, the OMEGA Project computing facility (34) was defined as one central medium-sized computer (XDS Sigma 7) and several on-line minicomputers (PDP-II/20), one per experimental grouP using the OMEGA magnet and detector system. This design concentrated the computing power in one big machine, yet permitted each experimental group maximum flexibility and independence through the use of its own minicomputer for setting up, debugging, and driving all its own on-line electronics. In order to keep costs low, each minicomputer was a "bare" machine-- 8K core, paper tape I/O, and teletype. With no disk or magnetic tape, programdevelopment on the minicomputer itself was unfeasible, and with the conve~ientavailability of the more powerful Sigma 7 it was also unnecessary. Therefore the PL-II compiler was implemented as a Fortran program running on the Sigma 7.
    The output of a compilation is a relocatable object module in the format accepted by the Sigma 7 linkage editor. Any number of PL-II modules can be compiled separately, stored in libraries on the Sigma 7 disks, and then linked together on the Sigma 7 to produce an absolute core image. In the early stages of OMEGA operation, this core image was punched onto paper tape and carried to the nearby PDP-II's for loading and execution. Later a high-speed (one megabyte) computer-to-computer data link was established that enabled the PDP-I1 to be loaded directly from the Sigma 7, obviating the need for paper tape.
    This method of program development for minicomputers proved to be an extremely productive one. The advantages are obvious--all program development tools available on the big machine are available "free" to the minicomputer user. Most large systems, such as the Sigma 7, represent a considerable investment by the manufacturer in development tools, such as file system capabilities, library processors, linkage editors, etc., that are orders of magnitude more powerful and easier to use than the support software (if any) provided with the minicomputer. Furthermore, enhancements to the central system, automatically benefit the program development process for the minicomputer user, and it is often easier to justify expenditures for such improvements to central systems. For example, the ORION system (36) developed for the OMEGA system enabled the minicomputer programmer to write, compile, debug and use programs for either the PDP-II or the Sigma 7 or both without ever leaving the teletype of his minicomputer. With program development unified to this extent, the user has to learn only one set of control cards and/or commands for one set of compiling, linking and loading facilities. This in turn encourages him to utilize the power of the linked system without going through the agony of learning a maze of contradictory details for two different systems.
    In 1974 the PL-II compiler was rewritten in itself to run on the PDP-II. This made PL-II available to PDP-I1 users that did not have convenient access to a large Fortran machine, and enabled them to use a PL-II compiler with the DOS and RSX operating systems for the PDP-11. The Fortran version of the compiler was modified to produce relocatable object modules in the DOS/RSX formats (in addition to the Sigma 7 format), but the problems of transporting these modules to machines not connected by data links were unexpectedly nontrivial, due primarily to the lack of a single common storage media that could be handled easily by both systems (at that time, RSX-IID did not support paper tape). Extract: Language Design
    Language Design
    The primary aim of PL-II was to become the single language for all programming on the OMEGA Project PDP-II's. In order to satisfy the demands of systems programuners, the language had to allow programmer access to all features of the hardware and the I/O devices. In order to satisfy the demands of physicists who were writing the data acquisition programs, the language had to have high-level structures typically found in most applications-oriented languages, such as Fortran. A con~mon technique for achieving such a goal is to implement a restricted subset of a highlevel language (a popular choice today is PL/I), but although this was considered the following are reasons why it was rejected as a viable approach for a minicomputer SIL.
    Many high-level languages ass%tme the existence of a run-time support system to provide a convenient environment for the progran~er. In particular, storage management, data formats and conversions, interrupt control and I/O device control (or lack of it) are implied parts of almost all highlevel languages today. But it is precisely for explicit programming of these tasks that we are designing the minicomputer SIL in the first place. Even assuming we could tolerate some minimal runtime package written in assembler, most highlevel storage management schemes, and especially the manner in which I/O devices are treated in high-level languages, are totally inappropriate to the realities of minicomputer hardware. Explicit interrupt management is essential to the data acquisition prograrmner, but what highlevel language accurately models the existing hardware interrupt structure of today's minicomputers?
    Data acquisition systems in particular often contain modules that must respond to interrupts and non-standard I/O devices in a highly time-dependent manner. In such circumstances even innocuous conventions in the progra~aning language, such as the automatic saving and restoring of all registers on each subroutine entry and exit, may be too time consuming, since few minicomputers have a single "save status" instruction. This convention may also be totally inappropriate, since only a few of the registers may be used in the interrupt service module. For example, the incredible expense of subroutine entry and exit in the PDP-II version of the SUE language (22) could never be tolerated in a high-energy physics experiment where the computer is alreadythe slowest piece of electronics in the data acquisition system.
    In addition to the advantage of programmer familiarity with the language, upward compatibility and portability can be claimed for programs written in the language subset. It would seem, however, that many minicomputer applications, especially data acquisition systems, are dedicated systems with low probability of ever being transported to another computer, since then many of the non-standard I/O devices would have to be redesigned as well. Furthermore, most minicomputer programs are designed to be aware of their real-world environment and respond to it in a highly context dependent manner. They are often tailored to a specific hardware configuration in which generality must be sacrificed in order to "fit" into the minicomputer. It is, therefore, unrealistic to expect that one would place a ~igh premium on getting the same program to run on another computer with a totally different environment.
    Many of the data structures and data referencing techniques employed in today's high-level languages are inappropriate to minicomputer hardware. In this regard the PDP-II with its eight hardware addressing modes is a particularly good example. Use of this rich set of addressing modes requires data structures and access algorithms that refer to data items, whether of the same type or not, through pointers that are incremented and decremented in a sequential fashion. Furthermore, these pointers must be maintained in registers if code size and execution speed are to be minimized.
    Conventional high-level language indexing techniques do not map well onto this aspect of the PDP-II hardware. Neither do the Pascal-style (42) field-selector techniques in which items within a structure are referenced by symbolic offset names. Therefore new high-level access techniques must be developed. But then the "subset" is no longer a true subset, since it contains language extensions, and programmers using both the original and the augmented subset languages will find the differences frustrating. Hence the intended "benefits" of subsetting (familiarity, upward compatibility, etcetera) are lost anyway.
    A final important consideration is the time and effort expended in implementing the SIL, since for most projects, especially minicomputer projects, producing the programming language is not the primary objective. Rather than spending inordinate amounts of effort trying to implement a subset of an existing, rigidly specified language that may not map well onto one's hardware, the language designer will have a much easier task if all aspects of the language specification are flexible. The first version of PL-II was in the hands of users within four months of its inception, including the first version of the user's manual (35), and this early availability was much more important to user acceptance than any fancy language features it might have contained, since development and test of both the software and the user-built I/O devices for the minicomputers could not proceed very far without the programming language. There is little benefit in producing a super tool after completion of all the tasks that might have used the tool. Extract: The PL-11 Language
    The PL-11 Language
    PL-11 was designed as a "new" language, but one modeled closely after PL360 (41). As can be seen from the sample program in Figure i, it is a typical example of the many PL-type languages based on PL360. All machine registers have symbolic names that are visibleto the programmer, and they must be explicitly allocated and operated upon by the prograImner. The language provides a static block structure with name scoping very similar to ALGOL 60's. All variables must be declared of a certain type, and they can be accessed symbolically only within the scope of the block containing their declaration. The storage allocated to a variable is assigned at compile time, and is permanent for the life of the program. Hence any variable can be initialized, and will retain its most recently assigned value across block or procedure exit and reentry. In this sense variables are automatically the "static own" variables of ALGOL 60. Constants can also be given symbolic names through declarations.
    Procedures can be declared in any block, and can be nested to any depth. Provision is made for defining GLOBAL procedures and data segments, and for referencing EXTERNAL procedures and data segments symbolically. Thus many separately compiled PL-11 program modules can reference each other and their common data segments symbolically. Each PL-11 module is compiled into relocatable binary form, and the interface conventions permit PL-11 modules to be linked with modules written in PAL-I1 or Fortran as well as PL-11. The highlevel control structures include IF - THEN, IF - THEN - ELSE, FOR, FOR - WHILE, WHILE, and CASE, all of which can be nested to any depth in any combination. GOTO's and labels are also permitted. Expressions are very low-level and are evaluated strictly left to right, including the assignment operator (=>), with no parenthesization or operator hierarchy. Dyadic operators are written in infix notation, monadic operators in postfix, and all operators map onto the machine instruction set in an obvious manner (Table 2).
    Table 3 lists special expressions that are mapped by the compiler onto single hardware instructions. All variables are typed, and no mixed-mode operations, except for assignment, are allowed, since the hardware does not support automatic type conversion. ~ The only data structures provided are linear arrays and stacks, and all subscripts must be a register and/or a constant, again due to hardware limitations.
    The above features, with minor variations such as the left-to-right assignment operator, are generally con~non to all PL-type languages, whereas the following appear to be unique to PL-11. PL-11 does not allow the progranuner to include any "inline" assembly language instructions, since all PDP-II instructions are representable in the syntax of the language. Any expression consisting of all constants (whether symbolic or not) is evaluated at compile-time. This feature is extremely useful for parameterizing programs without losing run-time efficiency, and is one found in almost all assemblers (where it is used primarily for address calculation), but is absent from almost all hlgh-level languages for no apparent reason other than oversight. In addition to regular procedures, interrupt procedures can be defined for any kind of hardware or software interrupt or trap.
    In order to simplify the interface between the on-line minicomputers and the experimental electronics, CAMAC, the international standard for interfacing electronic components (12), was adopted for all equipment used in the OMEGA Project. Presence of a standard interface enabled us to incorporate the conventions for using that standard into the syntax of PL-11. These features enable programmers to give symbolic names to CAMAC variables and functions, and then to utilize these names in the same manner as normal variables and functions. The physicist can therefore program operations on his external electronics in an extremely simple, obvious manner, yet the code generated by the compiler is exactly what is needed to drive the CAMAC interface--there is no efficiency loss.
    Through the use of compiler control cards placed in the input deck the programmer can control pagination of his program listing (another feature regrettably lacking in most high-level languages) and the particular object-time hardware configuration on which the compiled code is to run (which model PDP-II, what extra hardware it has, such as floating-point, and which type of CAMAC interface is in use). In addition, the INCLUDE control card allows symbolic PL-11 source statements from other files to be included anywhere in the deck. Thus procedure libraries and/or data base definitions can be incorporated symbolically at compile-time, as well as at link-edit time as in more conventional systems.
          in SIGPLAN Notices 11(04) April 1976 view details
  • van der Meulen, S. G. "ALGOL 68 might-have-beens" pp1-18 view details
          in Proceedings of the Strathclyde ALGOL 68 conference Glasgow, Scotland 1977 view details
  • Rain, Mark "Avoiding Trickle-down Recompilation in the Mary2 Implementation" view details
          in Software — Practice and Experience 14(12) December 1984 view details