[net.lang.ada] variant records

dean@rsch.WISC.EDU (Dean Luick) (10/31/86)

I am trying to write a stack package using a variant record in the main
record type and I am having great difficulty.  My problem is the following,
if I have the following definition:

type enum is (A, B, C, D);
type rec(kind : enum := A) is
    record
        case kind is
            when A | B =>       -- the actual values don't matter
                null;
            when C | D =>
                foo : integer;
    end record;

type node(xkind : enum := A);
type node_ptr is access node;
type node(xkind : enum := A) is
    record
        next : node_ptr;
        xrec : rec(xkind);
    end record;

stack       : node_ptr := NULL;
extra_nodes : node_ptr := NULL;

-- and I have the following later definiions:

procedure push(r : rec) is
    temp : node_ptr;
begin
    temp := new_node;
    temp.xrec := r;             -- position 'Z'
    temp.next := stack;
    stack := temp;
end push;

function new_node return node_ptr is
    temp : node_ptr;
begin
    temp := extra_nodes;
    if temp = NULL then
        temp := new node;
    else
        extra_nodes := extra_nodes.next;
    end if;
    return temp;
end new_node;

Suppose I create a rec of say, B, and try to push it.  At postion 'Z'
a constraint error is raised because of the different variant types ( in
the first case, temp's discriminant is A ).  Is there any way around this?
I was led to believe that I cound change the variant part of a type by
assigning it a whole aggregate (is that the right word?) say, like

case r.kind is 
    . . .
    when B =>
        temp.xrec := rec'(kind => B)
    . . .

Well, I tried that at position 'Z' and it failed.  I have run out of ideas.
Any help would be greatly appreciated.

dean

-- 

Dean Luick
uucp:	...!{allegra,harvard,ihnp4,seismo,topaz}!uwvax!dream!dean
arpa:	dean@dream.wisc.edu

bhs@MITRE-BEDFORD.ARPA (Bev Sobelman) (11/03/86)

This may apply to your constraint error problem:

When you declare a rec variable, are you using the default discriminant 
and then reassigning the whole record, or are you overriding the
default when you declare the record variable?  Consider these:

      Rec_1 : rec (kind => B);     -- this is a constrained record

       --- VS ---

      Rec_2 : rec;                -- this is unconstrained with
          .                          default discrim. = A 
          .
          .
      Rec_2 := (kind => B);       -- now have discrim. = B, still
                                     unconstrained

I haven't looked at the whole thing carefully enough to know whether
this would make a difference at position 'Z', but I thought it was
worth mentioning.

Bev Sobelman
bhs@mitre-bedford.arpa