-------------------------------------------------------------------------------
-- (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 (SparkLex.Lex)
procedure HyphIntro (Curr_Line : in out Line_Context;
                     Token     :    out SP_Symbols.SP_Terminal) is
   Ch1, Ch2  : Character;
   Anno_Kind : Anno_Type;
begin
   -- Hyphen already recognised, but do not accept it in case it introduces the
   -- annotation symbol of an annotation which requires the end_of_annotation
   -- token to inserted infront.
   LineManager.Lookahead_Char (Curr_Line => Curr_Line,
                               Ch        => Ch1);
   if Ch1 = '-' then
      LineManager.Lookahead_Char (Curr_Line => Curr_Line,
                                  Ch        => Ch2);

      if Ch2 = CommandLineData.Content.Anno_Char then
         if Curr_Line.Anno_Context = Mid_Annotation then
            Check_Anno_Type (Curr_Line       => Curr_Line,
                             Unfinished_Anno => True,
                             Anno_Kind       => Anno_Kind);
         else
            Check_Anno_Type (Curr_Line       => Curr_Line,
                             Unfinished_Anno => False,
                             Anno_Kind       => Anno_Kind);
         end if;

         case Anno_Kind is
            when Hide_Anno =>
               if Curr_Line.Context = In_Annotation then
                  LineManager.Reject_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.annotation_end;
               else
                  LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.hide_directive;
               end if;
            when Start_Anno =>
               if Curr_Line.Context = In_Annotation then
                  LineManager.Reject_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.annotation_end;
               else
                  LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.annotation_start;
               end if;
            when Proof_Anno =>
               if Curr_Line.Context = In_Annotation then
                  LineManager.Reject_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.annotation_end;
               else
                  LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
                  Token := SP_Symbols.proof_context;
               end if;
            when Other_Anno =>
               LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
               -- Making the following assignement means that the if --# is
               -- followed by an identifier (i.e. we have a proof constant declaration)
               -- then the --# will be treated as a beginning a proof context rather
               -- than an annotation.
               Token := SP_Symbols.proof_context;
            when No_Anno =>
               LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
               Token := SP_Symbols.comment;
         end case;
      else
         LineManager.Reject_Lookahead (Curr_Line => Curr_Line);
         LineManager.Accept_Char (Curr_Line => Curr_Line);
         LineManager.Accept_Char (Curr_Line => Curr_Line);

         while (Curr_Line.Curr_Pos <= E_Strings.Get_Length (E_Str => Curr_Line.Conts)
                  and then Ch2 /= End_Of_Text
                  and then not Format_Effector (Ch => Ch2))
           or else Ch2 = Ada.Characters.Latin_1.HT loop
            --# assert E_Strings.Get_Length (Curr_Line.Conts) = E_Strings.Get_Length (Curr_Line~.Conts) and
            --#   Curr_Line.Curr_Pos > Curr_Line~.Curr_Pos and
            --#   Curr_Line.Curr_Pos <= E_Strings.Get_Length (Curr_Line.Conts) + 1 and
            --#   Curr_Line.Lookahead_Pos = Curr_Line.Curr_Pos and
            --#   Curr_Line.Last_Token_Pos = Curr_Line~.Last_Token_Pos;
            LineManager.Accept_Char (Curr_Line => Curr_Line);
            Ch2 := E_Strings.Get_Element (E_Str => Curr_Line.Conts,
                                          Pos   => Curr_Line.Curr_Pos);
         end loop;
         Token := SP_Symbols.comment;
      end if;

   elsif Ch1 = '>' then
      LineManager.Accept_Lookahead (Curr_Line => Curr_Line);
      Token := SP_Symbols.implies;
   else
      LineManager.Reject_Lookahead (Curr_Line => Curr_Line);
      LineManager.Accept_Char (Curr_Line => Curr_Line);
      Token := SP_Symbols.minus;
   end if;
end HyphIntro;
