7

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.

In his book Systematic Programming: An Introduction, Wirth provides a syntax diagram

diagram

and an example

example

using the syntax accepted by the BESM-6 Pascal compiler. It appears that the compiler author was following the book quite closely; are there any extant compilers accepting that syntax?

10
  • 3
    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
    Commented May 10, 2019 at 8:29
  • @alephzero Pre-ISO 7185:1983.
    – Leo B.
    Commented May 10, 2019 at 8:39
  • 3
    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
    Commented May 10, 2019 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
    Commented May 10, 2019 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
    Commented May 10, 2019 at 10:49

1 Answer 1

6

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.

4
  • 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.
    Commented May 12, 2019 at 6:42
  • I could not find diagnostics mentioning mismatched parameters in homepages.cwi.nl/~steven/pascal/pint.p
    – Leo B.
    Commented May 28, 2019 at 8:07
  • It is now my belief that dynamic type checks were a "feature envy" hack to add support of procedural parameters to a compiler ported using P-series to minimize disruption to the compiler proper, and to keep its code size to a minimum.
    – Leo B.
    Commented Jun 7, 2021 at 7:03
  • It appears that the syntax has been taken directly from a Wirth's book. Please see update.
    – Leo B.
    Commented May 10, 2022 at 22:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .