-------------------------------------------------------------------------------
-- (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 Cells;

--# inherit Cells,
--#         Cell_Storage,
--#         Dictionary,
--#         LexTokenManager,
--#         SP_Symbols,
--#         Statistics,
--#         SystemErrors;

package Cells.Utility is

   type Type_Attribute is (Tick_First, Tick_Last);

   ------------------------------------------------------------------------------
   --  General utility
   ------------------------------------------------------------------------------

   procedure Create_Binary_Op_Cell
     (VCG_Heap : in out Cells.Heap_Record;
      Left     : in     Cells.Cell;
      Op       : in     SP_Symbols.SP_Symbol;
      Right    : in     Cells.Cell;
      Result   :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Result                from VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Left,
   --#                                    Op,
   --#                                    Right;

   ------------------------------------------------------------------------------
   --  Booleans
   ------------------------------------------------------------------------------

   function Is_True (VCG_Heap : in Cells.Heap_Record;
                     C        : in Cells.Cell) return Boolean;
   --# global in Dictionary.Dict;

   function Is_False (VCG_Heap : in Cells.Heap_Record;
                      C        : in Cells.Cell) return Boolean;
   --# global in Dictionary.Dict;

   procedure Create_Bool (VCG_Heap : in out Cells.Heap_Record;
                          Value    : in     Boolean;
                          C        :    out Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out Statistics.TableUsage;
   --# derives C                     from VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Dictionary.Dict,
   --#                                    Value;

   procedure Create_Not (VCG_Heap  : in out Cells.Heap_Record;
                         Predicate : in     Cells.Cell;
                         Negation  :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Negation              from VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Predicate;

   procedure Create_And
     (VCG_Heap : in out Cells.Heap_Record;
      Left     : in     Cells.Cell;
      Right    : in     Cells.Cell;
      Conjunct :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Conjunct              from VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Left,
   --#                                    Right;

   procedure Create_Implies
     (VCG_Heap    : in out Cells.Heap_Record;
      Antecedent  : in     Cells.Cell;
      Consequent  : in     Cells.Cell;
      Implication :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Implication           from VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Antecedent,
   --#                                    Consequent;

   procedure Simplify (VCG_Heap : in out Cells.Heap_Record;
                       C        : in out Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out Statistics.TableUsage;
   --# derives C,
   --#         Statistics.TableUsage,
   --#         VCG_Heap              from *,
   --#                                    C,
   --#                                    Dictionary.Dict,
   --#                                    VCG_Heap;

   ------------------------------------------------------------------------------
   --  Utility
   ------------------------------------------------------------------------------

   --  Join New_Term into the Conjuct.
   procedure Conjoin (VCG_Heap : in out Cells.Heap_Record;
                      New_Term : in     Cells.Cell;
                      Conjunct : in out Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out Statistics.TableUsage;
   --# derives Conjunct,
   --#         Statistics.TableUsage,
   --#         VCG_Heap              from *,
   --#                                    Conjunct,
   --#                                    Dictionary.Dict,
   --#                                    New_Term,
   --#                                    VCG_Heap;

   ------------------------------------------------------------------------------
   --  Types (general)
   ------------------------------------------------------------------------------

   --  This produces the DAG for The_Type'First, etc...
   procedure Create_Type_Attribute
     (VCG_Heap      : in out Cells.Heap_Record;
      The_Type      : in     Dictionary.Symbol;
      The_Attribute : in     Type_Attribute;
      Result        :    out Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out Statistics.TableUsage;
   --# derives Result,
   --#         VCG_Heap              from Dictionary.Dict,
   --#                                    The_Attribute,
   --#                                    The_Type,
   --#                                    VCG_Heap &
   --#         Statistics.TableUsage from *,
   --#                                    Dictionary.Dict,
   --#                                    The_Attribute,
   --#                                    The_Type,
   --#                                    VCG_Heap;

   ------------------------------------------------------------------------------
   --  Records
   ------------------------------------------------------------------------------

   procedure Create_Record_Access
     (VCG_Heap      : in out Cells.Heap_Record;
      The_Record    : in     Cells.Cell;
      The_Component : in     Dictionary.Symbol;
      The_Field     :    out Cells.Cell);
   --# global in     Dictionary.Dict;
   --#        in out Statistics.TableUsage;
   --# derives Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         The_Field             from VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    Dictionary.Dict,
   --#                                    The_Component,
   --#                                    The_Record;

   ------------------------------------------------------------------------------
   --  Arrays
   ------------------------------------------------------------------------------

   procedure Create_Array_Access
     (VCG_Heap    : in out Cells.Heap_Record;
      The_Array   : in     Cells.Cell;
      The_Index   : in     Cells.Cell;
      The_Element :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Statistics.TableUsage,
   --#         VCG_Heap              from *,
   --#                                    The_Array,
   --#                                    The_Index,
   --#                                    VCG_Heap &
   --#         The_Element           from The_Array,
   --#                                    The_Index,
   --#                                    VCG_Heap;

   ------------------------------------------------------------------------------
   --  Stashing things in cells that we probably shouldn't.
   ------------------------------------------------------------------------------

   procedure Create_Scope_Cell
     (VCG_Heap  : in out Cells.Heap_Record;
      The_Scope : in     Dictionary.Scopes;
      The_Cell  :    out Cells.Cell);
   --# global in out Statistics.TableUsage;
   --# derives Statistics.TableUsage from *,
   --#                                    VCG_Heap &
   --#         The_Cell              from VCG_Heap &
   --#         VCG_Heap              from *,
   --#                                    The_Scope;

   function Scope_Cell_Get_Scope (VCG_Heap   : in Cells.Heap_Record;
                                  Scope_Cell : in Cells.Cell) return Dictionary.Scopes;

end Cells.Utility;
