<commit_before>-----------------------------------------------------------------------
--  EL.Objects -- Generic Typed Data Representation
--  Copyright (C) 2009, 2010 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

--  package EL
--  package EL.Expressions
--  package EL.Objects
with Ada.Characters.Conversions;
with Ada.Calendar.Formatting;
with Ada.Calendar.Conversions;
with Interfaces.C;
with EL.Beans;
package body EL.Objects is

   use Ada.Characters.Conversions;
   use Ada.Calendar.Formatting;
   use type Interfaces.C.long;

   type String_Access is access constant String;

   --  Find the data type to be used for an arithmetic operation between two objects.
   function Get_Arithmetic_Type (Left, Right : Object) return Data_Type;

   --  Find the data type to be used for a composition operation between two objects.
   function Get_Compose_Type (Left, Right : Object) return Data_Type;

   --  Find the best type to be used to compare two operands.
   function Get_Compare_Type (Left, Right : Object) return Data_Type;

   function "+"(Str : in String)
                return Unbounded_String renames To_Unbounded_String;

   type Basic_Type is new Object_Type with record
      Name : String_Access;
   end record;

   --  Get the type name
   function Get_Name (Type_Def : Basic_Type) return String;

   --  Translate the object
   function To_String (Type_Def : Basic_Type;
                       Value    : in Object) return String;

   INTEGER_NAME     : aliased constant String := "Integer";
   BOOLEAN_NAME     : aliased constant String := "Boolean";
   STRING_NAME      : aliased constant String := "String";
   WIDE_STRING_NAME : aliased constant String := "Wide_Wide_String";
   FLOAT_NAME       : aliased constant String := "Float";
   TIME_NAME        : aliased constant String := "Time";
   BEAN_NAME        : aliased constant String := "Bean";

   Integer_Type     : aliased constant Basic_Type := Basic_Type '(Name => INTEGER_NAME'Access);
   Boolean_Type     : aliased constant Basic_Type := Basic_Type '(Name => BOOLEAN_NAME'Access);
   String_Type      : aliased constant Basic_Type := Basic_Type '(Name => STRING_NAME'Access);
   Wide_String_Type : aliased constant Basic_Type := Basic_Type '(Name => WIDE_STRING_NAME'Access);
   Float_Type       : aliased constant Basic_Type := Basic_Type '(Name => FLOAT_NAME'Access);
   Time_Type        : aliased constant Basic_Type := Basic_Type '(Name => TIME_NAME'Access);
   Bean_Type        : aliased constant Basic_Type := Basic_Type '(Name => BEAN_NAME'Access);

   --  ------------------------------
   --  Get the type name
   --  ------------------------------
   function Get_Name (Type_Def : Basic_Type) return String is
   begin
      return Type_Def.Name.all;
   end Get_Name;

   --  ------------------------------
   --  Check whether the object contains a value.
   --  Returns true if the object does not contain a value.
   --  ------------------------------
   function Is_Null (Value : in Object) return Boolean is
   begin
      return Value.Of_Type = TYPE_NULL;
   end Is_Null;

   --  ------------------------------
   --  Check whether the object is empty.
   --  If the object is null, returns true.
   --  If the object is the empty string, returns true.
   --  If the object is a list bean whose Get_Count is 0, returns true.
   --  Otherwise returns false.
   --  ------------------------------
   function Is_Empty (Value : in Object) return Boolean is
   begin
      case Value.Of_Type is
         when TYPE_NULL =>
            return True;

         when TYPE_STRING =>
            return Value.String_Value = "";

         when TYPE_WIDE_STRING  =>
            return Value.Wide_String_Value = "";

         when TYPE_BEAN =>
            if Value.Bean = null then
               return True;
            end if;
            if not (Value.Bean.all in EL.Beans.List_Bean'Class) then
               return False;
            end if;
            declare
               L : constant EL.Beans.List_Bean_Access :=
                 EL.Beans.List_Bean'Class (Value.Bean.all)'Unchecked_Access;
            begin
               return L.Get_Count = 0;
            end;

         when others =>
            return False;

      end case;
   end Is_Empty;

   --  ------------------------------
   --  Translate the object
   --  ------------------------------
   function To_String (Type_Def : Basic_Type;
                       Value    : in Object) return String is
      pragma Unreferenced (Type_Def);
   begin
      return To_String (Value);
   end To_String;

   --  ------------------------------
   --  Generic Object holding a value
   --  ------------------------------

   --  Get the type name
   function Get_Type_Name (Value : Object) return String is
   begin
      return Value.Type_Def.Get_Name;
   end Get_Type_Name;

   --  ------------------------------
   --  Get a type identification for the object value.
   --  ------------------------------
   function Get_Type (Value : in Object) return Data_Type is
   begin
      return Value.Of_Type;
   end Get_Type;

   --  ------------------------------
   --  Get the type definition of the object value.
   --  ------------------------------
   function Get_Type (Value : Object) return Object_Type'Class is
   begin
      return Value.Type_Def.all;
   end Get_Type;

   --  ------------------------------
   --  Convert the object to the corresponding type.
   --  ------------------------------
   function To_String (Value : Object) return String is
   begin
      case Value.Of_Type is
         when TYPE_INTEGER =>
            declare
               S : constant String := Long_Long_Integer'Image (Value.Int_Value);
            begin
               return S (S'First + 1 .. S'Last);
            end;

         when TYPE_BOOLEAN =>
            return Boolean'Image (Value.Bool_Value);

         when TYPE_FLOAT =>
            return Long_Long_Float'Image (Value.Float_Value);

         when TYPE_STRING =>
            return To_String (Value.String_Value);

         when TYPE_WIDE_STRING =>
            return To_String (To_Wide_Wide_String (Value.Wide_String_Value));

         when TYPE_TIME =>
            return Ada.Calendar.Formatting.Image (Value.Time_Value);
<commit_msg>Fix regression on integer to string conversion for negative numbers<commit_after>-----------------------------------------------------------------------
--  EL.Objects -- Generic Typed Data Representation
--  Copyright (C) 2009, 2010 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------

--  package EL
--  package EL.Expressions
--  package EL.Objects
with Ada.Characters.Conversions;
with Ada.Calendar.Formatting;
with Ada.Calendar.Conversions;
with Interfaces.C;
with EL.Beans;
package body EL.Objects is

   use Ada.Characters.Conversions;
   use Ada.Calendar.Formatting;
   use type Interfaces.C.long;

   type String_Access is access constant String;

   --  Find the data type to be used for an arithmetic operation between two objects.
   function Get_Arithmetic_Type (Left, Right : Object) return Data_Type;

   --  Find the data type to be used for a composition operation between two objects.
   function Get_Compose_Type (Left, Right : Object) return Data_Type;

   --  Find the best type to be used to compare two operands.
   function Get_Compare_Type (Left, Right : Object) return Data_Type;

   function "+"(Str : in String)
                return Unbounded_String renames To_Unbounded_String;

   type Basic_Type is new Object_Type with record
      Name : String_Access;
   end record;

   --  Get the type name
   function Get_Name (Type_Def : Basic_Type) return String;

   --  Translate the object
   function To_String (Type_Def : Basic_Type;
                       Value    : in Object) return String;

   INTEGER_NAME     : aliased constant String := "Integer";
   BOOLEAN_NAME     : aliased constant String := "Boolean";
   STRING_NAME      : aliased constant String := "String";
   WIDE_STRING_NAME : aliased constant String := "Wide_Wide_String";
   FLOAT_NAME       : aliased constant String := "Float";
   TIME_NAME        : aliased constant String := "Time";
   BEAN_NAME        : aliased constant String := "Bean";

   Integer_Type     : aliased constant Basic_Type := Basic_Type '(Name => INTEGER_NAME'Access);
   Boolean_Type     : aliased constant Basic_Type := Basic_Type '(Name => BOOLEAN_NAME'Access);
   String_Type      : aliased constant Basic_Type := Basic_Type '(Name => STRING_NAME'Access);
   Wide_String_Type : aliased constant Basic_Type := Basic_Type '(Name => WIDE_STRING_NAME'Access);
   Float_Type       : aliased constant Basic_Type := Basic_Type '(Name => FLOAT_NAME'Access);
   Time_Type        : aliased constant Basic_Type := Basic_Type '(Name => TIME_NAME'Access);
   Bean_Type        : aliased constant Basic_Type := Basic_Type '(Name => BEAN_NAME'Access);

   --  ------------------------------
   --  Get the type name
   --  ------------------------------
   function Get_Name (Type_Def : Basic_Type) return String is
   begin
      return Type_Def.Name.all;
   end Get_Name;

   --  ------------------------------
   --  Check whether the object contains a value.
   --  Returns true if the object does not contain a value.
   --  ------------------------------
   function Is_Null (Value : in Object) return Boolean is
   begin
      return Value.Of_Type = TYPE_NULL;
   end Is_Null;

   --  ------------------------------
   --  Check whether the object is empty.
   --  If the object is null, returns true.
   --  If the object is the empty string, returns true.
   --  If the object is a list bean whose Get_Count is 0, returns true.
   --  Otherwise returns false.
   --  ------------------------------
   function Is_Empty (Value : in Object) return Boolean is
   begin
      case Value.Of_Type is
         when TYPE_NULL =>
            return True;

         when TYPE_STRING =>
            return Value.String_Value = "";

         when TYPE_WIDE_STRING  =>
            return Value.Wide_String_Value = "";

         when TYPE_BEAN =>
            if Value.Bean = null then
               return True;
            end if;
            if not (Value.Bean.all in EL.Beans.List_Bean'Class) then
               return False;
            end if;
            declare
               L : constant EL.Beans.List_Bean_Access :=
                 EL.Beans.List_Bean'Class (Value.Bean.all)'Unchecked_Access;
            begin
               return L.Get_Count = 0;
            end;

         when others =>
            return False;

      end case;
   end Is_Empty;

   --  ------------------------------
   --  Translate the object
   --  ------------------------------
   function To_String (Type_Def : Basic_Type;
                       Value    : in Object) return String is
      pragma Unreferenced (Type_Def);
   begin
      return To_String (Value);
   end To_String;

   --  ------------------------------
   --  Generic Object holding a value
   --  ------------------------------

   --  Get the type name
   function Get_Type_Name (Value : Object) return String is
   begin
      return Value.Type_Def.Get_Name;
   end Get_Type_Name;

   --  ------------------------------
   --  Get a type identification for the object value.
   --  ------------------------------
   function Get_Type (Value : in Object) return Data_Type is
   begin
      return Value.Of_Type;
   end Get_Type;

   --  ------------------------------
   --  Get the type definition of the object value.
   --  ------------------------------
   function Get_Type (Value : Object) return Object_Type'Class is
   begin
      return Value.Type_Def.all;
   end Get_Type;

   --  ------------------------------
   --  Convert the object to the corresponding type.
   --  ------------------------------
   function To_String (Value : Object) return String is
   begin
      case Value.Of_Type is
         when TYPE_INTEGER =>
            if Value.Int_Value >= 0 then
               declare
                  S : constant String := Long_Long_Integer'Image (Value.Int_Value);
               begin
                  return S (S'First + 1 .. S'Last);
               end;
            else
               return Long_Long_Integer'Image (Value.Int_Value);
            end if;

         when TYPE_BOOLEAN =>
            return Boolean'Image (Value.Bool_Value);

         when TYPE_FLOAT =>
            return Long_Long_Float'Image (Value.Float_Value);

         when TYPE_STRING =>
            return To_String (Value.String_Value);

         when TYPE_WIDE_STRING =>
            return To_String (To_Wide_Wide_String (Value.Wide_String_Value));

         when TYPE_TIME =>
            return Ada.Calendar.Formatting.Image (Value.Time_Value);

{'fraction_non_alphanumeric': 0.16160675927251897, 'fraction_numerical': 0.0022196763568666763, 'mean_word_length': 1.7136195842238198, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5067252', 'n_tokens_mistral': 3730, 'n_tokens_neox': 3601, 'n_words': 1223}