'''PL/S''': the internal InternationalBusinessMachines (IBM) '''P'''rogramming '''L'''anguage [for] '''S'''ystems.

It was possible for an adept programmer to do almost anything systemish in an application using IBM PL/I--especially with mature versions of the PL/I Optimizing Compiler--that was possible in System/370 Assembler (IbmSystemThreeSixty): Data overlays? Dynamic program loading? Explicit multitasking? All no problem. But PL/I couldn't be used as a stand-alone systems-programming language. IBM PL/I implementations relied on PL/I run-time routines that interfaced to OS/370 system routines. So IBM couldn't write its operating systems using even its best PL/I compilers; the run-time routines necessary to the compiler wouldn't be available during operating-system development. Thus PL/S, which did not use a run-time library, but could easily embed whatever Assembler code was necessary using the "''@GEN''[''ERATE'']" and   "''@ENDGEN''" constructs, filled an important niche.  PL/S provided access to Assembler macros, and could specify that particular variables were to be assigned to particular S/370 registers.

It might be argued that PL/S was used, to a great extent, for the structured-programming benefits of its PL/I flow-of-control statements, which prevented a whole category of potential errors, and produced a straightforward translation into S/370 Assembler. RealProgrammers at IBM favored the listing options that combined the high-level PL/S code, the Assembler  generated from the high-level code, and the explicitly coded Assembler embedded using "''@GEN''" and "''@ENDGEN''". It really was ''not'' practical to use PL/S as a high-level language whose loftiness excused the programmer from understanding the S/370 architecture and its Assembler.

The straightforward approach to translating PL/S into Assembler code had one especially exasperating consequence: Each PL/S ''structure'' produced an Assembler ''dsect'' (''data section''), which meant that all field (''member''?) names across a single compilation needed to be unique, unlike in PL/I. That is to say, PL/S ''structures'' provided no ''scope''. So every mundane  "size" or "length" field needed to have a unique spelling; if one ''structure'' had a field named "size", any other comparable-purpose field in any other structure needed its own unique spelling--or misspelling--for example: "siz", "sz", or "sze"--a great opportunity for difficult-to-detect errors caused by a programmer's eyes glazing over.

For an academic best-guess from outside IBM about PL/S, see Gio Wiederhold and John Ehrman: "An Inferred Syntax and Semantics of PL/S". Proceedings of the ACM Conference on System Implementation Languages. ''SIGPLAN Notices'', vol. 6 num. 9 (Oct. 1971), p. 111--121.

This might also be an approprite place for another citation: Martin Hopkins: "Problems of PL/I for system programming". ACM 'SIGPLAN Notices'', 6(9), pp. 89-91, October 1971.

----

[A request was edited in for clarification of "PL/S lines of source-code with 'interleaved Assembler code'"]
''What does that mean?''

Please see expanded description above, unless the issue is the meaning of "interleaved".

''The original wording was "with its interleaved"; if you'd simply written "with embedded", the meaning would have been clear, and the explanation unnecessary.''--anon.

Additional explanation still seems necessary after all. What was "interleaved" was not just the ''embedded'' Assembler, the latter adjective describing only what was explicitly coded between "''@GEN''" and "''@ENDGEN''". The compiler also "interleaved" the ''generated'' Assembler code resulting from compiling the high-level PL/S code. As an admittedly contrived example code fragment, hobbled by my fading memory of S/370 Assembler:

  DCL (COUNT, LIMIT, SEMAPHOR) FIXED BIN(31);
  ...
  IF (COUNT >= LIMIT) THEN DO;
    L   R5,COUNT
    C   R5,LIMIT
    BLT *+8
  @GEN;
    TS  SEMAPHOR
  @ENDGEN;
  END;
  /* 'BLT' conditionally branches over 'TS' to here,
  absent an ELSE-part */

'TS' above is intended to be the S/370 atomic ''test-and-set'' MutualExclusion instruction,
for which PL/S had no high-level primitives that I recall. I don't recall whether the compiler would really substitute the compiler-allocated address for the variable name SEMAPHOR in the embedded 'TS' instruction. A more typical--but much longer and more complicated--example would have I/O-macro expansions between "''@GEN''" and "''@ENDGEN''".
--ClayPhipps

----

CategoryProgrammingLanguage CategoryPli