[Oberon] Module aliases - what is the correct way to handle them

Andreas Pirklbauer andreas_pirklbauer at yahoo.com
Tue Feb 18 20:52:45 CET 2020


Paul,

I have added your proposal below as (the new version of) the file ORB06.Mod at:

   http://github.com/andreaspirklbauer/Oberon-test-module-aliases

Your proposal reads:

  PROCEDURE ThisModule(name, orgname: ORS.Ident; non: BOOLEAN; key: LONGINT): Object;
    VAR mod: Module; obj, obj1: Object;
  BEGIN obj1 := topScope; obj := obj1.next;  (*search for module*)
    WHILE (obj # NIL) & (obj(Module).orgname # orgname) DO
      obj1 := obj; obj := obj1.next
    END;
    IF obj = NIL THEN  (*new module - search for name/alias*)
      obj := topScope.next;
      WHILE (obj # NIL) & (obj.name # name) DO obj := obj.next END ;
      IF obj = NIL THEN  (*insert new module*)
        NEW(mod); mod.class := Mod; mod.rdo := FALSE;
        mod.name := name; mod.orgname := orgname; mod.val := key;
        mod.lev := nofmod; INC(nofmod); mod.type := noType;
        mod.dsc := NIL; mod.next := NIL;
        obj1.next := mod; obj := mod
      ELSE ORS.Mark("mult def")
      END
    ELSE (*module already present*)
      IF non THEN ORS.Mark("invalid import order") END
    END ;
    RETURN obj
  END ThisModule;

I have tested it against the test modules B0-B11 in the test file M.Mod (this suite is designed such that B0 should always be correct, B1-B5 should return “mult def” and the reminaing modules should issue error msgs depending on the implementation of ORB)

  MODULE B0; IMPORT M0, X := M1; END B0.

  MODULE B1; IMPORT M0, M0; END B1.
  MODULE B2; IMPORT M0, M0 := M1; END B2.
  MODULE B3; IMPORT M0 := M1, M0; END B3.
  MODULE B4; IMPORT M0 := M1, M0 := M1; END B4.
  MODULE B5; IMPORT M0 := M1, M0 := M2; END B5.

  MODULE B6; IMPORT M0, X := M0; END B6.
  MODULE B7; IMPORT X := M0, M0; END B7.
  MODULE B8; IMPORT M0, X := M0, Y := M0; END B8.
  MODULE B9; IMPORT X := M0, Y := M0; END B9.
  MODULE B10; IMPORT X := M0, M0 := M1; END B10.
  MODULE B11; IMPORT M0 := M1, M1 := M0; END B11.

with the following results:

  ORP.Compile ORB06.Mod/s ~   System.Free ORP ORG ORB ~   now recompile B0-B11

  -> B0: compiles

  -> B1: does not compile - reports "invalid import order"
  -> B2: does not compile - reports "mult def"
  -> B3: does not compile - reports "mult def"
  -> B4: does not compile - reports "mult def", reports "invalid import order"
  -> B5: does not compile - reports "mult def" twice

  -> B6: does not compile - reports "invalid import order"
  -> B7: does not compile - reports "invalid import order"
  -> B8: does not compile - reports "invalid import order" twice
  -> B9: does not compile - reports "invalid import order"
  -> B10: compiles
  -> B11: does not compile - reports "mult def"

Is this what you intended? I guess that at least B1 should also return “mult def”.

Meanwhile, I have improved my ORB07.Mod to make it cleaner, by separating
the cases of “explicit import” and “re-import” --> see ORB08.Mod.

-ap

-----------------------------------------------------------------------------------

  > I'm still a bit uncomfortable with your loop which tests both canonical 
  > names and aliases at the same time in your ORB07.Mod suggestion:
  >
  >   WHILE (obj # NIL) & (obj.name # name) & (obj.name # orgname) &
  >         (obj(Module).orgname # orgname) & (obj(Module).orgname # name) 
  >   DO ...
  >
  > and would like to propose the following as a minimum change, which fixes 
  > the current ORB.Mod bug and adds the "mult def" check required to catch 
  > a re-use of an alias:
  >
  > #   WHILE (obj # NIL) & (obj(Module).orgname # orgname) DO obj1 := obj; 
  > obj := obj1.next END;
  >     IF obj = NIL THEN  (*new module - search for name/alias*)
  > +     obj := topScope.next; WHILE (obj # NIL) & (obj.name # name) DO obj 
  > := obj.next END ;
  > +     IF obj # NIL THEN ORS.Mark("mult def")
  > +     ELSE
  >         NEW(mod); mod.class := Mod; mod.rdo := FALSE;
  >         mod.name := name; mod.orgname := orgname; mod.val := key;
  >         mod.lev := nofmod; INC(nofmod); mod.type := noType;
  >         mod.dsc := NIL; mod.next := NIL;
  >         obj1.next := mod; obj := mod
  > +     END
  >    ELSE (*module already present*)
  >       IF non THEN ORS.Mark("invalid import order") END
  >    END ;




More information about the Oberon mailing list