[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