[net.lang.mod2] ETH Modula2 Single Pass

neil@fornax.uucp (Neil MacKenzie) (09/17/86)

I have a copy of the Single pass Modula-2 compiler from ETH and seems quite
good. Unfortunately it came with hardly any libraries to access the toolbox etc.
If any one on the net knows where I can get a hold of the libraries I would 
appreciate hearing from them. 

				Thanks
				 Neil MacKenize
				 Simon Fraser University
				 uw-beaver!ubc-vision!fornax!neil

treid@MITRE.ARPA (Thomas Reid) (09/19/86)

Please tell us more about the compiler and its availability.  Thanks Tom.

rpd@f.gp.cs.cmu.edu (Richard Draves) (09/22/86)

I don't believe a true one-pass Modula-2 compiler is possible.
I have some experience with the language, having implemented
the front-end (first-pass) for a compiler.  I have also discussed
this issue with Mike Powell, implementor of the famed Powell compiler,
and he concurs.

The problem is that identifiers may be used in statements before they
are declared (although identifiers used in declarations must be declared
before use).  Page 145 of the 3rd edition of Wirth's book is very clear.
You may think a back-patching scheme can overcome this, but I have some
sample programs that I think can convince anyone that the problems with
such an approach are intractable.

Does this purported one-pass compiler compile the whole language or a subset?
If it does compile the whole language, does anyone know how it accomplishes
this in a single pass?  Let me mention that reading a program into memory,
perhaps in the form of a syntax tree, and then generating code is *not*
one pass.

Rich

harv@kansas-state.CSNET (Harvard Townsend) (09/23/86)

Modula Corp. of Provo, Utah sells a one-pass compiler for the IBM PC which
I assume is based on Wirth's compiler (see pages 68-69 in Sept./Oct. 1986 
Journal of Pascal, Ada, & Modula-2, "Modula-2 Compiler Available in Source").
This compiler recognizes a "FORWARD" declaration for procedures, a la Pascal.
______________________________________
Harvard Townsend, Systems Administrator
Kansas State University, Dept. of Computer Science
Manhattan, KS 66506   (913)532-6350
CSNET:	harv@kansas-state -or- harv%kansas-state@csnet-relay.arpa
			  -or- harv%kansas-state@relay.cs.net
BITNET: harv@ksuvax1.bitnet -or- harv%ksuvax1.bitnet@WISCVM.WISC.EDU
UUCP: ihnp4!ltuxa!ksuvax1!harv

barad@brand.UUCP (Herb Barad) (09/23/86)

In article <5@f.gp.cs.cmu.edu> rpd@f.gp.cs.cmu.edu (Richard Draves) writes:
>I don't believe a true one-pass Modula-2 compiler is possible.
>I have some experience with the language, having implemented
>the front-end (first-pass) for a compiler.  I have also discussed
>this issue with Mike Powell, implementor of the famed Powell compiler,
>and he concurs.
>
Yes, the compiler is possible.  In fact, I have used it.  This is
sometimes called the Heitz compiler as Wener Heitz (sorry about name
spelling) as well as good ol' Nick W. worked on it.  I know many who
are using the Lillith version and love it.  I have used the Macintosh
version called "MacMETH" - beware as this version as SERIOUS BUGS.  I
have had Keith Poole from Modula Corp help me out and he agrees that
the Mac version has serious bugs.  Modula Corp does not get any
support from ETH on this product, so he can't help me out.  I have
also found serious bugs in MacModula-2 (all versions) dealing with
their handling of processes (coroutines).

You have to remember that the definition of the language has changed
(again, sigh!) for the one-pass compiler.  There are no export
statements as everything in the definition module is exported.
Coroutines are no longer part of the definition of the language - but
many implementation will still have them I hope.

One great thing about it - IT IS FAST.  MacMETH compiles about 40-100
times faster than MacModula-2.  I suppose similar speed-ups are
obtained elsewhere...

By the way, about the Powell compiler - I have also hit some serious
bugs there.  I have been able to call procedures with the wrong number
of arguments and it links!  How did this happend?  Well, I was
changing a module around and made the number of parameters in some
procedure calls different.  Some people came around to distract me and
we went out to lunch...  Later, I forgot to change the module that
holds the calls to these changed procedures and I ran my makefile.
Well, my makefile was not made properly, so all it did was recompile
the files that had been edited and linked them - successfully!!!  It
did not do any checking for me.  I realize that this goof was
initially my fault (almost all bugs are), but a strictly typed
language such as Modula-2 is suppose to check this...  Since
everything compiled and linked, it took me quite a long time to track
this down with the debugger.

>The problem is that identifiers may be used in statements before they
>are declared (although identifiers used in declarations must be declared
>before use).  Page 145 of the 3rd edition of Wirth's book is very clear.
>You may think a back-patching scheme can overcome this, but I have some
>sample programs that I think can convince anyone that the problems with
>such an approach are intractable.
>
>Does this purported one-pass compiler compile the whole language or a subset?
>If it does compile the whole language, does anyone know how it accomplishes
>this in a single pass?  Let me mention that reading a program into memory,
>perhaps in the form of a syntax tree, and then generating code is *not*
>one pass.
>
This I don't know about - I suppose you might contact the people at
ETH and/or Modula Corp for an answer.



-- 

Herb Barad	[USC - Signal and Image Processing Institute]

USENET:		...!sdcrdcf!usc-oberon!brand!barad			or
		...!mcvax!seismo!sdcsvax!sdcrdcf!usc-oberon!brand!barad

ARPANET:	barad@brand.usc.edu

USMail:		Univ. of Southern California
		Powell Hall 306, MC-0272
		Los Angeles, CA 90089-0272
		phone: (213) 743-0911

