[comp.lang.modula2] Typecompatibility with extended datatypes

ciao@diku.dk (Lars Christensen) (05/11/88)

  I have a question on extended datatypes.
  Suppose, you want to make a stack-structure with elements of different
types. You may then define the following type:

       TYPE
         StackPtr = RECORD p: POINTER TO StackPtr END;

Every stackelement, should have this type as its basetype, so that the stack
is build as a linked list.
  The stack and two types of elements may be declared like this:

       VAR
         Stack: RECORD (StackPtr) END;
	 Ielement: POINTER TO RECORD (StackPtr) i: Integer END;
	 Celement: POINTER TO RECORD (StackPtr) c: Char END;

The operation Push is easy enough: ( Stackinitialization deleted)

        PROCEDURE PUSH(VAR s:StackPtr; VAR e: POINTER TO StackPtr);
	BEGIN
	  e^.p:=s.p; (* e^.p is set to point to the top element *)
	  s.p :=e    (* The stack s.p is set to point to this new element *)
	END;

It could be called with:

	New(Ielement); Ielement.i:=5; Push(Stack,Ielement);

But when I want to Pop an element, I would like to check whether the 
type of the top element and the variable to return that element in are
_exactly_ equal like this:

	  PROCEDURE Pop(VAR s:StackPtr; VAR e: POINTER TO StackPtr);
	  BEGIN
	    IF Type(e^)<>Type(s.p^) THEN (* <-------------- *)
	      Error('Pop of wrong type!')
	    ELSE
	      e:=s.p;   (* e is set to point at top element on stack *)
	      s.p:=e^.p (* s.p is set to point to the next element *)
	    END;
	  END;

and called with:

	   Pop(Stack,Ielement) (* OK if after the previous Push *)
	   Pop(Stack,Celement) (* Should error if after previous Push *)

But the Type() operations are not allowed. How could I implement this check
with the extended type scheme given by N.Wirth?

Any help would be appreciated.

Lars Christensen