3 with Unchecked_Deallocation
;
8 function Is_Null
(E
: Env_Handle
) return Boolean is
11 return Smart_Pointer
(E
) = Null_Smart_Pointer
;
15 function New_Env
(Outer
: Env_Handle
) return Env_Handle
is
19 if Is_Null
(Outer
) then
22 Level
:= Deref
(Outer
).Level
+ 1;
26 ("Envs: Creating at level " & Natural'Image (Level
));
28 return Env_Handle
(Smart_Pointers
.New_Ptr
(new Env
'
29 (Base_Class with The_Map => String_Mal_Hash.Empty_Map,
38 Elem : Smart_Pointers.Smart_Pointer) is
42 ("Envs: Setting " & Key &
43 " to " & Types.Deref (Elem).To_String &
44 " at level " & Natural'Image (Deref (E).Level));
46 String_Mal_Hash.Include
47 (Container => Deref (E).The_Map,
48 Key => Ada.Strings.Unbounded.To_Unbounded_String (Key),
53 function Get (E : Env_Handle; Key: String)
54 return Smart_Pointers.Smart_Pointer is
63 ("Envs: Finding " & Key &
64 " at level " & Natural'Image (Deref (E).Level));
67 C := Find (Deref (E).The_Map,
68 Ada.Strings.Unbounded.To_Unbounded_String (Key));
70 if C = No_Element then
72 if Is_Null (Deref (E).Outer_Env) then
75 return Get (Deref (E).Outer_Env, Key);
86 (E : Env_Handle; Outer_Env : Env_Handle) is
88 -- Attempt to avoid making loops.
89 if Deref (E).Level /= 0 then
90 Deref (E).Outer_Env := Outer_Env;
95 function To_String (E : Env_Handle) return String is
96 use String_Mal_Hash, Ada.Strings.Unbounded;
98 Res : Unbounded_String;
100 C := First (Deref (E).The_Map);
101 while C /= No_Element loop
102 Append (Res, Key (C) & " => " & Types.To_String (Types.Deref (Element (C)).all) & ", ");
105 return To_String (Res);
109 -- Sym and Exprs are lists. Bind Sets Keys in Syms to the corresponding
110 -- expression in Exprs.
111 procedure Bind (E : Env_Handle; Syms, Exprs : Types.List_Mal_Type) is
113 S, Expr : List_Mal_Type;
117 while not Is_Null (S) and not Is_Null (Expr) loop
118 Set (E, Deref_Atom (Car (S)).Get_Atom, Car (Expr));
119 S := Deref_List (Cdr (S)).all;
120 Expr := Deref_List (Cdr (Expr)).all;
125 function String_Hash (Key : Ada.Strings.Unbounded.Unbounded_String)
126 return Ada.Containers.Hash_Type is
128 Res : Ada.Containers.Hash_Type;
132 Str_Len := Ada.Strings.Unbounded.Length (Key);
133 for I in 1..Str_Len loop
135 Character'Pos (Ada.Strings.Unbounded.Element (Key, I));
143 Current := New_Env (Current);
147 procedure Free is new Unchecked_Deallocation (Env, Env_Ptr);
149 procedure Delete_Env is
152 Ada.Text_IO.Put_Line ("Deleting env at level " & Natural'Image (Deref (Current).Level));
154 -- Always leave one Env!
155 if not Is_Null (Deref (Current).Outer_Env) then
156 Current := Deref (Current).Outer_Env;
157 -- The old Current is finalized *if* there are no references to it.
158 -- Note closures may refer to the old env.
163 function Get_Current return Env_Handle is
169 function Deref (SP : Env_Handle) return Env_Ptr is
171 return Env_Ptr (Smart_Pointers.Deref (Smart_Pointers.Smart_Pointer (SP)));