--------------------------------
-- Ivan Levashew aka OCTAGRAM --
--              Barnaul, 2009 --
--------------------------------

-- Convenient definitions mainly
-- inspired by Turbo Pascal (and Delphi)

with
   System, Interfaces, Turbo_Platform.Bits;

use
   System, Interfaces;

package Turbo is
   pragma Preelaborate;

   ------------------------------------
   -- Pointer types for Interfaces.* --
   ------------------------------------

   type A_Integer_8 is access all Integer_8;
   type A_Integer_16 is access all Integer_16;
   type A_Integer_32 is access all Integer_32;
   type A_Integer_64 is access all Integer_64;

   type A_Unsigned_8 is access all Unsigned_8;
   type A_Unsigned_16 is access all Unsigned_16;
   type A_Unsigned_32 is access all Unsigned_32;
   type A_Unsigned_64 is access all Unsigned_64;

   ----------------
   -- Boolean_32 --
   ----------------

   type Boolean_32 is private;
   type A_Boolean_32 is access all Boolean_32;

   False_32 : constant Boolean_32;
   True_32  : constant Boolean_32;

   function "+" (Item : Boolean_32) return Boolean;

   function "+" (Item : Boolean_32) return Integer_32;

   function "+" (Item : Boolean) return Boolean_32;

   function "+" (Item : Integer_32) return Boolean_32;

   function "=" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "=" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "=" (Left, Right : Boolean_32) return Boolean;

   function ">" (Left : Boolean_32; Right : Boolean) return Boolean;
   function ">" (Left : Boolean; Right : Boolean_32) return Boolean;
   function ">" (Left, Right : Boolean_32) return Boolean;

   function "<" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "<" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "<" (Left, Right : Boolean_32) return Boolean;

   function ">=" (Left : Boolean_32; Right : Boolean) return Boolean;
   function ">=" (Left : Boolean; Right : Boolean_32) return Boolean;
   function ">=" (Left, Right : Boolean_32) return Boolean;

   function "<=" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "<=" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "<=" (Left, Right : Boolean_32) return Boolean;

   function "and" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "and" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "and" (Left, Right : Boolean_32) return Boolean;

   function "or" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "or" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "or" (Left, Right : Boolean_32) return Boolean;

   function "xor" (Left : Boolean_32; Right : Boolean) return Boolean;
   function "xor" (Left : Boolean; Right : Boolean_32) return Boolean;
   function "xor" (Left, Right : Boolean_32) return Boolean;

   function "not" (Item : Boolean_32) return Boolean;

   pragma Inline ("=", ">", "<", ">=", "<=", "+", "and", "or", "xor", "not");

   ----------------
   -- Boolean_16 --
   ----------------

   type Boolean_16 is private;
   type A_Boolean_16 is access all Boolean_16;

   False_16 : constant Boolean_16;
   True_16  : constant Boolean_16;

   function "+" (Item : Boolean_16) return Boolean;

   function "+" (Item : Boolean_16) return Integer_16;

   function "+" (Item : Boolean) return Boolean_16;

   function "+" (Item : Integer_16) return Boolean_16;

   function "=" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "=" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "=" (Left, Right : Boolean_16) return Boolean;

   function ">" (Left : Boolean_16; Right : Boolean) return Boolean;
   function ">" (Left : Boolean; Right : Boolean_16) return Boolean;
   function ">" (Left, Right : Boolean_16) return Boolean;

   function "<" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "<" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "<" (Left, Right : Boolean_16) return Boolean;

   function ">=" (Left : Boolean_16; Right : Boolean) return Boolean;
   function ">=" (Left : Boolean; Right : Boolean_16) return Boolean;
   function ">=" (Left, Right : Boolean_16) return Boolean;

   function "<=" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "<=" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "<=" (Left, Right : Boolean_16) return Boolean;

   function "and" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "and" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "and" (Left, Right : Boolean_16) return Boolean;

   function "or" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "or" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "or" (Left, Right : Boolean_16) return Boolean;

   function "xor" (Left : Boolean_16; Right : Boolean) return Boolean;
   function "xor" (Left : Boolean; Right : Boolean_16) return Boolean;
   function "xor" (Left, Right : Boolean_16) return Boolean;

   function "not" (Item : Boolean_16) return Boolean;

   pragma Inline ("=", ">", "<", ">=", "<=", "+", "and", "or", "xor", "not");

   ---------------
   -- Boolean_8 --
   ---------------

   type Boolean_8 is private;
   type A_Boolean_8 is access all Boolean_8;

   False_8 : constant Boolean_8;
   True_8  : constant Boolean_8;

   function "+" (Item : Boolean_8) return Boolean;

   function "+" (Item : Boolean_8) return Integer_8;

   function "+" (Item : Boolean) return Boolean_8;

   function "+" (Item : Integer_8) return Boolean_8;

   function "=" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "=" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "=" (Left, Right : Boolean_8) return Boolean;

   function ">" (Left : Boolean_8; Right : Boolean) return Boolean;
   function ">" (Left : Boolean; Right : Boolean_8) return Boolean;
   function ">" (Left, Right : Boolean_8) return Boolean;

   function "<" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "<" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "<" (Left, Right : Boolean_8) return Boolean;

   function ">=" (Left : Boolean_8; Right : Boolean) return Boolean;
   function ">=" (Left : Boolean; Right : Boolean_8) return Boolean;
   function ">=" (Left, Right : Boolean_8) return Boolean;

   function "<=" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "<=" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "<=" (Left, Right : Boolean_8) return Boolean;

   function "and" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "and" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "and" (Left, Right : Boolean_8) return Boolean;

   function "or" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "or" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "or" (Left, Right : Boolean_8) return Boolean;

   function "xor" (Left : Boolean_8; Right : Boolean) return Boolean;
   function "xor" (Left : Boolean; Right : Boolean_8) return Boolean;
   function "xor" (Left, Right : Boolean_8) return Boolean;

   function "not" (Item : Boolean_8) return Boolean;

   pragma Inline ("=", ">", "<", ">=", "<=", "+", "and", "or", "xor", "not");

   -------------
   -- Strings --
   -------------

   type Buffer_8 is new String;
   type Buffer_16 is new Wide_String;
   type Buffer_32 is new Wide_Wide_String;

   subtype Char_8 is Character;
   subtype Char_16 is Wide_Character;
   subtype Char_32 is Wide_Wide_Character;

   NUL_8 : constant Char_8 := Char_8'Val (0);
   NUL_16 : constant Char_16 := Char_16'Val (0);
   NUL_32 : constant Char_32 := Char_32'Val (0);

   type A_Char_8 is new System.Address;
   type A_Char_16 is new System.Address;
   type A_Char_32 is new System.Address;

   type A_A_Char_8 is access all A_Char_8;
   type A_A_Char_16 is access all A_Char_16;
   type A_A_Char_32 is access all A_Char_32;

   ---------------
   -- A_Address --
   ---------------

   type A_Address is access all System.Address;
