[Oberon] Module aliases - what is the correct way to handle them
andreas_pirklbauer at yahoo.com
Fri Feb 14 08:02:11 CET 2020
Some additional comments:
1. First, some history: For decades I was secretely hoping that module aliases would one day go way from the language and that I therefore would ever have to expend scarce brain cycles on such an uninteresting topic. But they didn’t go away - some people seem to find them useful.
2. Given that current version of ORB.ThisModule on projectoberon.com is incorrect and should be patched, I have finally decided to (reluctantly) look into this topic and put out a few variants on a repository for discussion. Within 24 hours we iterated quickly on a number of variants. So the process was efficient, as we now have a few correct versions, starting with ORB07.Mod. I didn’t expect to get there within a day.
3. In my own version of Oberon, I currently (and temporarily!) use ORB07.Mod, which simply tests all possible combinations of name/orgname:
(*ORB07.Mod*) obj1 := topScope; obj := obj1.next; (*search for module*)
WHILE (obj # NIL) & (obj.name # name) & (obj.name # orgname) &
(obj(Module).orgname # orgname) & (obj(Module).orgname # name) DO (**)
obj1 := obj; obj := obj1.next
IF obj = NIL THEN (*insert new module*)
ELSE (*module already present*)
IF non OR (obj(Module).orgname # name) THEN ORS.Mark("invalid import order") END
FULLY KNOWING that it is unnecessarily restrictive (one cannot, for example, compile "IMPORT Z := M0, M0 := M1” in test module M5). But at least it is simple and correct. My rationale for making it this restrictive was that it actually *prevents* the use of more or less confusing import statements like the ones in test modules M4 and M5. Not a particularly terrible restriction. But clearly not implementing the full language specification, which is more general.
4. In the meantime, I have put out another iteration ORB10.Mod, which removes all restrictions *except* the “invalid import order” case. So it is now “equally restrictive” as the FPGA Oberon version, while however being correct and als while keeping the complexity at a minimum.
5. There will be another iteration ORB11.Mod that finally removes *all* limitations, including the “invalid import order” one. However, I want to do it *without* adding significant complexity. Specifically, the goal is to implement the full solution, but WITHOUT ..
a) having to use a global module table GModtab - a technique which has been used for a long time now in various compilers
b) or having to stitch together implicit imports (re-exported types) and later explicit ones in the symbol table
The key idea for ORB11.Mod is to first pre-parse the import statement and merely create “empty" module entries in the symbol table (together with the alias names, if any). This yields the complete list of explicitly imported modules upfront. Then traverse that list and call ORB.Import for each of the previously generated entries (recursively, potentially). Implicit imports (re-imported types) are handled as in the current implementation, i.e. they are simply added to the topScope, while re-importing only those types that are actually needed. The difficulty of this approach is (probably) to transform ORB.Import so that it can be called recursively. In the absence of cyclic module imports, this should be doable (or is already the case?).
If it turns our to be doable with reasonable effort, I may adopt it. Otherwise I will either stick to ORB07.Mod or upgrade to ORB10.Mod
> On 14 Feb 2020, at 06:54, Andreas Pirklbauer <andreas_pirklbauer at yahoo.com> wrote:
> Hi Andreas,
> PS: Current iteration is ORB9, which however is still incomplete. Be
> Thanks for this. If I have it correctly, in summary:
> 1. "Invalid import order" is an implementation restriction to save the
> compiler from having housekeeping code to stitch together the implicit
> imports (re-exported types) and later explicit ones. You have kindly
> contributed alternative implementations which get round this limitation.
> 2. Prof. Wirth's current ORB.ThisModule code is incorrect, and should be
> patched along the lines of Michael's fix, but comparing canonical
> orgnames, i.e.
> WHILE (obj # NIL) & (obj(Module).orgname # orgname) DO obj1 := obj;
> obj := obj1.next END ;
> WHILE (obj # NIL) & (obj.name # name) DO obj1 := obj; obj := obj1.next
> END ;
> WHILE (obj # NIL) & (obj(Module).orgname # name) DO obj1 := obj; obj
> = obj1.next END ;
> Or is there more we need to look into at this stage?
More information about the Oberon