[Oberon] Oberon for a C++ user.

Felix Friedrich felix.friedrich at inf.ethz.ch
Mon Nov 21 08:40:45 CET 2016


Andreas

Although it is nice that it works like this, your code example misses 
the point of the previous code: there are two different variants 
coexisting of a singleton object (a module) with the consequence that a 
type test or type guard on instances of the "old" module emitted from a 
"new" module does not work any more.
Eventually it is not a drama because no practically important examples 
seem to exist. Moreover with some indirection on the type descriptors it 
would be easy to solve. But for the sake of purity....

Kind regards
Felix




> Felix,
>
> below is the output (under Experimental Oberon) of a modified set of 
> your modules A, B, and C (source code appended below).
>
>
> It nicely shows that C.Delete selects the "right" module B, i.e. 
> either the "old B" (here called B*), or the "new B" (here called B). 
> The type descriptors and the code of module B* (removed from module 
> list) is still available in memory.
>
>
> All type tests automatically select the "right" type descriptor and 
> the "old B" is only removed from memory when no more references from 
> the remaining modules exist.
>
>
> Andreas
>
>
> COMMAND SEQUENCE (see below for source code of A, B, and C):
>
> B.Insert 1             ... insert elemt from old B
> System.ShowModules     ... B is the old B
> System.Free B/f        ... remove old B from module list, don't 
> release memorz
> System.ShowModules     ... B* is the old B
> B.Insert 2             ... new B
> System.ShowModules     ... B* is the old B, B is the new B
> C.Delete 1             ... deletes the element created by the old B
> C.Delete 2             ... deletes the element created by the old B
> C.Init                 ... clears the data structure rooted in A.root
> Modules.Collect        ... collects B* (no longer referenced)
> System.ShowModules     ... module B* no longer in memory
>
> GENERATED OUTPUT:
>
> 1) B.Insert 1
> insert element from module B module descriptor at  000212C0
>
> 2) System.ShowModules
> B  000212C0 000213D0   0
> A  00020F60 00020FDC   1
> System   0001CB80 0001D320   0
> ...
>
> 3) System.Free B/f
> B unloading: removing from module list (references exist)
>
> 4) System.ShowModules
> *B   000212C0 000213D0   0 (removed from module list)
> A  00020F60 00020FDC   1
> System   0001CB80 0001D320   0
> ...
>
> 5) B.Insert 2
> insert element from module B module descriptor at  00021800
>
> 6) System.ShowModules
> B  00021800 00021910   0
> *B   000212C0 000213D0   0 (removed from module list)
> A  00020F60 00020FDC   2
> System   0001CB80 0001D320   0
> ...
>
> 7) C.Delete 1
> type of t is T from module B* module descriptor at  000212C0
>
> 8) C.Delete 2
> type of t is T from module B module descriptor at  00021800
>
> 9) C.Init + Modules.Collect + System.ShowModules
> B  00021800 00021910   0
> A  00020F60 00020FDC   2
> System   0001CB80 0001D320   0
> ...
>
> ----------------------------------------------------------------------------------------------------
>
> MODULE A; (*base module managing data structure of base type T*)
>   TYPE T* = POINTER TO R;
>     P* = PROCEDURE (t: T);
>     R* = RECORD i*: INTEGER;
> close*: P;
> next: T
>     END ;
>
>   VAR root*: T;
>
> PROCEDURE Find*(i: INTEGER): T;
>     VAR t: T;
>   BEGIN t := root;
> WHILE (t # NIL) & (t.i # i) DO t := t.next END ;
> RETURN t
>   END Find;
>
> PROCEDURE Insert*(t: T);
>     VAR s: T;
>   BEGIN s := Find(t.i);
>     IF s = NIL THEN t.next := root; root := t END
>   END Insert;
>
> PROCEDURE Delete*(i: INTEGER);
>     VAR s, t: T;
>   BEGIN t := root; s := t;
> WHILE (t # NIL) & (t.i # i) DO s := t; t := t.next END ;
>     IF t # NIL THEN t.close(t);
> IF t = root THEN root := NIL ELSE s.next := t.next END
>     END
>   END Delete;
>
> PROCEDURE Init*;
>   BEGIN root := NIL
>   END Init;
>
> BEGIN Init
> END A.
>
> --------------------------------------
>
> MODULE B; (*client of A, defining extensions of A.T*)
> IMPORT A, Modules, Texts, Oberon;
> TYPE T* = POINTER TO R;
> R* = RECORD (A.R) j: INTEGER END;
>
>   VAR M: Modules.Module;
> W: Texts.Writer;
>
> PROCEDURE Close*(t: A.T);
> VAR S: Texts.Scanner;
> BEGIN
> IF (t IS T) & (M # NIL) THEN
> Texts.WriteString(W, "type of t is T from module "); 
> Texts.WriteString(W, M.name);
> Texts.WriteString(W, " module descriptor at "); Texts.WriteHex(W, ORD(M));
> Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
> END
>   END Close;
>
> PROCEDURE Insert*;
> VAR S: Texts.Scanner; t: T;
> BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); 
> Texts.Scan(S);
> IF S.class = Texts.Int THEN NEW(t); t.i := S.i; t.close := Close; 
> A.Insert(t);
> Texts.WriteString(W, "insert element from module "); 
> Texts.WriteString(W, M.name);
> Texts.WriteString(W, " module descriptor at "); Texts.WriteHex(W, ORD(M));
> Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
> END
>   END Insert;
>
> PROCEDURE Init*;
> BEGIN
>   END Init;
>
> BEGIN Texts.OpenWriter(W); M := Modules.root;
> WHILE (M # NIL) & (M.name # "B") DO M := M.next END
> END B.
>
> --------------------------------------
>
> ODULE C; (*tool module*)
> IMPORT A, Texts, Oberon;
>
> VAR W: Texts.Writer;
>
> PROCEDURE Delete*;
> VAR S: Texts.Scanner;
> BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); 
> Texts.Scan(S);
> IF S.class = Texts.Int THEN A.Delete(S.i) END
> END Delete;
>
> PROCEDURE Init*;
> BEGIN
> END Init;
>
> BEGIN Texts.OpenWriter(W)
> END C.
>
> ----------------
>
>
>
>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.inf.ethz.ch/pipermail/oberon/attachments/20161121/0e84a2c6/attachment.html>


More information about the Oberon mailing list