| -- C392011.A |
| -- |
| -- Grant of Unlimited Rights |
| -- |
| -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687, |
| -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained |
| -- unlimited rights in the software and documentation contained herein. |
| -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making |
| -- this public release, the Government intends to confer upon all |
| -- recipients unlimited rights equal to those held by the Government. |
| -- These rights include rights to use, duplicate, release or disclose the |
| -- released technical data and computer software in whole or in part, in |
| -- any manner and for any purpose whatsoever, and to have or permit others |
| -- to do so. |
| -- |
| -- DISCLAIMER |
| -- |
| -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR |
| -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED |
| -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE |
| -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE |
| -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A |
| -- PARTICULAR PURPOSE OF SAID MATERIAL. |
| --* |
| -- |
| -- OBJECTIVE: |
| -- Check that if a function call with a controlling result is itself |
| -- a controlling operand of an enclosing call on a dispatching operation, |
| -- then its controlling tag value is determined by the controlling tag |
| -- value of the enclosing call. |
| -- |
| -- TEST DESCRIPTION: |
| -- The test builds and traverses a "ragged" list; a linked list which |
| -- contains data elements of three different types (all rooted at |
| -- Level_0'Class). The traversal of this list checks the objective |
| -- by calling the dispatching operation "Check" using an item from the |
| -- list, and calling the function create; thus causing the controlling |
| -- result of the function to be determined by evaluating the value of |
| -- the other controlling parameter to the two-parameter Check. |
| -- |
| -- |
| -- CHANGE HISTORY: |
| -- 22 SEP 95 SAIC Initial version |
| -- 23 APR 96 SAIC Corrected commentary, differentiated integer. |
| -- |
| --! |
| |
| ----------------------------------------------------------------- C392011_0 |
| |
| package C392011_0 is |
| |
| type Level_0 is tagged record |
| Ch_Item : Character; |
| end record; |
| |
| function Create return Level_0; |
| -- primitive dispatching function |
| |
| procedure Check( Left, Right: in Level_0 ); |
| -- has controlling parameters |
| |
| end C392011_0; |
| |
| -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
| |
| with Report; |
| with TCTouch; |
| package body C392011_0 is |
| |
| The_Character : Character := 'A'; |
| |
| function Create return Level_0 is |
| Created_Item_0 : constant Level_0 := ( Ch_Item => The_Character ); |
| begin |
| The_Character := Character'Succ(The_Character); |
| TCTouch.Touch('A'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- A |
| return Created_Item_0; |
| end Create; |
| |
| procedure Check( Left, Right: in Level_0 ) is |
| begin |
| TCTouch.Touch('B'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- B |
| end Check; |
| |
| end C392011_0; |
| |
| ----------------------------------------------------------------- C392011_1 |
| |
| with C392011_0; |
| package C392011_1 is |
| |
| type Level_1 is new C392011_0.Level_0 with record |
| Int_Item : Integer; |
| end record; |
| |
| -- note that Create becomes abstract upon this derivation hence: |
| |
| function Create return Level_1; |
| |
| procedure Check( Left, Right: in Level_1 ); |
| |
| end C392011_1; |
| |
| -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
| |
| with TCTouch; |
| package body C392011_1 is |
| |
| Integer_1 : Integer := 0; |
| |
| function Create return Level_1 is |
| Created_Item_1 : constant Level_1 |
| := ( C392011_0.Create with Int_Item => Integer_1 ); |
| -- note call to ^--------------^ -- A |
| begin |
| Integer_1 := Integer'Succ(Integer_1); |
| TCTouch.Touch('C'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- C |
| return Created_Item_1; |
| end Create; |
| |
| procedure Check( Left, Right: in Level_1 ) is |
| begin |
| TCTouch.Touch('D'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- D |
| end Check; |
| |
| end C392011_1; |
| |
| ----------------------------------------------------------------- C392011_2 |
| |
| with C392011_1; |
| package C392011_2 is |
| |
| type Level_2 is new C392011_1.Level_1 with record |
| Another_Int_Item : Integer; |
| end record; |
| |
| -- note that Create becomes abstract upon this derivation hence: |
| |
| function Create return Level_2; |
| |
| procedure Check( Left, Right: in Level_2 ); |
| |
| end C392011_2; |
| |
| -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
| |
| with TCTouch; |
| package body C392011_2 is |
| |
| Integer_2 : Integer := 100; |
| |
| function Create return Level_2 is |
| Created_Item_2 : constant Level_2 |
| := ( C392011_1.Create with Another_Int_Item => Integer_2 ); |
| -- note call to ^--------------^ -- AC |
| begin |
| Integer_2 := Integer'Succ(Integer_2); |
| TCTouch.Touch('E'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- E |
| return Created_Item_2; |
| end Create; |
| |
| procedure Check( Left, Right: in Level_2 ) is |
| begin |
| TCTouch.Touch('F'); -- --- ---- ----- ---- --- -- --- ---- ----- ---- -- F |
| end Check; |
| |
| end C392011_2; |
| |
| ------------------------------------------------------- C392011_2.C392011_3 |
| |
| with C392011_0; |
| package C392011_2.C392011_3 is |
| |
| type Wide_Reference is access all C392011_0.Level_0'Class; |
| |
| type Ragged_Element; |
| |
| type List_Pointer is access Ragged_Element; |
| |
| type Ragged_Element is record |
| Data : Wide_Reference; |
| Next : List_Pointer; |
| end record; |
| |
| procedure Build_List; |
| |
| procedure Traverse_List; |
| |
| end C392011_2.C392011_3; |
| |
| -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
| |
| package body C392011_2.C392011_3 is |
| |
| The_List : List_Pointer; |
| |
| procedure Build_List is |
| begin |
| |
| -- build a list that looks like: |
| -- Level_2, Level_1, Level_2, Level_1, Level_0 |
| -- |
| -- the mechanism is to create each object, "pushing" the existing list |
| -- onto the end: cons( new_item, car, cdr ) |
| |
| The_List := |
| new Ragged_Element'( new C392011_0.Level_0'(C392011_0.Create), null ); |
| -- Level_0 >> A |
| |
| The_List := |
| new Ragged_Element'( new C392011_1.Level_1'(C392011_1.Create), The_List ); |
| -- Level_1 -> Level_0 >> AC |
| |
| The_List := |
| new Ragged_Element'( new C392011_2.Level_2'(C392011_2.Create), The_List ); |
| -- Level_2 -> Level_1 -> Level_0 >> ACE |
| |
| The_List := |
| new Ragged_Element'( new C392011_1.Level_1'(C392011_1.Create), The_List ); |
| -- Level_1 -> Level_2 -> Level_1 -> Level_0 >> AC |
| |
| The_List := |
| new Ragged_Element'( new C392011_2.Level_2'(C392011_2.Create), The_List ); |
| -- Level_2 -> Level_1 -> Level_2 -> Level_1 -> Level_0 >> ACE |
| |
| end Build_List; |
| |
| procedure Traverse_List is |
| |
| Next_Item : List_Pointer := The_List; |
| |
| -- Check that if a function call with a controlling result is itself |
| -- a controlling operand of an enclosing call on a dispatching operation, |
| -- then its controlling tag value is determined by the controlling tag |
| -- value of the enclosing call. |
| |
| -- Level_2 -> Level_1 -> Level_2 -> Level_1 -> Level_0 |
| |
| begin |
| |
| while Next_Item /= null loop -- here we go! |
| -- these calls better dispatch according to the value in the particular |
| -- list item; causing the call to create to dispatch accordingly. |
| -- why do it twice? To make sure order makes no difference |
| |
| C392011_0.Check(Next_Item.Data.all, C392011_0.Create); |
| -- Create will touch first, then Check touches |
| |
| C392011_0.Check(C392011_0.Create, Next_Item.Data.all); |
| |
| -- Here's what's s'pos'd to 'appen: |
| -- Check( Lev_2, Create ) >> ACEF |
| -- Check( Create, Lev_2 ) >> ACEF |
| -- Check( Lev_1, Create ) >> ACD |
| -- Check( Create, Lev_1 ) >> ACD |
| -- Check( Lev_2, Create ) >> ACEF |
| -- Check( Create, Lev_2 ) >> ACEF |
| -- Check( Lev_1, Create ) >> ACD |
| -- Check( Create, Lev_1 ) >> ACD |
| -- Check( Lev_0, Create ) >> AB |
| -- Check( Create, Lev_0 ) >> AB |
| |
| Next_Item := Next_Item.Next; |
| end loop; |
| end Traverse_List; |
| |
| end C392011_2.C392011_3; |
| |
| ------------------------------------------------------------------- C392011 |
| |
| with Report; |
| with TCTouch; |
| with C392011_2.C392011_3; |
| |
| procedure C392011 is |
| |
| begin -- Main test procedure. |
| |
| Report.Test ("C392011", "Check that if a function call with a " & |
| "controlling result is itself a controlling " & |
| "operand of an enclosing call on a dispatching " & |
| "operation, then its controlling tag value is " & |
| "determined by the controlling tag value of " & |
| "the enclosing call" ); |
| |
| C392011_2.C392011_3.Build_List; |
| TCTouch.Validate( "A" & "AC" & "ACE" & "AC" & "ACE", "Build List" ); |
| |
| C392011_2.C392011_3.Traverse_List; |
| TCTouch.Validate( "ACEFACEF" & |
| "ACDACD" & |
| "ACEFACEF" & |
| "ACDACD" & |
| "ABAB", |
| "Traverse List" ); |
| |
| Report.Result; |
| |
| end C392011; |