Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-crg!lll-lcc!pyramid!decwrl!magic!ehs From: ehs@magic.DEC.COM (Ed Satterthwaite) Newsgroups: net.lang.mod2 Subject: Re: ETH Modula2 Single Pass Message-ID: <1189@magic.DEC.COM> Date: Thu, 25-Sep-86 16:51:32 EDT Article-I.D.: magic.1189 Posted: Thu Sep 25 16:51:32 1986 Date-Received: Fri, 26-Sep-86 20:15:20 EDT Reply-To: ehs@magic.UUCP (Ed Satterthwaite) Organization: DEC Systems Research Center, Palo Alto Lines: 65 In-Reply-To: <5@f.gp.cs.cmu.edu> --------- On the handling of forward references: While working for Xerox PARC, I had access to a one-pass Modula-2 compiler. It was written in Cedar (= Mesa + garbage collection), but Juerg Gutknecht, its author and one of Wirth's associates in Zurich, claimed that the front end was just a transliteration of the ETH one-pass design. The language rules were indeed bent to allow one-pass compilation. One could argue, however, that the cited rule on forward references (special case #1, p. 145, 3rd edition) never did allow very much, since the statements in which forward references are most interesting occur within the blocks of procedure and module bodies, but such blocks are themselves embedded within declarations according to the syntax of ProcedureDeclaration and ModuleDeclaration. Aside: The 2nd edition supplied lots of such fodder for the language lawyers. I don't know how much the 3rd edition improved this situation. In any case, there seem to be two essential uses of forward references: mutually recursive procedure declarations and mutually recursive type declarations. As noted in a previous reply by Harvard Townsend, the one-pass ETH compiler solves the first problem by reintroducing Pascal's "FORWARD". It is not quite so onerous in Modula-2 because many FORWARD declarations can (must) be disguised as the procedure headings appearing in definition modules. Recursive type declarations involving pointer indirection are admitted by special case #2, p. 145. They can almost be handled satisfactorily by a one-pass compiler that treats the referent types opaquely until they are resolved. The (transliterated) ETH compiler is actually fairly sloppy about this. Consider the following code fragment: PROCEDURE P1; TYPE P = POINTER TO T; TYPE T = BOOLEAN; VAR p: P; BEGIN p^ := TRUE END P1; TYPE T = INTEGER; PROCEDURE P2; TYPE P = POINTER TO T; TYPE T = BOOLEAN; VAR p: P; BEGIN p^ := TRUE; p^ := 3 END P2; The first assignment (in P1) is accepted, but the second generates a (very cryptic) error message and the third is compiled without complaint. I am told that this surprising behavior might have been a feature of the original ETH compiler also. If I recall correctly (I am less sure of this), attempts to dereference expressions with not-yet-resolved pointer types simply give compile-time type errors. The language rules on type matching and forward references seem designed to outlaw any legitimate uses of this, but consider, e.g., p^ := q^ or p^ = 7. Finally, I have found occasional but legitimate uses for recursively defined procedure *types*, e.g., P: TYPE = PROCEDURE(..., P, ...) As far as I can tell, there is no way to construct such types in Modula-2. Usual disclaimers, etc.