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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
------------------------------------------------------------------------------
-- --
-- GNAT LIBRARY COMPONENTS --
-- --
-- G N A T . S P I T B O L --
-- --
-- S p e c --
-- --
-- Copyright (C) 1997-2006, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT 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 GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
-- Boston, MA 02110-1301, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- this unit does not by itself cause the resulting executable to be --
-- covered by the GNU General Public License. This exception does not --
-- however invalidate any other reasons why the executable file might be --
-- covered by the GNU Public License. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- SPITBOL-like interface facilities
-- This package provides a set of interfaces to semantic operations copied
-- from SPITBOL, including a complete implementation of SPITBOL pattern
-- matching. The code is derived from the original SPITBOL MINIMAL sources,
-- created by Robert Dewar. The translation is not exact, but the
-- algorithmic approaches are similar.
with Ada.Finalization; use Ada.Finalization;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Interfaces; use Interfaces;
package GNAT.Spitbol is
pragma Preelaborate;
-- The Spitbol package relies heavily on the Unbounded_String package,
-- using the synonym VString for variable length string. The following
-- declarations define this type and other useful abbreviations.
subtype VString is Ada.Strings.Unbounded.Unbounded_String;
function V (Source : String) return VString
renames Ada.Strings.Unbounded.To_Unbounded_String;
function S (Source : VString) return String
renames Ada.Strings.Unbounded.To_String;
Nul : VString renames Ada.Strings.Unbounded.Null_Unbounded_String;
-------------------------
-- Facilities Provided --
-------------------------
-- The SPITBOL support in GNAT consists of this package together with
-- several child packages. In this package, we have first a set of
-- useful string functions, copied exactly from the corresponding
-- SPITBOL functions, except that we had to rename REVERSE because
-- reverse is a reserved word (it is now Reverse_String).
-- The second element of the parent package is a generic implementation
-- of a table facility. In SPITBOL, the TABLE function allows general
-- mappings from any datatype to any other datatype, and of course, as
-- always, we can freely mix multiple types in the same table.
-- The Ada version of tables is strongly typed, so the indexing type and
-- the range type are always of a consistent type. In this implementation
-- we only provide VString as an indexing type, since this is by far the
-- most common case. The generic instantiation specifies the range type
-- to be used.
-- Three child packages provide standard instantiations of this table
-- package for three common datatypes:
-- GNAT.Spitbol.Table_Boolean (file g-sptabo.ads)
-- The range type is Boolean. The default value is False. This
-- means that this table is essentially a representation of a set.
-- GNAT.Spitbol.Table_Integer (file g-sptain.ads)
-- The range type is Integer. The default value is Integer'First.
-- This provides a general mapping from strings to integers.
-- GNAT.Spitbol.Table_VString (file g-sptavs.ads)
-- The range type is VString. The default value is the null string.
-- This provides a general mapping from strings to strings.
-- Finally there is another child package:
-- GNAT.Spitbol.Patterns (file g-spipat.ads)
-- This child package provides a complete implementation of SPITBOL
-- pattern matching. The spec contains a complete tutorial on the
-- use of pattern matching.
---------------------------------
-- Standard String Subprograms --
---------------------------------
-- This section contains some operations on unbounded strings that are
-- closely related to those in the package Unbounded.Strings, but they
-- correspond to the SPITBOL semantics for these operations.
function Char (Num : Natural) return Character;
pragma Inline (Char);
-- Equivalent to Character'Val (Num)
function Lpad
(Str : VString;
Len : Natural;
Pad : Character := ' ') return VString;
function Lpad
(Str : String;
Len : Natural;
Pad : Character := ' ') return VString;
-- If the length of Str is greater than or equal to Len, then Str is
-- returned unchanged. Otherwise, The value returned is obtained by
-- concatenating Length (Str) - Len instances of the Pad character to
-- the left hand side.
procedure Lpad
(Str : in out VString;
Len : Natural;
Pad : Character := ' ');
-- The procedure form is identical to the function form, except that
-- the result overwrites the input argument Str.
function Reverse_String (Str : VString) return VString;
function Reverse_String (Str : String) return VString;
-- Returns result of reversing the string Str, i.e. the result returned
-- is a mirror image (end-for-end reversal) of the input string.
procedure Reverse_String (Str : in out VString);
-- The procedure form is identical to the function form, except that the
-- result overwrites the input argument Str.
function Rpad
(Str : VString;
Len : Natural;
Pad : Character := ' ') return VString;
function Rpad
(Str : String;
Len : Natural;
Pad : Character := ' ') return VString;
-- If the length of Str is greater than or equal to Len, then Str is
-- returned unchanged. Otherwise, The value returned is obtained by
-- concatenating Length (Str) - Len instances of the Pad character to
-- the right hand side.
procedure Rpad
(Str : in out VString;
Len : Natural;
Pad : Character := ' ');
-- The procedure form is identical to the function form, except that the
-- result overwrites the input argument Str.
function Size (Source : VString) return Natural
renames Ada.Strings.Unbounded.Length;
function Substr
(Str : VString;
Start : Positive;
Len : Natural) return VString;
function Substr
(Str : String;
Start : Positive;
Len : Natural) return VString;
-- Returns the substring starting at the given character position (which
-- is always counted from the start of the string, regardless of bounds,
-- e.g. 2 means starting with the second character of the string), and
-- with the length (Len) given. Indexing_Error is raised if the starting
-- position is out of range, and Length_Error is raised if Len is too long.
function Trim (Str : VString) return VString;
function Trim (Str : String) return VString;
-- Returns the string obtained by removing all spaces from the right
-- hand side of the string Str.
procedure Trim (Str : in out VString);
-- The procedure form is identical to the function form, except that the
-- result overwrites the input argument Str.
-----------------------
-- Utility Functions --
-----------------------
-- In SPITBOL, integer values can be freely treated as strings. The
-- following definitions help provide some of this capability in
-- some common cases.
function "&" (Num : Integer; Str : String) return String;
function "&" (Str : String; Num : Integer) return String;
function "&" (Num : Integer; Str : VString) return VString;
function "&" (Str : VString; Num : Integer) return VString;
-- In all these concatenation operations, the integer is converted to
-- its corresponding decimal string form, with no leading blank.
function S (Num : Integer) return String;
function V (Num : Integer) return VString;
-- These operators return the given integer converted to its decimal
-- string form with no leading blank.
function N (Str : VString) return Integer;
-- Converts string to number (same as Integer'Value (S (Str)))
-------------------
-- Table Support --
-------------------
-- So far, we only provide support for tables whose indexing data values
-- are strings (or unbounded strings). The values stored may be of any
-- type, as supplied by the generic formal parameter.
generic
type Value_Type is private;
-- Any non-limited type can be used as the value type in the table
Null_Value : Value_Type;
-- Value used to represent a value that is not present in the table
with function Img (A : Value_Type) return String;
-- Used to provide image of value in Dump procedure
with function "=" (A, B : Value_Type) return Boolean is <>;
-- This allows a user-defined equality function to override the
-- predefined equality function.
package Table is
------------------------
-- Table Declarations --
------------------------
type Table (N : Unsigned_32) is private;
-- This is the table type itself. A table is a mapping from string
-- values to values of Value_Type. The discriminant is an estimate of
-- the number of values in the table. If the estimate is much too
-- high, some space is wasted, if the estimate is too low, access to
-- table elements is slowed down. The type Table has copy semantics,
-- not reference semantics. This means that if a table is copied
-- using simple assignment, then the two copies refer to entirely
-- separate tables.
-----------------------------
-- Table Access Operations --
-----------------------------
function Get (T : Table; Name : VString) return Value_Type;
function Get (T : Table; Name : Character) return Value_Type;
pragma Inline (Get);
function Get (T : Table; Name : String) return Value_Type;
-- If an entry with the given name exists in the table, then the
-- corresponding Value_Type value is returned. Otherwise Null_Value
-- is returned.
function Present (T : Table; Name : VString) return Boolean;
function Present (T : Table; Name : Character) return Boolean;
pragma Inline (Present);
function Present (T : Table; Name : String) return Boolean;
-- Determines if an entry with the given name is present in the table.
-- A returned value of True means that it is in the table, otherwise
-- False indicates that it is not in the table.
procedure Delete (T : in out Table; Name : VString);
procedure Delete (T : in out Table; Name : Character);
pragma Inline (Delete);
procedure Delete (T : in out Table; Name : String);
-- Deletes the table element with the given name from the table. If
-- no element in the table has this name, then the call has no effect.
procedure Set (T : in out Table; Name : VString; Value : Value_Type);
procedure Set (T : in out Table; Name : Character; Value : Value_Type);
pragma Inline (Set);
procedure Set (T : in out Table; Name : String; Value : Value_Type);
-- Sets the value of the element with the given name to the given
-- value. If Value is equal to Null_Value, the effect is to remove
-- the entry from the table. If no element with the given name is
-- currently in the table, then a new element with the given value
-- is created.
----------------------------
-- Allocation and Copying --
----------------------------
-- Table is a controlled type, so that all storage associated with
-- tables is properly reclaimed when a Table value is abandoned.
-- Tables have value semantics rather than reference semantics as
-- in Spitbol, i.e. when you assign a copy you end up with two
-- distinct copies of the table, as though COPY had been used in
-- Spitbol. It seems clearly more appropriate in Ada to require
-- the use of explicit pointers for reference semantics.
procedure Clear (T : in out Table);
-- Clears all the elements of the given table, freeing associated
-- storage. On return T is an empty table with no elements.
procedure Copy (From : Table; To : in out Table);
-- First all the elements of table To are cleared (as described for
-- the Clear procedure above), then all the elements of table From
-- are copied into To. In the case where the tables From and To have
-- the same declared size (i.e. the same discriminant), the call to
-- Copy has the same effect as the assignment of From to To. The
-- difference is that, unlike the assignment statement, which will
-- cause a Constraint_Error if the source and target are of different
-- sizes, Copy works fine with different sized tables.
----------------
-- Conversion --
----------------
type Table_Entry is record
Name : VString;
Value : Value_Type;
end record;
type Table_Array is array (Positive range <>) of Table_Entry;
function Convert_To_Array (T : Table) return Table_Array;
-- Returns a Table_Array value with a low bound of 1, and a length
-- corresponding to the number of elements in the table. The elements
-- of the array give the elements of the table in unsorted order.
---------------
-- Debugging --
---------------
procedure Dump (T : Table; Str : String := "Table");
-- Dump contents of given table to the standard output file. The
-- string value Str is used as the name of the table in the dump.
procedure Dump (T : Table_Array; Str : String := "Table_Array");
-- Dump contents of given table array to the current output file. The
-- string value Str is used as the name of the table array in the dump.
private
------------------
-- Private Part --
------------------
-- A Table is a pointer to a hash table which contains the indicated
-- number of hash elements (the number is forced to the next odd value
-- if it is even to improve hashing performance). If more than one
-- of the entries in a table hashes to the same slot, the Next field
-- is used to chain entries from the header. The chains are not kept
-- ordered. A chain is terminated by a null pointer in Next. An unused
-- chain is marked by an element whose Name is null and whose value
-- is Null_Value.
type Hash_Element;
type Hash_Element_Ptr is access all Hash_Element;
type Hash_Element is record
Name : String_Access := null;
Value : Value_Type := Null_Value;
Next : Hash_Element_Ptr := null;
end record;
type Hash_Table is
array (Unsigned_32 range <>) of aliased Hash_Element;
type Table (N : Unsigned_32) is new Controlled with record
Elmts : Hash_Table (1 .. N);
end record;
pragma Finalize_Storage_Only (Table);
procedure Adjust (Object : in out Table);
-- The Adjust procedure does a deep copy of the table structure
-- so that the effect of assignment is, like other assignments
-- in Ada, value-oriented.
procedure Finalize (Object : in out Table);
-- This is the finalization routine that ensures that all storage
-- associated with a table is properly released when a table object
-- is abandoned and finalized.
end Table;
end GNAT.Spitbol;
|