Natools

Check-in [048393b674]
Login
Overview
Comment:s_expressions-conditionals-strings: new package providing evaluation of boolean expressions about strings
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 048393b6747fbb929533d59ab27f9df6d27d3c3d
User & Date: nat on 2015-03-31 19:10:45
Other Links: manifest | tags
Context
2015-04-01
21:16
s_expressions-conditionals-strings-tests: new package providing a fully covering test suite for string conditionals check-in: 2b39e14775 user: nat tags: trunk
2015-03-31
19:10
s_expressions-conditionals-strings: new package providing evaluation of boolean expressions about strings check-in: 048393b674 user: nat tags: trunk
2015-03-30
17:05
s_expressions-conditionals-generic_evaluate: new generic function providing a boolean expression evaluation framework check-in: ca4b731098 user: nat tags: trunk
Changes

Modified README.md from [e8804745cd] to [50d67b54d8].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39







+







      - `Pools`: task-safe pool of referencesjj
  - `S-expressions`: library for dealing with [S-expressions][1]
      - `Atom_Buffers`: dynamic buffer for S-expression atoms
      - `Atom_Ref_Constructors`: helper constructors for atom references
      - `Atom_Refs`: common reference-counted atoms
      - `Conditionals`: S-expression boolean expressions about some object
          - `Generic_Evaluate`: Generic boolean expression evaluation framework
          - `Strings`: Boolean expressions on standard strings
      - `Dynamic_Interpreters`: S-expression interpreter with mutable
        commands and callbacks
      - `Encodings`: translators to and from official S-expression encodings
      - `File_Readers`: objects reading a file to an atom or a S-expression
      - `File_Writers`: file-backed S-expression printer
      - `Generic_Caches`: memory container for S-expressions
      - `Interpeter_Loop`: inner loop of S-expression interpreters,

Added generated/natools-static_maps-s_expressions-conditionals-strings-p.adb version [4afcbe25fa].

































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
with Interfaces; use Interfaces;

package body Natools.Static_Maps.S_Expressions.Conditionals.Strings.P is

   P : constant array (0 .. 2) of Natural :=
     (2, 11, 13);

   T1 : constant array (0 .. 2) of Unsigned_8 :=
     (9, 9, 0);

   T2 : constant array (0 .. 2) of Unsigned_8 :=
     (6, 4, 5);

   G : constant array (0 .. 16) of Unsigned_8 :=
     (0, 5, 0, 1, 0, 6, 0, 0, 7, 0, 0, 0, 0, 1, 1, 0, 3);

   function Hash (S : String) return Natural is
      F : constant Natural := S'First - 1;
      L : constant Natural := S'Length;
      F1, F2 : Natural := 0;
      J : Natural;
   begin
      for K in P'Range loop
         exit when L < P (K);
         J  := Character'Pos (S (P (K) + F));
         F1 := (F1 + Natural (T1 (K)) * J) mod 17;
         F2 := (F2 + Natural (T2 (K)) * J) mod 17;
      end loop;
      return (Natural (G (F1)) + Natural (G (F2))) mod 8;
   end Hash;

end Natools.Static_Maps.S_Expressions.Conditionals.Strings.P;

Added generated/natools-static_maps-s_expressions-conditionals-strings-p.ads version [c1b86b1aea].





1
2
3
4
+
+
+
+
package Natools.Static_Maps.S_Expressions.Conditionals.Strings.P is
   pragma Pure;
   function Hash (S : String) return Natural;
end Natools.Static_Maps.S_Expressions.Conditionals.Strings.P;

Added generated/natools-static_maps-s_expressions-conditionals-strings-s.adb version [f20278b59d].

































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
with Interfaces; use Interfaces;

