Extended Type Formal VAR Parameters

General discussions about working with the Astrobe IDE and programming ARM Cortex-M3, M4 and M7 microcontrollers.

Extended Type Formal VAR Parameters

Postby gray » Sat Apr 13, 2019 4:17 am

Code: Select all
MODULE M;

  TYPE
    T1 = POINTER TO T1Desc;
    T1Desc = RECORD
    END;
   
    T2 = POINTER TO T2Desc;
    T2Desc = RECORD(T1Desc)
    END;
   
  VAR
    t1: T1;
    t2: T2;
   
  PROCEDURE P1(t: T1);
  END P1;
 
  PROCEDURE P2(VAR t: T1);
  END P2;
 
BEGIN
  t1 := t2;
  P1(t2);
  P2(t2) (* does not compile *)
END M.

I am not sure why the compiler rejects the assignment to the VAR procedure parameter in P2.
gray
 
Posts: 29
Joined: Tue Feb 12, 2019 2:59 am

Re: Extended Type Formal VAR Parameters

Postby cfbsoftware » Sat Apr 13, 2019 5:02 am

Refer to section 10.1. Formal parameters in the Oberon Language Report. In particular:

The type of each formal parameter is specified in the parameter list. For variable parameters, it must be identical to the corresponding actual parameter's type, except in the case of a record, where it must be a base type of the corresponding actual parameter's type.

At compile time, the type of the actual parameter in your call to P2 is T2 whereas it should be T1. The call to P1 is OK because the formal parameter to P1 is not a variable parameter.

The following example is OK:

Code: Select all
MODULE M2;

  TYPE
    T1 = POINTER TO T1Desc;
    T1Desc = RECORD
    END;
   
    T2 = POINTER TO T2Desc;
    T2Desc = RECORD(T1Desc)
    END;
   
  VAR
    t1: T1;
    t2: T2;
    t1d: T1Desc;
    t2d: T2Desc;
   
  PROCEDURE P1(t: T1);
  END P1;
 
  PROCEDURE P2(VAR t: T1);
  END P2;
 
  PROCEDURE P1d(VAR t: T1Desc);
  END P1d;
 
BEGIN
  t1 := t2;
  t1d := t2d;
  P1(t2);
  P2(t1);
  P1d(t2d)
END M2.
cfbsoftware
Site Admin
 
Posts: 383
Joined: Fri Dec 31, 2010 12:30 pm

Re: Extended Type Formal VAR Parameters

Postby gray » Sun Apr 14, 2019 1:30 am

Hm, thanks, yes, the Report is clear about this. Mr W's writing is succinct and precise as usual. I was mulling over the reason why pointers to an extended type cannot be passed as VAR parameters declared as pointer to a base type thereof.

Is this the (or a) use case and problem the rule prevents?
Code: Select all
MODULE M9;

  TYPE
    T1 = POINTER TO T1Desc;
    T1Desc = RECORD
      i: INTEGER
    END;
   
    T2 = POINTER TO T2Desc;
    T2Desc = RECORD(T1Desc)
      k: INTEGER
    END;
 
  VAR
    t2: T2;
   
  PROCEDURE P1(VAR t: T1);
    VAR
      t1: T1;
  BEGIN
    NEW(t1);
    t := t1
  END P1;
 
BEGIN
  NEW(t2);
  t2.i := 4;
  t2.k := 13;
  P1(t2); (* error *)
  t2.k := 17 (* ouch *)
END M9.
gray
 
Posts: 29
Joined: Tue Feb 12, 2019 2:59 am

Re: Extended Type Formal VAR Parameters

Postby cfbsoftware » Sun Apr 14, 2019 4:16 am

I can recommend an excellent reference to help you to understand the reasoning behind these sorts of details. It is the book titled Object-Oriented Programming in Oberon-2 by Hanspeter Mössenböck. It is available as PDF with the friendly permission of Springer-Verlag from :

http://ssw.jku.at/Research/Books/Oberon2.pdf

Keep in mind while you are reading it that Oberon-2 has additional O-O features (e.g. type-bound procedures), and some differences (e.g. WITH instead of CASE) so it is not all relevant to Oberon-07. However, there should still be enough to be useful to you.
cfbsoftware
Site Admin
 
Posts: 383
Joined: Fri Dec 31, 2010 12:30 pm

Re: Extended Type Formal VAR Parameters

Postby gray » Mon Apr 15, 2019 2:30 am

Code: Select all
MODULE M8;

  TYPE
    T1 = RECORD
      i: INTEGER
    END;
   
    T2 = RECORD(T1)
      k: INTEGER
    END;
 
  VAR
    t1: T1;
    t2: T2;
   
  PROCEDURE P1(VAR t: T1);
    VAR
      t1: T1;
  BEGIN
    t1.i := 17;
    t := t1
  END P1;
 
BEGIN
  t2 := t1; (* illegal *)
  t2.i := 13;
  t2.k := 4;
  P1(t2); (* t2.i = 17, t2.k = 4 *)
END M8.

The t2 := t1 assignment is illegal, as per compiler error as well as the Report. However, P1(t2) and the assignment therein works and yields the results as indicated in the comment. Is this legal code as per the language definition? If yes, what are the rules of the assignment in P1 as regards the record fields in T2 but not in T1?
gray
 
Posts: 29
Joined: Tue Feb 12, 2019 2:59 am

Re: Extended Type Formal VAR Parameters

Postby cfbsoftware » Mon Apr 15, 2019 8:48 am

That all looks good to me. In this case the assignment:

Code: Select all
t := t1

is equivalent to:
Code: Select all
t.i := t1.i

t2.k remains unchanged. If you wanted to modify k as well you would need to use an assignment with a type guard (and a type test to be on the safe side) within the procedure P1.

Code: Select all
PROCEDURE P1(VAR t: T1);
    VAR
      t1: T1;
  BEGIN
    t1.i := 17;
    t := t1;
    IF t IS T2 THEN t(T2).k := 99 END;
  END P1;


Alternatively, if you prefer, you can use CASE to handle both the type test and guard:

Code: Select all
  PROCEDURE P1(VAR t: T1);
    VAR
      t1: T1;
  BEGIN
    t1.i := 17;
    t := t1;
    CASE t OF T2: t.k := 99 END;
  END P1;
cfbsoftware
Site Admin
 
Posts: 383
Joined: Fri Dec 31, 2010 12:30 pm


Return to Astrobe for ARM Cortex-M3, M4 and M7