[comp.lang.ada] Nasty Expanded Names Semantics

mendal@SIERRA.STANFORD.EDU (Geoffrey O. Mendal) (06/20/88)

Dear Ada Fans-

After a long Spring of not asking any silly questions, we're back!
We've run the following code through the Verdix VADS and DEC-Ada
compilers with different results.  At issue is what is meant by
the following sentence found in 4.1.3(17):

  In the case of an accept statement, the prefix must be either the
  simple name of the entry or entry family, or an expanded name
  ending with such a simple name (that is, no index is allowed).

Here's our test case:

  procedure Nested_Accepts is
    task T is
      entry X (I : in out Integer);
      entry Y (I : in out Integer);
      entry Z (I : in out Integer);
    end T;

    task body T is
    begin
      accept X (I : in out Integer) do
        accept Y (I : in out Integer) do
          accept Z (I : in out Integer) do
            I := X.Y.I;                    -- 1.
            I := Z.I;                      -- 2.
	    I := X.I;                      -- 3.
            I := T.Y.I;                    -- 4.
            I := Nested_Accepts.T.X.I;     -- 5.
          end Z;
        end Y;
      end X;
    end T;
  begin
    null;  -- No illegality here! :-)
  end Nested_Accepts;

Specifically, what does the phrase "ending with such a simple name" mean?
Does it mean the last simple name of the entire prefix or does it mean
the "tail" of the entire prefix (strip off the first name of the prefix)?

Clearly, statement #1 above is illegal by any interpretation of 4.1.3(17).
Also, statements #2 and #3 would seem to be clearly legal.  The problem
of interpretation comes in with statements #4 and #5.  Are they both
legal or illegal?  Different compilers give different answers.

The Compiler Implementors Guide and Ada Rapporteur Group Notes do not
seem to tackle this issue, so we're asking you.

Thanks in advance for any (correct) answers.

Geoff and Doug

rracine@AJPO.SEI.CMU.EDU (06/22/88)

Geoffrey O. Mendal asks a reasonable question about the semantics of 
naming entries. His code is:

procedure Nested_Accepts is
  task T is
    entry X (I : in out Integer);
    entry Y (I : in out Integer);
    entry Z (I : in out Integer);
  end T;

  task body T is
  begin
    accept X (I : in out Integer) do
      accept Y (I : in out Integer) do
        accept Z (I : in out Integer) do
          I := X.Y.I;                    -- 1.
          I := Z.I;                      -- 2.
          I := X.I;                      -- 3.
          I := T.Y.I;                    -- 4.
          I := Nested_Accepts.T.X.I;     -- 5.
        end Z;
      end Y;
    end X;
  end T;
begin
  null;  -- No illegality here! :-)
end Nested_Accepts;

After reading the section of the LRM in question (4.1.3), I am amazed that
either #4 or #5 could be thought to be illegal.  Paragraph 17, to me, 
is simply trying to disallow the index of an entry family.

I tried the code on three compilers, and got three different results,
including the result I want (only #1 is an error).  All of these compilers
are the latest versions.

DEC Ada has #1, #4 and #5 as errors.
Verdix (on VAX, targeted to 68020) has #1 and #5 as errors.
Meridian (on IBM PC) has only #1 as error.

This is a good candidate for an ACVC test.

Roger Racine

arny@wayback.UUCP (Arny B. Engelson) (06/24/88)

In article <8806200116.AA02895@ajpo.sei.cmu.edu>, mendal@SIERRA.STANFORD.EDU (Geoffrey O. Mendal) writes:
: We've run the following code through the Verdix VADS and DEC-Ada
: compilers with different results.  At issue is what is meant by
: the following sentence found in 4.1.3(17):
: 
:   In the case of an accept statement, the prefix must be either the
:   simple name of the entry or entry family, or an expanded name
:   ending with such a simple name (that is, no index is allowed).
: 
: Here's our test case:
: 
:   procedure Nested_Accepts is
:     task T is
:       entry X (I : in out Integer);
:       entry Y (I : in out Integer);
:       entry Z (I : in out Integer);
:     end T;
: 
:     task body T is
:     begin
:       accept X (I : in out Integer) do
:         accept Y (I : in out Integer) do
:           accept Z (I : in out Integer) do
:             I := X.Y.I;                    -- 1.
:             I := Z.I;                      -- 2.
: 	      I := X.I;                      -- 3.
:             I := T.Y.I;                    -- 4.
:             I := Nested_Accepts.T.X.I;     -- 5.
:           end Z;
:         end Y;
:       end X;
:     end T;
:   begin
:     null;  -- No illegality here! :-)
:   end Nested_Accepts;
: 
: Specifically, what does the phrase "ending with such a simple name" mean?
: Does it mean the last simple name of the entire prefix or does it mean
: the "tail" of the entire prefix (strip off the first name of the prefix)?

I interpret this as meaning the LAST simple name of the entire prefix.
Why?  Aside from that being my off-the-cuff interpretation of "ending",
I can't think of a legitimate reason to make it mean the "tail".  This
would prohibit the recursive application of the rule, as I use it below.

Having ending mean the tail limits the expanded name to the first name
of the prefix, followed by the simple name.  I don't think this is a
good idea, and I also think if this is what was intended, it would have
been explicitly specified that way.


: Clearly, statement #1 above is illegal by any interpretation of 4.1.3(17).
: Also, statements #2 and #3 would seem to be clearly legal.  The problem
: of interpretation comes in with statements #4 and #5.  Are they both
: legal or illegal?  Different compilers give different answers.
: 
: The Compiler Implementors Guide and Ada Rapporteur Group Notes do not
: seem to tackle this issue, so we're asking you.
: 
: Thanks in advance for any (correct) answers.
: 
: Geoff and Doug


After reading 4.1.3, I believe statements #4 and #5 are both legal.
In both cases, the prefix is an expanded name ending with the simple
name of the entry in which "I" is immediately declared.  By recursive
application of the rules for expanded names, these prefixes are legal.

             I := T.Y.I;                    -- 4.

   In this case, the prefix for "I" denotes the entry "Y", which is
   an expanded name ending with the simple name of the entry (see para
   17, sentence 2).  This expanded name "T.Y" is legal because "T"
   denotes the program unit (task) in which the entry is immediately
   declared (I am not sure if 9-10 or 16-17 apply here, though).


             I := Nested_Accepts.T.X.I;     -- 5.

   Taken one step further (via recursively applying paragraphs 16-17), 
   this seems OK too.  "T" is declared immediately within the program
   unit (procedure) "Nested_Accepts".


  - Arny Engelson