Dynamic type of record var parameter
Hello, please consider the following test of dynamic type of record variable parameters: MODULE Test; IMPORT Texts, Oberon; TYPE r0 = RECORD i : INTEGER; END; r1 = RECORD (r0) x : REAL END; r2 = RECORD (r1) c : CHAR END; p0 = POINTER TO r0; p1 = POINTER TO r1; p2 = POINTER TO r2; VAR W : Texts.Writer; PROCEDURE check(VAR r : r0); BEGIN IF r IS r2 THEN Texts.WriteString(W, "is r2") ELSIF r IS r1 THEN Texts.WriteString(W, "is r1") ELSIF r IS r0 THEN Texts.WriteString(W, "is r0") END; Texts.WriteLn(W) END eins; PROCEDURE do* (); VAR p : p0; r : r0; q : p2; t : r2; BEGIN NEW(p); NEW(q); check(t); check(p^); check(q^); p := q; check(p^); Texts.Append(Oberon.Log, W.buf); END do; BEGIN Texts.OpenWriter(W); END Test. Output from Oberon 2013 emulator is: is r2 is r0 is r2 is r0 What surprises me is the last one. The dynamic type is r2 not r0. It looks like the compiler uses the static type from the local variable p instead of the dynamic type of p^. Is this intended behavior? Greetings, chris
Yes, the last should be r2 -- Diego Sardina On Mon, Jan 11, 2021, at 11:44 PM, chris wrote:
Hello,
please consider the following test of dynamic type of record variable parameters:
MODULE Test;
IMPORT Texts, Oberon;
TYPE r0 = RECORD i : INTEGER; END; r1 = RECORD (r0) x : REAL END; r2 = RECORD (r1) c : CHAR END; p0 = POINTER TO r0; p1 = POINTER TO r1; p2 = POINTER TO r2;
VAR W : Texts.Writer;
PROCEDURE check(VAR r : r0); BEGIN IF r IS r2 THEN Texts.WriteString(W, "is r2") ELSIF r IS r1 THEN Texts.WriteString(W, "is r1") ELSIF r IS r0 THEN Texts.WriteString(W, "is r0") END; Texts.WriteLn(W) END eins;
PROCEDURE do* (); VAR p : p0; r : r0; q : p2; t : r2; BEGIN NEW(p); NEW(q); check(t); check(p^); check(q^); p := q; check(p^); Texts.Append(Oberon.Log, W.buf); END do;
BEGIN Texts.OpenWriter(W); END Test.
Output from Oberon 2013 emulator is: is r2 is r0 is r2 is r0
What surprises me is the last one. The dynamic type is r2 not r0. It looks like the compiler uses the static type from the local variable p instead of the dynamic type of p^. Is this intended behavior?
Greetings, chris -- Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems https://lists.inf.ethz.ch/mailman/listinfo/oberon
-----Original Message----- From: Oberon [mailto:oberon-bounces@lists.inf.ethz.ch] On Behalf Of chris Sent: Tuesday, 12 January 2021 9:14 AM To: oberon@lists.inf.ethz.ch Subject: [Oberon] Dynamic type of record var parameter
Hello,
please consider the following test of dynamic type of record variable parameters:
MODULE Test;
IMPORT Texts, Oberon;
TYPE r0 = RECORD i : INTEGER; END; r1 = RECORD (r0) x : REAL END; r2 = RECORD (r1) c : CHAR END; p0 = POINTER TO r0; p1 = POINTER TO r1; p2 = POINTER TO r2;
VAR W : Texts.Writer;
PROCEDURE check(VAR r : r0); BEGIN IF r IS r2 THEN Texts.WriteString(W, "is r2") ELSIF r IS r1 THEN Texts.WriteString(W, "is r1") ELSIF r IS r0 THEN Texts.WriteString(W, "is r0") END; Texts.WriteLn(W) END eins;
PROCEDURE do* (); VAR p : p0; r : r0; q : p2; t : r2; BEGIN NEW(p); NEW(q); check(t); check(p^); check(q^); p := q; check(p^); Texts.Append(Oberon.Log, W.buf); END do;
BEGIN Texts.OpenWriter(W); END Test.
Output from Oberon 2013 emulator is: is r2 is r0 is r2 is r0
What surprises me is the last one. The dynamic type is r2 not r0. It looks like the compiler uses the static type from the local variable p instead of the dynamic type of p^. Is this intended behavior?
My understanding is that you need to use a type guard to assert that p can be assumed to have a dynamic type of p2: i.e. p := q; check(p(p2)^); or to be safe: p := q; IF p IS p2 THEN check(p(p2)^) END; However, I'm not a fan of anonymous variables so I would be more likely to write: p := q; IF p IS p2 THEN t := p(p2)^; check(t) END; For more information refer to Section 11.2 in Programming in Oberon by Martin Reiser and Niklaus Wirth: https://people.inf.ethz.ch/wirth/ProgInOberonWR.pdf Regards, Chris Burrows CFB Software https://www.astrobe.com/RISC5
On 2021-01-11 23:44, chris wrote:
What surprises me is the last one. The dynamic type is r2 not r0. It looks like the compiler uses the static type from the local variable p instead of the dynamic type of p^. Is this intended behavior?
Probably an error in the Project Oberon compiler. I just tried your example with OBNC (replacing Texts with Out) and it (correctly?) prints is r2 is r0 is r2 is r2 Here is a somewhat minimal example which highlights the issue: MODULE Test2; IMPORT Out; TYPE T0 = RECORD END; T1 = RECORD (T0) END; P0 = POINTER TO T0; P1 = POINTER TO T1; PROCEDURE PrintDynamicType(VAR x: T0); BEGIN CASE x OF T1: Out.String("T1") | T0: Out.String("T0") END; Out.Ln END PrintDynamicType; PROCEDURE Run*; VAR p0: P0; p1: P1; BEGIN NEW(p1); p0 := p1; PrintDynamicType(p0^) END Run; END Test2. -- August
participants (4)
-
August Karlstrom -
chris -
Chris Burrows -
Diego Sardina