[Oberon] Conditional compilation using IF const THEN

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Sat Aug 11 09:36:21 CEST 2018

   > I have tried to work out how the authors of ETH-M2 and GPCP
   > achieved this but have been unsuccessful so far.

First, note that the ETH Modula-2 compilers has seen multiple
re-implementations over the years. As hardware with more and
more RAM became available, the number of passes was reduced.
That’s a topic in and by itself, but only of historic interest.

A. Here is an excerpt of Pass3 of the ETH Modula-2 Multi-Pass
Compiler in the Lilith implementation Version C18 of 10.02.82:

    PROCEDURE IfStatement;
    BEGIN (*IfStatement*)
      jumpList := NIL;
      LOOP Expression(lat);
        IF lat.mode=constantMod THEN
          IF BOOLEAN(lat.value) THEN           (*<-------*)
            StatSeq3(endsy, elsifsy, elsesy);
            IF sy<>endsy THEN Skip(endsy, endsy) END;
          ELSE Skip(elsesy, elsifsy);
            IF sy <> elsifsy THEN EXIT END;

I have no way to check this today (no access to Lilith ;-),
but I “believe* this is what is happening.

To replicate that on Project Oberon on RISC you’d need
to adjust ORP.StatSequence accordingly and check the
x after Expression(x) whether it is a boolean constant.

a) BOOLEAN converts lat.value

   (in M2 on Lilith the field ‘lat’ is an attribute and a
   descriptor of the operand in an expression,
   in Project Oberon it would correspond to x.a)

b) The IF BOOLEAN(lat.value) THEN expression
   then becomes either IF TRUE or IF FALSE

c) If it is FALSE, then Skip(elsesy, elsifsy) is
   executed (see above code), i.e. NO code is generated.

Again, I have no way to check, but I believe that this
*may* be the way it was done.

B. And here is an excerpt of MacMETH compiler in MC68000
which I was most familiar with at the time (and which was based
on one of the Lilith implementations if I remember correctly):


     ELSIF sym = if THEN
        GetSym; RefPoint; Expression(x); GenCFJ(x, L0);
        CheckSym(then, 27); StatSeq; L1 := 0;
        WHILE (sym = elsif) DO
          GetSym; GenFJ(L1); FixLink(L0); RefPoint; Expression(x);
          GenCFJ(x, L0); CheckSym(then, 27); StatSeq
        IF sym = else THEN
          GetSym; GenFJ(L1); FixLink(L0); StatSeq
        ELSE FixLink(L0)
        FixLink(L1); CheckSym(end, 20)

So there it is not done. It already looks at lot like Oberon on RISC.


More information about the Oberon mailing list