--   type P_P_Address is access all P_Address;

--   No GUID in Turbo!
--     ----------
--     -- GUID --
--     ----------
--
--     type T_GUID_D4 is
--       array (0 .. 7) of Unsigned_8;
--     pragma Pack (T_GUID_D4);
--
--     type T_GUID is record
--        D1 : Unsigned_32;
--        D2 : Unsigned_16;
--        D3 : Unsigned_16;
--        D4 : T_GUID_D4;
--     end record;
--     pragma Pack (T_GUID);
--
--     type A_GUID is access all T_GUID;

   -----------------
   -- Integer_Ptr --
   -----------------

   type Integer_Ptr is new Turbo_Platform.Bits.Integer_Ptr_Internal;
   type Unsigned_Ptr is new Turbo_Platform.Bits.Unsigned_Ptr_Internal;

   type A_Integer_Ptr is access all Integer_Ptr;
   type A_Unsigned_Ptr is access all Unsigned_Ptr;

   -- type T_Handle is new Integer_Ptr; -- no T_Handle in Turbo!
   -- type A_Handle is access all T_Handle;
   -- TODO: deny most integer operations

private

   type Boolean_32 is new Integer_32;

   False_32 : constant Boolean_32 := 0;
   True_32  : constant Boolean_32 := 1;

   type Boolean_16 is new Integer_16;

   False_16 : constant Boolean_16 := 0;
   True_16  : constant Boolean_16 := 1;

   type Boolean_8 is new Integer_8;

   False_8 : constant Boolean_8 := 0;
   True_8  : constant Boolean_8 := 1;

end Turbo;
