1 with Ada
.Strings
.Unbounded
.Hash
;
4 package body Types
.Hash_Map
is
6 function "=" (A
, B
: Hash_Map_Mal_Type
) return Boolean is
7 A_Key
, A_Elem
, B_Elem
: Mal_Handle
;
11 if A
.Length
/= B
.Length
then
15 while Has_Element
(C
) loop
17 A_Elem
:= Element
(C
);
18 B_Elem
:= Mal_Mal_Hash
.Element
(B
.Hash
, A_Key
);
19 if A_Elem
/= B_Elem
then
27 function New_Hash_Map_Mal_Type
30 return Smart_Pointers
.New_Ptr
31 (new Hash_Map_Mal_Type
'
33 List_Type => Hashed_List,
34 The_List => Smart_Pointers.Null_Smart_Pointer,
35 Last_Elem => Smart_Pointers.Null_Smart_Pointer,
36 Is_Key_Expected => True,
37 Next_Key => Smart_Pointers.Null_Smart_Pointer,
38 Hash => Mal_Mal_Hash.Empty_Map));
39 end New_Hash_Map_Mal_Type;
41 overriding function Prepend (Op : Mal_Handle; To_Vector : Hash_Map_Mal_Type)
44 raise Not_Appropriate;
45 return Smart_Pointers.Null_Smart_Pointer;
48 overriding procedure Append (V : in out Hash_Map_Mal_Type; E : Mal_Handle) is
50 if V.Is_Key_Expected then
58 V.Is_Key_Expected := not V.Is_Key_Expected;
61 overriding function Length (L : Hash_Map_Mal_Type) return Natural is
63 return Natural (L.Hash.Length);
66 overriding function Is_Null (L : Hash_Map_Mal_Type) return Boolean is
68 return L.Hash.Is_Empty;
71 overriding function Null_List (L : List_Types) return Hash_Map_Mal_Type is
76 List_Type
=> Hashed_List
,
77 The_List
=> Smart_Pointers
.Null_Smart_Pointer
,
78 Last_Elem
=> Smart_Pointers
.Null_Smart_Pointer
,
79 Is_Key_Expected
=> False,
80 Next_Key
=> Smart_Pointers
.Null_Smart_Pointer
,
81 Hash
=> Mal_Mal_Hash
.Empty_Map
);
84 -- Duplicate copies the list (logically). This is to allow concatenation,
85 -- The result is always a List_List.
86 overriding
function Duplicate
(The_List
: Hash_Map_Mal_Type
) return Mal_Handle
is
88 raise Not_Appropriate
;
89 return Smart_Pointers
.Null_Smart_Pointer
;
92 overriding
function Nth
(L
:Hash_Map_Mal_Type
; N
: Natural) return Mal_Handle
is
94 raise Not_Appropriate
;
95 return Smart_Pointers
.Null_Smart_Pointer
;
98 overriding
procedure Add_Defs
(Defs
: Hash_Map_Mal_Type
; Env
: Envs
.Env_Handle
) is
100 raise Not_Appropriate
;
103 -- Get the first item in the list:
104 overriding
function Car
(L
: Hash_Map_Mal_Type
) return Mal_Handle
is
106 raise Not_Appropriate
;
107 return Smart_Pointers
.Null_Smart_Pointer
;
110 -- Get the rest of the list (second item onwards)
111 overriding
function Cdr
(L
: Hash_Map_Mal_Type
) return Mal_Handle
is
113 raise Not_Appropriate
;
114 return Smart_Pointers
.Null_Smart_Pointer
;
118 overriding
function Map
119 (Func_Ptr
: Func_Access
;
120 L
: Hash_Map_Mal_Type
)
126 Res
:= New_Hash_Map_Mal_Type
;
128 while Has_Element
(C
) loop
129 -- Assuming we're not applying the func to the keys too.
130 Deref_Hash
(Res
).Hash
.Include
132 New_Item
=> Func_Ptr
(Element
(C
)));
138 function Assoc
(H
: Hash_Map_Mal_Type
; List
: Mal_Handle
) return Mal_Handle
is
140 Rest_List
: List_Mal_Type
;
144 Res
:= New_Hash_Map_Mal_Type
;
145 Rest_List
:= Deref_List
(List
).all;
147 -- Copy arg into result.
148 Deref_Hash
(Res
).Hash
:= H
.Hash
;
150 while not Is_Null
(Rest_List
) loop
151 Deref_Hash
(Res
).Append
(Car
(Rest_List
));
152 Rest_List
:= Deref_List
(Cdr
(Rest_List
)).all;
158 function Dis_Assoc
(H
: Hash_Map_Mal_Type
; List
: Mal_Handle
) return Mal_Handle
is
160 Rest_List
: List_Mal_Type
;
164 Res
:= New_Hash_Map_Mal_Type
;
165 Rest_List
:= Deref_List
(List
).all;
167 -- Copy arg into result.
168 Deref_Hash
(Res
).Hash
:= H
.Hash
;
170 while not Is_Null
(Rest_List
) loop
171 Mal_Mal_Hash
.Exclude
(Deref_Hash
(Res
).Hash
, Car
(Rest_List
));
172 Rest_List
:= Deref_List
(Cdr
(Rest_List
)).all;
178 function Get
(H
: Hash_Map_Mal_Type
; Key
: Mal_Handle
) return Mal_Handle
is
182 C
:= Mal_Mal_Hash
.Find
(H
.Hash
, Key
);
183 if Has_Element
(C
) then
186 return New_Nil_Mal_Type
;
191 function All_Keys
(H
: Hash_Map_Mal_Type
) return Mal_Handle
is
192 Res
, Map_Key
: Mal_Handle
;
196 Res
:= New_List_Mal_Type
(List_List
);
198 while Has_Element
(C
) loop
200 Deref_List
(Res
).Append
(Map_Key
);
207 function All_Values
(H
: Hash_Map_Mal_Type
) return Mal_Handle
is
208 Res
, Map_Val
: Mal_Handle
;
212 Res
:= New_List_Mal_Type
(List_List
);
214 while Has_Element
(C
) loop
215 Map_Val
:= Element
(C
);
216 Deref_List
(Res
).Append
(Map_Val
);
223 function Contains
(H
: Hash_Map_Mal_Type
; Key
: Mal_Handle
) return Boolean is
225 return Mal_Mal_Hash
.Contains
(H
.Hash
, Key
);
228 function Deref_Hash
(SP
: Mal_Handle
) return Hash_Ptr
is
230 return Hash_Ptr
(Deref
(SP
));
233 function Hash
(M
: Mal_Handle
) return Ada
.Containers
.Hash_Type
is
235 return Ada
.Strings
.Unbounded
.Hash
236 (Ada
.Strings
.Unbounded
.To_Unbounded_String
237 (Deref
(M
).To_String
));
240 overriding
function To_Str
241 (T
: Hash_Map_Mal_Type
; Print_Readably
: Boolean := True)
245 if (T
.Hash
.Length
= 0) then
246 return Opening
(T
.List_Type
) &
247 Closing
(T
.List_Type
);
250 Res
: Ada
.Strings
.Unbounded
.Unbounded_String
;
256 Res
:= Ada
.Strings
.Unbounded
."&"
257 (Opening
(T
.List_Type
),
258 Ada
.Strings
.Unbounded
.To_Unbounded_String
259 (To_String
(Deref
(Key
(C
)).all, Print_Readably
)));
260 Res
:= Ada
.Strings
.Unbounded
."&" (Res
, " ");
261 Res
:= Ada
.Strings
.Unbounded
."&"
263 Ada
.Strings
.Unbounded
.To_Unbounded_String
264 (To_String
(Deref
(Element
(C
)).all, Print_Readably
)));
266 while Has_Element
(C
) loop
267 Res
:= Ada
.Strings
.Unbounded
."&" (Res
, " ");
268 Res
:= Ada
.Strings
.Unbounded
."&"
270 Ada
.Strings
.Unbounded
.To_Unbounded_String
271 (To_String
(Deref
(Key
(C
)).all, Print_Readably
)));
272 Res
:= Ada
.Strings
.Unbounded
."&" (Res
, " ");
273 Res
:= Ada
.Strings
.Unbounded
."&"
275 Ada
.Strings
.Unbounded
.To_Unbounded_String
276 (To_String
(Deref
(Element
(C
)).all, Print_Readably
)));
279 Res
:= Ada
.Strings
.Unbounded
."&" (Res
, Closing
(T
.List_Type
));
280 return Ada
.Strings
.Unbounded
.To_String
(Res
);