4

The BESM-6 Pascal compiler I'm experimenting with has a notable difference from Standard Pascal: formal arguments of formal parameters-procedures or functions are not specified, but are checked at runtime:

 PASCAL COMPILER 15.0 (15.02.82)
 00001    1  0 PROGRAM MAIN(OUTPUT);
 00007    2  1 PROCEDURE P(FUNCTION F:INTEGER);
 00007    3  3 BEGIN
 00015    4  3   WRITELN(F(P));
 00036    5  2 END;
 00037    6  1 FUNCTION F(I:INTEGER):INTEGER;
 00037    7  3 BEGIN
 00045    8  3   F := I + 5
 00045    9  2 END;
 00047   10  2 BEGIN
 00050   11  2   P(F);
 00072   12  0 END.

Here we pass an integer function F to the procedure P and we attempt to call it with a procedure argument, whereas it accepts an integer argument and returns it incremented by 5 (e.g. in case of WRITELN(F(5)), 10 would be printed.

The compilation succeeds, and at runtime the following happens:

 FORMAL PROC CALL ERROR
 FOR 1 PARAMETR CALL FROM 001032

 PASCAL PM DUMP
      9 STACK LENGTH.  NAME=       P.LINE=3

   3586 STACK LENGTH.  NAME=    MAIN.LINE=12

 PASCAL PMD END

I've been able to verify that actual parameters are checked for number and for "severe" type discrepancies. E.g. passing CHAR to a function which accepts INTEGER succeeds, but attempting to pass a procedure instead of an integer fails.

Standard Pascal would not accept the code as written; it requires the formal parameter prototypes to be declared the same way as in actual definitions, like

   PROCEDURE P(FUNCTION F(I:INTEGER):INTEGER);

and all type checks are done at compile time.

Naturally, skipping compile-time type checks was done to reduce the size of the compiler at the cost of speed of the execution. Is it the way it was routinely done in the pre-standard Pascal compilers, or was it a corner cut specifically in the BESM-6 implementation? (A slight hint to the latter is the spelling error in the word PARAMETER which mirrors the Russian spelling ПАРАМЕТР.)

  • 2
    What exactly do you mean by "pre-standard" Pascal compilers? Compilers with non-standard additions were common after the standard was defined. FWIW early versions of Turbo Pascal dealt with this issue a different non-standard way: procedures and functions could not be passed as parameters. – alephzero May 10 at 8:29
  • @alephzero Pre-ISO 7185:1983. – Leo B. May 10 at 8:39
  • 2
    Actually, I would think that compile-time type checks would have been much simpler to implement than runtime checks. I don't think they "cut corners" here. At compile time, the compiler needs to have the types on hand anyways. It looks to me as if procedural parameters were an afterthought in the compiler that was added later as a "backpack" – tofro May 10 at 8:49
  • @tofro Real-world Pascal needs to call procedures and functions not written in Pascal. In general you can't describe the syntax of such calls within the spirit of the Pascal standard (e.g. an external procedure may have variable number of arguments). So for practical purposes, deferring checking till run time, and therefore having no checks on calls to external procedures, is a reasonable compiler design compromise. – alephzero May 10 at 10:38
  • @alephzero: Except that for external procedures in, say, UCSD Pascal, there were no runtime checks because no type information was available at runtime (at least in the UCSD p-Code variant I'm familiar with). So it's not a "compiler design compromise", and it doesn't "reduce the size of the compiler at the cost of the speed of the execution"; it just skips the normal Pascal compile-time type checks because for some arguments to external procedures this makes sense. – dirkt May 10 at 10:49
5

Pascal compilers/runtimes typically do some (very often, optionally, enabled by a flag) run-time type checking. A very typical run-time check supported by most Pascal compilers is array bounds checking, because it is the most common type-related mismatch error in Pascal programs and bounds of actually used array indices are very hard to check at compile time against actual sizes.

Checking procedural parameters at compile time, on the other hand, is actually relatively easy (or, rather, not conceivably more difficult than what the compiler needs to do anyhow) - Because you can call any procedure or function directly (i.e. not across a procedural parameter redirection), it's type and formal parameters must be in some symbol table anyhow - It is relatively easy to check whether such an actual parameter fits the function's formal parameter - If the compiler is cleverly built, that is simply a comparison between two symbol table entries.

Regarding your terminology: In my book, "standard Pascal" is what Wirth published in Pascal User Manual and Report - and was later standardized (unchanged in contents, but rather only formalized) as ISO 7185:1983. So, you simply cannot say that there ever was a thing like a "pre-standard Pascal compiler".

If you look at what Wirth provided in terms of implementations, there were actually two: A CDC compiler that supported procedural parameters and a P-code compiler that didn't.

  • Any compiler implemented before the ISO standard was adopted in 1983 is pre-standard by definition. As you say, the P-code compilers didn't support procedural parameters; do you know if they had runtime type checks? – Leo B. May 12 at 6:42
  • I could not find diagnostics mentioning mismatched parameters in homepages.cwi.nl/~steven/pascal/pint.p – Leo B. May 28 at 8:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.