comp.lang.ada
 help / color / mirror / Atom feed
From: okellogg@freenet.de (Oliver Kellogg)
Subject: Re: child packages and nested packages
Date: 23 Apr 2002 14:44:49 -0700
Date: 2002-04-23T21:44:49+00:00	[thread overview]
Message-ID: <6a6390b8.0204231344.6fd957ca@posting.google.com> (raw)
In-Reply-To: 6a6390b8.0203251126.8eebc37@posting.google.com

I'm attempting to implement this feature (permitting a nested
package as the parent the of a child package) in GNAT.
Since it's just a proof of concept, I'm doing this only for the
simple case where the parent is nested exactly one deep.
However, I'm having a problem. It seems to relate to

  Names : List_Id := New_List (Defining_Unit_Name (Specification (Decl)));

in the bottom page of the added code block below.
Later, while Analyze_Use_Package loops through the Names, the Nkind
of the (first and only) name node appears not to have been set.
I'm sure there's something wrong with the way I synthesize the use
clause.  Help, anyone?


*** par-load.adb.orig   Thu Mar 14 10:59:36 2002
--- par-load.adb        Tue Apr 23 22:25:25 2002
***************
*** 290,301 ****
           Unum :=
             Load_Unit
               (Load_Name  => Spec_Name,
!               Required   => True,
                Subunit    => False,
                Error_Node => Curunit);
  
           if Unum /= No_Unit then
              Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
           end if;
        end if;
  
--- 290,383 ----
           Unum :=
             Load_Unit
               (Load_Name  => Spec_Name,
!               Required   => False,
                Subunit    => False,
                Error_Node => Curunit);
  
           if Unum /= No_Unit then
              Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+          else
+             --  The Spec_Name may refer to a nested package.
+             Spec_Name := Get_Parent_Spec_Name (Spec_Name);
+             if Spec_Name /= No_Name then
+                Unum :=
+                  Load_Unit
+                    (Load_Name  => Spec_Name,
+                     Required   => True,
+                     Subunit    => False,
+                     Error_Node => Curunit);
+                if Unum /= No_Unit then
+                   Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+                   --  Check that the referenced nested package exists.
+                   declare
+                      function Infix (Threefix : String) return String;
+                      --  Given a name "A.B.C", returns "B".
+                      --  Returns "" if the input name does not contain
+                      --  two periods.
+                      function Infix (Threefix : String) return String is
+                         I1 : Natural := Threefix'First;
+                         I2 : Natural;
+                      begin
+                         while I1 <= Threefix'Last
+                           and then Threefix (I1) /= '.' loop
+                            I1 := I1 + 1;
+                         end loop;
+                         if I1 = Threefix'Last then
+                            return "";
+                         end if;
+                         I1 := I1 + 1;
+                         I2 := I1;
+                         while I2 <= Threefix'Last
+                           and then Threefix (I2) /= '.' loop
+                            I2 := I2 + 1;
+                         end loop;
+                         if I2 = Threefix'Last then
+                            return "";
+                         end if;
+                         return Threefix (I1 .. I2 - 1);
+                      end Infix;
+                      Found : Boolean := False;
+                      Spec : Node_Id := Specification (Unit (Cunit (Unum)));
+                      Decls : List_Id := Visible_Declarations (Spec);
+                      Decl : Node_Id := First (Decls);
+                      Nested_Name : String
+                        := Infix (Get_Name_String (Unit_Name (Cur_Unum)));
+                      Pkg_Name : Name_Id;
+                   begin
+                      while Present (Decl) loop
+                         if Nkind (Decl) = N_Package_Declaration then
+                            Pkg_Name :=
+                              Chars (Defining_Unit_Name (Specification (Decl)))
;
+                            if Get_Name_String (Pkg_Name) = Nested_Name then
+                               Found := True;
+                               exit;
+                            end if;
+                         end if;
+                         Next (Decl);
+                      end loop;
+                      if Found then
+                         Set_Parent_Spec (Unit (Curunit), Cunit (Unum));
+                         --  Synthesize a use clause for the parent package.
+                         declare
+                            Names : List_Id
+                              := New_List
+                                (Defining_Unit_Name (Specification (Decl)));
+                            Use_Nested_Parent : Node_Id
+                              := Make_Use_Package_Clause (Loc, Names);
+                         begin
+                            Prepend_To
+                              (Visible_Declarations
+                                 (Specification (Unit (Curunit))),
+                                  Use_Nested_Parent);
+                            Mark_Rewrite_Insertion (Use_Nested_Parent);
+                         end;
+                      else
+                         Error_Msg ("parent package not found", Loc);
+                      end if;
+                   end;
+ 
+                end if;
+             end if;
           end if;
        end if;



  parent reply	other threads:[~2002-04-23 21:44 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-03-23 15:02 child packages and nested packages Oliver Kellogg
2002-03-25 15:01 ` Ted Dennison
2002-03-25 19:26   ` Oliver Kellogg
2002-03-25 22:31     ` Stephen Leake
2002-04-23 21:44     ` Oliver Kellogg [this message]
2002-04-24 14:52       ` Oliver Kellogg
2002-03-26 14:21   ` Marin David Condic
2002-03-28  9:51 ` Oliver Kellogg
2002-03-28 14:49   ` Ted Dennison
2002-03-28 18:30     ` Oliver Kellogg
2002-03-28 22:13       ` Ted Dennison
2002-03-29  5:30         ` Oliver Kellogg
2002-03-29 11:59           ` Sergey Koshcheyev
2002-03-29 15:14             ` Ted Dennison
2002-03-29 13:05           ` Oliver Kellogg
  -- strict thread matches above, loose matches on Subject: below --
2010-03-04  5:37 Oliver Kellogg
2010-03-04 14:55 ` Admin - Do Not Email
2010-03-04 16:12 ` Adam Beneschan
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox