-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

with E_Strings;
with LexTokenManager;
with SPARK_IO;
with SP_Symbols;

package body SPrint is

   procedure Print_Node (Node   : in STree.SyntaxNode;
                         Indent : in Natural)
   --# global in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                Indent,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                STree.Table;
   is
      Node_Type : SP_Symbols.SP_Symbol;

      procedure Put_Node_Type
      --# global in     Node_Type;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                Node_Type;
      is
         -- Use 'Image here for convenience, so hide...
         --# hide Put_Node_Type;
      begin
         SPARK_IO.Put_String (SPARK_IO.Standard_Output, SP_Symbols.SP_Symbol'Image (Node_Type), 0);
      end Put_Node_Type;

   begin
      Node_Type := STree.Syntax_Node_Type (Node => Node);

      SPARK_IO.Put_Integer (File  => SPARK_IO.Standard_Output,
                            Item  => Integer (STree.NodeToRef (Node)),
                            Width => 6,
                            Base  => 10);
      SPARK_IO.Put_Char (SPARK_IO.Standard_Output, ' ');

      for I in Natural range 1 .. Indent loop
         SPARK_IO.Put_Char (SPARK_IO.Standard_Output, '-');
      end loop;

      Put_Node_Type;

      case Node_Type is

         when SP_Symbols.identifier        |
           SP_Symbols.integer_number    |
           SP_Symbols.real_number       |
           SP_Symbols.based_integer     |
           SP_Symbols.based_real        |
           SP_Symbols.character_literal |
           SP_Symbols.string_literal    =>

            SPARK_IO.Put_Char (SPARK_IO.Standard_Output, ' ');
            E_Strings.Put_String
              (File  => SPARK_IO.Standard_Output,
               E_Str => LexTokenManager.Lex_String_To_String (Lex_Str => STree.Node_Lex_String (Node => Node)));

         when others =>
            null;
      end case;

      SPARK_IO.New_Line (SPARK_IO.Standard_Output, 1);
   end Print_Node;

   procedure Recursive_Dump (Node   : in STree.SyntaxNode;
                             Indent : in Natural)
   --# global in     LexTokenManager.State;
   --#        in     STree.Table;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                Indent,
   --#                                LexTokenManager.State,
   --#                                Node,
   --#                                STree.Table;
   is
      -- Recurse all ye who enter here!
      --# hide Recursive_Dump;
      Child : STree.SyntaxNode;
   begin
      -- pre-order traversal;
      Print_Node (Node, Indent);

      Child := STree.Child_Node (Current_Node => Node);

      while Child /= STree.NullNode loop
         Recursive_Dump (Child, Indent + 3);
         Child := STree.Next_Sibling (Current_Node => Child);
      end loop;
   end Recursive_Dump;

   ----------------------
   -- Dump_Syntax_Tree --
   ----------------------

   procedure Dump_Syntax_Tree (Node   : in STree.SyntaxNode;
                               Indent : in Natural) is
   begin
      SPARK_IO.New_Line (SPARK_IO.Standard_Output, 1);
      SPARK_IO.Put_String (SPARK_IO.Standard_Output, "Dump of syntax tree for node ", 0);
      Print_Node (Node, 0);
      SPARK_IO.New_Line (SPARK_IO.Standard_Output, 1);

      Recursive_Dump (Node, Indent);

   end Dump_Syntax_Tree;

end SPrint;