package body Natools.Static_Maps.S_Expressions.Conditionals.Strings.S is

   P : constant array (0 .. 0) of Natural :=
     (0 .. 0 => 4);

   T1 : constant array (0 .. 0) of Unsigned_8 :=
     (0 .. 0 => 4);

   T2 : constant array (0 .. 0) of Unsigned_8 :=
     (0 .. 0 => 3);

   G : constant array (0 .. 4) of Unsigned_8 :=
     (0, 0, 0, 0, 1);

   function Hash (S : String) return Natural is
      F : constant Natural := S'First - 1;
      L : constant Natural := S'Length;
      F1, F2 : Natural := 0;
      J : Natural;
   begin
      for K in P'Range loop
         exit when L < P (K);
         J  := Character'Pos (S (P (K) + F));
         F1 := (F1 + Natural (T1 (K)) * J) mod 5;
         F2 := (F2 + Natural (T2 (K)) * J) mod 5;
      end loop;
      return (Natural (G (F1)) + Natural (G (F2))) mod 2;
   end Hash;

end Natools.Static_Maps.S_Expressions.Conditionals.Strings.S;

Added generated/natools-static_maps-s_expressions-conditionals-strings-s.ads version [ce6ba128ce].





1
2
3
4
+
+
+
+
package Natools.Static_Maps.S_Expressions.Conditionals.Strings.S is
   pragma Pure;
   function Hash (S : String) return Natural;
end Natools.Static_Maps.S_Expressions.Conditionals.Strings.S;

Added generated/natools-static_maps-s_expressions-conditionals-strings-t.adb version [05e048ed32].



























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--  Generated at 2015-03-31 18:55:08 +0000 by Natools.Static_Hash_Maps
--  from src/natools-s_expressions-conditionals-strings-maps.sx

with Natools.Static_Maps.S_Expressions.Conditionals.Strings.P;
with Natools.Static_Maps.S_Expressions.Conditionals.Strings.S;
function Natools.Static_Maps.S_Expressions.Conditionals.Strings.T
  return Boolean is
begin
   for I in Map_1_Keys'Range loop
      if Natools.Static_Maps.S_Expressions.Conditionals.Strings.P.Hash
           (Map_1_Keys (I).all) /= I
      then
         return False;
      end if;
   end loop;

   for I in Map_2_Keys'Range loop
      if Natools.Static_Maps.S_Expressions.Conditionals.Strings.S.Hash
           (Map_2_Keys (I).all) /= I
      then
         return False;
      end if;
   end loop;

   return True;
end Natools.Static_Maps.S_Expressions.Conditionals.Strings.T;

Added generated/natools-static_maps-s_expressions-conditionals-strings-t.ads version [c5a50a7abb].







1
2
3
4
5
6
+
+
+
+
+
+
--  Generated at 2015-03-31 18:55:08 +0000 by Natools.Static_Hash_Maps
--  from src/natools-s_expressions-conditionals-strings-maps.sx

function Natools.Static_Maps.S_Expressions.Conditionals.Strings.T
  return Boolean;
pragma Pure (Natools.Static_Maps.S_Expressions.Conditionals.Strings.T);

Added generated/natools-static_maps-s_expressions-conditionals-strings.adb version [0ace4d80ab].

































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--  Generated at 2015-03-31 18:55:08 +0000 by Natools.Static_Hash_Maps
--  from src/natools-s_expressions-conditionals-strings-maps.sx

with Natools.Static_Maps.S_Expressions.Conditionals.Strings.P;
with Natools.Static_Maps.S_Expressions.Conditionals.Strings.S;

package body Natools.Static_Maps.S_Expressions.Conditionals.Strings is

   function To_Parametric (Key : String) return Parametric_Condition is
      N : constant Natural
        := Natools.Static_Maps.S_Expressions.Conditionals.Strings.P.Hash (Key);
   begin
      if Map_1_Keys (N).all = Key then
         return Map_1_Elements (N);
      else
         return Unknown_Parametric_Condition;
      end if;
   end To_Parametric;


   function To_Simple (Key : String) return Simple_Condition is
      N : constant Natural
        := Natools.Static_Maps.S_Expressions.Conditionals.Strings.S.Hash (Key);
   begin
      if Map_2_Keys (N).all = Key then
         return Map_2_Elements (N);
      else
         return Unknown_Simple_Condition;
      end if;
   end To_Simple;

end Natools.Static_Maps.S_Expressions.Conditionals.Strings;

