-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (Sem)
procedure Check_Closing_Identifier (End_Name_Node, Ident_Node : in STree.SyntaxNode) is
   Start_Ident_Node : STree.SyntaxNode;
   End_Ident_Node   : STree.SyntaxNode;
begin
   Start_Ident_Node := Ident_Node;
   End_Ident_Node   := Last_Child_Of (Start_Node => End_Name_Node);
   -- ASSUME End_Ident_Node = identifier
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => End_Ident_Node) = SP_Symbols.identifier,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect End_Ident_Node = identifier in Check_Closing_Identifier");
   loop
      --# assert Syntax_Node_Type (End_Name_Node, STree.Table) = SP_Symbols.dotted_simple_name and
      --#   Syntax_Node_Type (Start_Ident_Node, STree.Table) = SP_Symbols.identifier and
      --#   Syntax_Node_Type (End_Ident_Node, STree.Table) = SP_Symbols.identifier;

      -- check identifiers at current positions:
      if LexTokenManager.Lex_String_Case_Insensitive_Compare
        (Lex_Str1 => Node_Lex_String (Node => Start_Ident_Node),
         Lex_Str2 => Node_Lex_String (Node => End_Ident_Node)) /=
        LexTokenManager.Str_Eq then
         ErrorHandler.Semantic_Error
           (Err_Num   => 58,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => End_Ident_Node),
            Id_Str    => Node_Lex_String (Node => Start_Ident_Node));
         exit;
      end if;

      -- move on to next identifiers:
      Start_Ident_Node := Next_Sibling (Current_Node => Parent_Node (Current_Node => Start_Ident_Node));
      End_Ident_Node   := Next_Sibling (Current_Node => Parent_Node (Current_Node => End_Ident_Node));

      -- finished when both exhausted:
      exit when Syntax_Node_Type (Node => Start_Ident_Node) /= SP_Symbols.identifier
        and then Syntax_Node_Type (Node => End_Ident_Node) /= SP_Symbols.identifier;

      -- check if only one exhausted (length mismatch):
      if Syntax_Node_Type (Node => Start_Ident_Node) /= SP_Symbols.identifier
        or else Syntax_Node_Type (Node => End_Ident_Node) /= SP_Symbols.identifier then
         ErrorHandler.Semantic_Error
           (Err_Num   => 615,
            Reference => ErrorHandler.No_Reference,
            Position  => Node_Position (Node => End_Name_Node),
            Id_Str    => LexTokenManager.Null_String);
         exit;
      end if;
   end loop;
end Check_Closing_Identifier;