CC.GALVIN@R20.UTEXAS.EDU (Pete Galvin) (09/24/86)

At a talk Prof. Wirth gave here, he discussed his new, ONE-PASS, Modula-2
compiler.  I think he uses back-patching.  I also seem to recall him
saying he changed the language definition slightly to accomodate this...
but I'm not sure.

                                        --Pete
-------

ehs@magic.DEC.COM (Ed Satterthwaite) (09/25/86)

---------

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.

heeb@ethz.UUCP (Hansruedi Heeb) (09/30/86)

You can access any tool-box tool if you know it's address. An example:

FROM SYSTEM IMPORT WORD;

PROCEDURE DrawChar(ch: WORD); CODE 0A883H;


	Hansruedi Heeb
	{seismo|decvax}!mcvax!cernvax!ethz!heeb
-- 
	Hansruedi Heeb
	{seismo|decvax}!mcvax!cernvax!ethz!heeb

heeb@ethz.UUCP (Hansruedi Heeb) (10/02/86)

>I don't believe a true one-pass Modula-2 compiler is possible.

True, Wirth *did* change the language (definitions must come before
usage). But: the new compiler is sooooo fast (3000 lines/minute on
MAC with hard-disk) that you will forget the drawbacks.

Availability: from ETH (mail to ...ethz!modula2) but it is not free (100$ ??).

	Hansruedi Heeb
	{seismo|decvax}!mcvax!cernvax!ethz!heeb



-- 
	Hansruedi Heeb
	{seismo|decvax}!mcvax!cernvax!ethz!heeb

joel@gould9.UUCP (Joel West) (10/08/86)

In article <384@ethz.UUCP>, heeb@ethz.UUCP (Hansruedi Heeb) writes:
> You can access any tool-box tool if you know it's address. An example:
> 
> FROM SYSTEM IMPORT WORD;
> 
> PROCEDURE DrawChar(ch: WORD); CODE 0A883H;
> 
> 
> 	Hansruedi Heeb
> 	{seismo|decvax}!mcvax!cernvax!ethz!heeb

Actually, this loses something in the translation, since the
word here is "trap" not "address".  A trap is an unimplemented
68000 instruction.

This only works for stack-based calls, which are normally limited
to the toolbox.  For example, if MacMETH doesn't provide assembler,
and doesn't provide direct access to the file manager, device
manager, and memory manager, you're SOOL.
-- 
	Joel West			     MCI Mail: 282-8879
	Western Software Technology, POB 2733, Vista, CA  92083
	{cbosgd, ihnp4, pyramid, sdcsvax, ucla-cs} !gould9!joel
	joel%gould9.uucp@NOSC.ARPA

bobc@tikal.UUCP (10/09/86)

In article <809@gould9.UUCP> joel@gould9.UUCP (Joel West) writes:
>This only works for stack-based calls, which are normally limited
>to the toolbox.  For example, if MacMETH doesn't provide assembler,
>and doesn't provide direct access to the file manager, device
>manager, and memory manager, you're SOOL.
>-- 
>	Joel West			     MCI Mail: 282-8879

Actually you don't need a assembler to do OS traps, but some simple
rules are in order.  First OS traps require some glue code to adjust
things correctly for example, and the INLINE directive should be used
instead of the "CODE" procedure:

FROM SYSTEM IMPORT ADDRESS,INLINE,SETREG,REG,ADR,WORD;
CONST A0 = 8; D0 = 0;
PROCEDURE OSEventAvail (mask: WORD; VAR theEvent: EventRecord): BOOLEAN;
BEGIN
	SETREG(8,ADR(theEvent)); SETREG(0,mask);
	CODE(0A030H);
	RETURN(VAL(INTEGER,REG(0)) = 0)
END OSEventAvail;

Rule #2 Don't use WITH statements with INLINE traps. Things will
normally work ok if the WITH closes before the TRAP.  For example the
following may fail:

IMPLEMENTATION MODULE FileManager;
FROM SYSTEM		IMPORT ADR,REG,SETREG,INLINE,WORD;
FROM PascalStrings	IMPORT MakePascalString;
FROM MacTypes		IMPORT OSErr;
FROM FileTypes		IMPORT OSType,ParamBlockRec;
CONST
    OpenTrap	=   0A000H;
    A0		=   8;
    D0		=   0;
...
PROCEDURE FSOpen(VAR Name:ARRAY OF CHAR;vRef:INTEGER;VAR ref:INTEGER):OSErr;
VAR PB:ParamBlockRec; Str:ARRAY[0..255] OF CHAR;
BEGIN
    WITH PB DO
	ioCompletion := NIL; MakePascalString(Name,Str);
	PB.ioNamePtr := ADR(Str); PB.ioVRefNum := vRef;
	PB.ioVersNum := 0C; PB.ioPermssn := 0C; PB.ioMisc := NIL;
	SETREG(A0,ADR(PB)); INLINE(OpenTrap);
	ref := ioRefNum; RETURN(ioResult);
    END;
END FSOpen;
....
But if it is done like this it will work:
    WITH PB DO
	ioCompletion := NIL;
	...
	ioMisc := NIL;
    END;
    SETREG(A0,ADR(PB)); INLINE(OpenTrap);
    ref := ioRefNum;
    RETURN(ioResult);
    ...

Of the things in MacMETH that I want the most are: HFS Search Paths, in
both the Linker and in the Loader for finding object files.  But by the
time that they get that done I will not need MacMETH anymore.  (Hint:
I am working on a MPW version of Modula-2).

Bob Campbell
Teltone Corporation		18520 - 66th AVE NE
P.O. Box 657			Seattle, WA 98155
Kirkland, WA 98033

{amc,dataio,fluke,hplsla,sunup,uw-beaver}!tikal!bobc