The idea of Pascal-S was to get a small, one step system for students to run their programs on instead of the full blown compiler. In Wirths' world of the CDC 6400 and "big iron" computers, you submitted a program by "batch", and got back results the same way. I.e., your program run consisted of handing a deck of cards to the computer operator, then coming back some time later (perhaps hours), and picking up a listing. The Pascal-S system allowed the job turnaround to be faster, although the cooperation of the operator was still suspect.
I converted the Pascal-S source code to ISO 7185 status, and in doing so eliminated several CDC 6000 dependencies. You should be able to run it on any ISO 7185 compliant processor. Your processor will have to do something with the program header file that represents the source program Pascal-S will compile, however.
The ISO 7185 version of Pascal-S here has been modernized to work with 32 bit processors and IEEE standard 64 bit floating point reals. It also contains extensive documentation on what language it runs, and what is required to get it to compile on your system. All the changes made to the original are well documented in the source. It also contains the instruction 36 "bug fix", documented below.
One common activity I use the program for is to verify ISO 7185 operation for various compilers. You can also do that. If your compiler is able to run the ISO 7185 version of Pascal-S, it is probably a pretty good ISO 7185 compiler. Pascal-S is a non-trivial program that uses most of the language.
Another common activity is to use Pascal-S as a starting point to build your own compiler or compiler-interpreter. However, note that the P4 system might be more appropriate for that, since it processes nearly the full Pascal language.
With the gracious permission of Professor Niklaus Wirth, I have been able to scan and reproduce the original article that introduced Pascal-S here. This article originally appeared in the Series of Technical Reports of the Institut fur Informatik of ETH Zurich, approximately 1972. It reappears here with permission from the author, Niklaus Wirth.
Also, over the years I have used Pascal-S as a test input program for testing compilers, and while debugging it, have found that a "instruction set reference" is handy for understanding the internal workings of Pascal-S. I generated this document, and it appears below. It is, however, not quite complete as yet.
Pascal-S: A Subset and its Implementation. Original article introducing Pascal-S by Niklaus Wirth. Contains the complete, original source of the CDC 6000 version of Pascal-S.
Pascal-S instruction set reference. Document gives an explanation and list of the instruction set used in the interpretation of Pascal-S.
Pascal-S., Pascal subset compiler/interpreter, modified for ISO 7185 use. This file consists of the Pascal-S from Wirths' original article, with minor corrections to run on ISO 7185 Pascal (Pascal-S proceeded the ISO 7185 by at about 10 years). This is the file you want if you are going to compile and run Pascal-S! Don't worry, the changes made are well documented inside the source. You are very unlikely to get the original version to run without the modifications made in this version!
This version runs under Windows/XP or later.
You run it by giving it the Pascal source file you want to run, with extention, as:
> pascals hello.pas
It will compile, run it, and print output, or input from, the console.
In the course of running the test material through Pascal-s, I noticed that certain real values were coming out with the wrong sign, or were entirely wrong.
Examining the source for Pascal-s, I came across an interesting fact. The code for negation of integer or real appears very wrong.
Looking at the code, in simpleexpresion, a code "36" is emitted for negation:
begin (* simpleexpression *)
if sy in [plus, minus] then
begin op := sy; insymbol;
term(fsys+[plus, minus], x);
if x.typ > reals then error(33) else
if op = minus then emit(36)
Note that x.typ is:
types = (notyp, ints, reals, bools, chars, arrays, records);
so x.typ > reals is a test for integer (ints) or real (reals), because it won't be a notyp. So the code 36 is emitted for both negate real and negate integer. Now if you look below to interpret, here is what instruction 36 does:
36: s[t].i := - s[t].i;
The .i part means the integer part of a stack record. Ie., it negates integer. But the operand, on the stack, of instruction 36 could be real !
Now my copy of Pascal-s was actually typed in from the original article by Wirth on Pascal-s, of which I have a copy via D. W. Barron's "Pascal: The Language and its implementation". I typed that in quite a few years ago. I note that some other, original copies have appeared on the net (the above site also lists one). Anyways, I figured there was probably some error. I could not believe that Wirth, a very careful (and clever) programmer would have an undiscovered bug in his code. Further, Pascal-s was used by hundreds of programmers in universities for simple Pascal work back in the 1970's.
Examining the original Wirth article carefully, there appeared to be no error in copying it. The original code had the "bug" in it as well.
Unwilling to simply declare it to be a bug and fix it, I began to think about what I knew about the CDC 6000 series computer, and looking at some CDC 6600/6000 reference material. The CDC has a very unique floating point format. The CDC 6000 uses 60 bit words for both integer and floating point formats. In fact, a floating point number is essentially the mantissa, represented by a 60 bit signed integer, with the exponent stuck into the high order bits between bit 48 and bit 59. The exponent even is allowed to appear as the complement of itself so that it remains valid if the entire number is complemented (the CDC 6600 used 1's complement numbers).
The result is that a negate instruction works equally well on both real and integer formats, on the CDC 6600 series computers.
Now the declaration of a stack operand in Pascal appears as:
s: array [1..stacksize] of (* blockmark:
record case types of (* s[b+0] = fct result *)
ints: (i: integer); (* s[b+1] = return adr *)
reals: (r: real); (* s[b+2] = static link *)
bools: (b: boolean); (* s[b+3] = dynamic link *)
chars: (c: char); (* s[b+4] = table index *)
notyp, arrays, records: ()
I.e.., its a variant record, which means that all of the different types overlay each other in memory. In fact, since all of these objects appear as single machine words (60 bits in the case of the CDC 6000), these are different forms of a single machine word.
The result was that there did not need to be a different form for negation on real or integer values. Only one type of negate was needed. Hence the code was correct - but only for the CDC 6600 series computers. On any other computer the identical, and correctly compiled code, yields the incorrect result, which could be anything from the wrong sign to total data corruption, since the wrong data type is being manipulated.
Wirth probably forgot about this feature of Pascal-s. It is mentioned nowhere in the original Wirth written Pascal-s document.
Hows that for a weird code dependency ?