Added generated/natools-static_maps-s_expressions-conditionals-strings.ads version [cc9021c49e].






























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--  Generated at 2015-03-31 18:55:08 +0000 by Natools.Static_Hash_Maps
--  from src/natools-s_expressions-conditionals-strings-maps.sx

package Natools.Static_Maps.S_Expressions.Conditionals.Strings is
   pragma Pure;

   type Parametric_Condition is
     (Unknown_Parametric_Condition,
      Case_Insensitive,
      Case_Sensitive,
      Contains_All,
      Contains_Any,
      Starts_With);

   type Simple_Condition is
     (Unknown_Simple_Condition,
      Is_ASCII,
      Is_Empty);

   function To_Parametric (Key : String) return Parametric_Condition;
   function To_Simple (Key : String) return Simple_Condition;

private

   Map_1_Key_0 : aliased constant String := "case-insensitive";
   Map_1_Key_1 : aliased constant String := "case-sensitive";
   Map_1_Key_2 : aliased constant String := "contains";
   Map_1_Key_3 : aliased constant String := "contains-all";
   Map_1_Key_4 : aliased constant String := "contains-all-of";
   Map_1_Key_5 : aliased constant String := "contains-any";
   Map_1_Key_6 : aliased constant String := "contains-any-of";
   Map_1_Key_7 : aliased constant String := "starts-with";
   Map_1_Keys : constant array (0 .. 7) of access constant String
     := (Map_1_Key_0'Access,
         Map_1_Key_1'Access,
         Map_1_Key_2'Access,
         Map_1_Key_3'Access,
         Map_1_Key_4'Access,
         Map_1_Key_5'Access,
         Map_1_Key_6'Access,
         Map_1_Key_7'Access);
   Map_1_Elements : constant array (0 .. 7) of Parametric_Condition
     := (Case_Insensitive,
         Case_Sensitive,
         Contains_All,
         Contains_All,
         Contains_All,
         Contains_Any,
         Contains_Any,
         Starts_With);

   Map_2_Key_0 : aliased constant String := "is-ascii";
   Map_2_Key_1 : aliased constant String := "is-empty";
   Map_2_Keys : constant array (0 .. 1) of access constant String
     := (Map_2_Key_0'Access,
         Map_2_Key_1'Access);
   Map_2_Elements : constant array (0 .. 1) of Simple_Condition
     := (Is_ASCII,
         Is_Empty);

end Natools.Static_Maps.S_Expressions.Conditionals.Strings;

Added src/natools-s_expressions-conditionals-strings-maps.sx version [7a3d8c8852].




































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
(Natools.Static_Maps.S_Expressions.Conditionals.Strings
   pure
   (test-function T)
   (extra-decl "\
   type Parametric_Condition is
     (Unknown_Parametric_Condition,
      Case_Insensitive,
      Case_Sensitive,
      Contains_All,
      Contains_Any,
      Starts_With);

   type Simple_Condition is
     (Unknown_Simple_Condition,
      Is_ASCII,
      Is_Empty);")

   (Parametric_Condition
      (hash-package Natools.Static_Maps.S_Expressions.Conditionals.Strings.P)
      (function To_Parametric)
      (not-found Unknown_Parametric_Condition)
      (nodes
         (Case_Insensitive   case-insensitive)
         (Case_Sensitive   case-sensitive)
         (Contains_All   contains contains-all contains-all-of)
         (Contains_Any   contains-any contains-any-of)
         (Starts_With   starts-with)))

   (Simple_Condition
      (hash-package Natools.Static_Maps.S_Expressions.Conditionals.Strings.S)
      (function To_Simple)
      (not-found Unknown_Simple_Condition)
      (nodes
         (Is_ASCII   is-ascii)
         (Is_Empty   is-empty))))

Added src/natools-s_expressions-conditionals-strings.adb version [52b9048770].




































































































































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
------------------------------------------------------------------------------
-- Copyright (c) 2015, Natacha Porté                                        --
--                                                                          --
-- Permission to use, copy, modify, and distribute this software for any    --
-- purpose with or without fee is hereby granted, provided that the above   --
-- copyright notice and this permission notice appear in all copies.        --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         --
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  --
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   --
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    --
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  --
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           --
------------------------------------------------------------------------------

with Ada.Characters.Handling;
with Ada.Strings.Fixed;
with Natools.Static_Maps.S_Expressions.Conditionals.Strings;

package body Natools.S_Expressions.Conditionals.Strings is

   package Fixed renames Ada.Strings.Fixed;


   function Conditional_On_Atoms
     (Context : in Strings.Context;
      Arguments : in out Lockable.Descriptor'Class;
      Element : access function (Context : in Strings.Context;
                                 Data : in Atom)
                                return Boolean;
      Conjunction : in Boolean)
     return Boolean;
      --  Evaluate Element on all atoms of Arguments and combine them

   function Contains (Context : in Strings.Context; Data : in Atom)
     return Boolean;
      --  Check whether Context contains Data

   function Is_Prefix (Context : in Strings.Context; Data : in Atom)
     return Boolean;
      --  Check whether Context starts with Data

   function To_Lower (Item : in Character) return Character
     renames Ada.Characters.Handling.To_Lower;
      --  Clearer name for lower case translation, used for case-insentivity



   ------------------------------
   -- Local Helper Subprograms --
   ------------------------------

   function Conditional_On_Atoms
     (Context : in Strings.Context;
      Arguments : in out Lockable.Descriptor'Class;
      Element : access function (Context : in Strings.Context;
                                 Data : in Atom)
                                return Boolean;
      Conjunction : in Boolean)
     return Boolean
   is
      Result : Boolean := not Conjunction;
      Event : Events.Event := Arguments.Current_Event;
   begin
      while Event = Events.Add_Atom loop
         Result := Element.all (Context, Arguments.Current_Atom);
         exit when Result /= Conjunction;
         Arguments.Next (Event);
      end loop;

      return Result;
   end Conditional_On_Atoms;


   function Contains (Context : in Strings.Context; Data : in Atom)
     return Boolean
   is
      Str_Value : String := To_String (Data);
   begin
      if Context.Settings.Case_Sensitive then
         return Fixed.Index
           (Context.Data.all,
            Str_Value,
            Str_Value'First,
            Ada.Strings.Forward) > 0;
      else
         Fixed.Translate (Str_Value, To_Lower'Access);
         return Fixed.Index
           (Context.Data.all,
            Str_Value,
            Str_Value'First,
            Ada.Strings.Forward,
            Ada.Characters.Handling.To_Lower'Access) > 0;
      end if;
   end Contains;


   function Is_Prefix (Context : in Strings.Context; Data : in Atom)
     return Boolean is
   begin
      if Context.Data.all'Length < Data'Length then
         return False;
      end if;

      declare
         Prefix : String renames Context.Data.all
           (Context.Data.all'First
            .. Context.Data.all'First + Data'Length - 1);
      begin
         if Context.Settings.Case_Sensitive then
            return Prefix = To_String (Data);
         else
            return Fixed.Translate (Prefix, To_Lower'Access)
              = Fixed.Translate (To_String (Data), To_Lower'Access);
         end if;
      end;
   end Is_Prefix;



   ---------------------------
   -- Evaluation Primitives --
   ---------------------------

   function Parametric_Evaluate
     (Context : in Strings.Context;
      Name : in Atom;
      Arguments : in out Lockable.Descriptor'Class)
     return Boolean
   is
      use Natools.Static_Maps.S_Expressions.Conditionals.Strings;
   begin
      case To_Parametric (To_String (Name)) is
         when Unknown_Parametric_Condition =>
            if Context.Parametric_Fallback /= null then
               return Context.Parametric_Fallback
                 (Context.Settings, Name, Arguments);
            else
               raise Constraint_Error with "Unknown parametric condition """
                 & To_String (Name) & '"';
            end if;

         when Case_Insensitive =>
            declare
               New_Context : Strings.Context := Context;
            begin
               New_Context.Settings.Case_Sensitive := False;
               return Evaluate (New_Context, Arguments);
            end;

         when Case_Sensitive =>
            declare
               New_Context : Strings.Context := Context;
            begin
               New_Context.Settings.Case_Sensitive := True;
               return Evaluate (New_Context, Arguments);
            end;

         when Contains_All =>
            return Conditional_On_Atoms
              (Context, Arguments, Contains'Access, True);

         when Contains_Any =>
            return Conditional_On_Atoms
              (Context, Arguments, Contains'Access, False);

         when Starts_With =>
            return Conditional_On_Atoms
              (Context, Arguments, Is_Prefix'Access, False);
      end case;
   end Parametric_Evaluate;


   function Simple_Evaluate
     (Context : in Strings.Context;
      Name : in Atom)
     return Boolean
   is
      use Natools.Static_Maps.S_Expressions.Conditionals.Strings;
   begin
      case To_Simple (To_String (Name)) is
         when Unknown_Simple_Condition =>
            if Context.Parametric_Fallback /= null then
               return Context.Simple_Fallback (Context.Settings, Name);
            else
               raise Constraint_Error with "Unknown simple condition """
                 & To_String (Name) & '"';
            end if;

         when Is_ASCII =>
            for I in Context.Data.all'Range loop
               if Context.Data (I)
                 not in Character'Val (0) .. Character'Val (127)
               then
                  return False;
               end if;
            end loop;
            return True;

         when Is_Empty =>
            return Context.Data.all'Length = 0;
      end case;
   end Simple_Evaluate;



   --------------------------
   -- Evaluation Shortcuts --
   --------------------------

   function Evaluate
     (Text : in String;
      Expression : in out Lockable.Descriptor'Class)
     return Boolean
   is
      Aliased_Text : aliased constant String := Text;
      Context : constant Strings.Context
        := (Data => Aliased_Text'Access,
            Parametric_Fallback => null,
            Simple_Fallback => null,
            Settings => <>);
   begin
      return Evaluate (Context, Expression);
   end Evaluate;

end Natools.S_Expressions.Conditionals.Strings;

Added src/natools-s_expressions-conditionals-strings.ads version [d357316879].




































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
------------------------------------------------------------------------------
-- Copyright (c) 2015, Natacha Porté                                        --
--                                                                          --
-- Permission to use, copy, modify, and distribute this software for any    --
-- purpose with or without fee is hereby granted, provided that the above   --
-- copyright notice and this permission notice appear in all copies.        --
--                                                                          --
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --
-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF         --
-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR  --
-- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   --
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN    --
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  --
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.           --
------------------------------------------------------------------------------

------------------------------------------------------------------------------
-- Natools.S_Expressions.Conditionals.Strings provides primitives to        --
-- evaluate S-expression conditions about strings.                          --
------------------------------------------------------------------------------

with Natools.S_Expressions.Conditionals.Generic_Evaluate;
with Natools.S_Expressions.Lockable;

package Natools.S_Expressions.Conditionals.Strings is
   pragma Preelaborate;

   type Settings (Data : not null access constant String) is record
      Case_Sensitive : Boolean := True;
   end record;

   type Context
     (Data : not null access constant String;
      Parametric_Fallback : access function
        (Settings : in Strings.Settings;
         Name : in Atom;
         Arguments : in out Lockable.Descriptor'Class)
        return Boolean;
      Simple_Fallback : access function
        (Settings : in Strings.Settings;
         Name : in Atom)
        return Boolean)
   is record
      Settings : Strings.Settings (Data);
   end record;


   function Parametric_Evaluate
     (Context : in Strings.Context;
      Name : in Atom;
      Arguments : in out Lockable.Descriptor'Class)
     return Boolean;

   function Simple_Evaluate
     (Context : in Strings.Context;
      Name : in Atom)
     return Boolean;

   function Evaluate is new Generic_Evaluate
     (Context, Parametric_Evaluate, Simple_Evaluate);

   function Evaluate
     (Text : in String;
      Expression : in out Lockable.Descriptor'Class)
     return Boolean;

end Natools.S_Expressions.Conditionals.Strings;