Commit | Line | Data |
---|---|---|
09c532ba | 1 | with Ada.Text_IO; |
13ce1681 | 2 | with Types; |
9a6f4925 CM |
3 | with Unchecked_Deallocation; |
4 | ||
5 | package body Envs is | |
6 | ||
7 | ||
13ce1681 CM |
8 | function Is_Null (E : Env_Handle) return Boolean is |
9 | use Smart_Pointers; | |
10 | begin | |
b5bad5ea | 11 | return E = Null_Env_Handle; |
13ce1681 CM |
12 | end Is_Null; |
13 | ||
14 | ||
b5bad5ea | 15 | function New_Env (Outer : Env_Handle := Null_Env_Handle) return Env_Handle is |
13ce1681 CM |
16 | use Smart_Pointers; |
17 | Level : Natural; | |
18 | begin | |
19 | if Is_Null (Outer) then | |
20 | Level := 0; | |
21 | else | |
22 | Level := Deref (Outer).Level + 1; | |
23 | end if; | |
24 | if Debug then | |
25 | Ada.Text_IO.Put_Line | |
26 | ("Envs: Creating at level " & Natural'Image (Level)); | |
27 | end if; | |
28 | return Env_Handle (Smart_Pointers.New_Ptr (new Env' | |
29 | (Base_Class with The_Map => String_Mal_Hash.Empty_Map, | |
30 | Outer_Env => Outer, | |
31 | Level => Level))); | |
32 | end New_Env; | |
33 | ||
34 | ||
35 | procedure Set | |
36 | (E : Env_Handle; | |
37 | Key : String; | |
38 | Elem : Smart_Pointers.Smart_Pointer) is | |
39 | begin | |
40 | if Debug then | |
41 | Ada.Text_IO.Put_Line | |
42 | ("Envs: Setting " & Key & | |
43 | " to " & Types.Deref (Elem).To_String & | |
44 | " at level " & Natural'Image (Deref (E).Level)); | |
45 | end if; | |
9a6f4925 | 46 | String_Mal_Hash.Include |
13ce1681 | 47 | (Container => Deref (E).The_Map, |
9a6f4925 | 48 | Key => Ada.Strings.Unbounded.To_Unbounded_String (Key), |
13ce1681 | 49 | New_Item => Elem); |
c4b822cd | 50 | end Set; |
9a6f4925 | 51 | |
09c532ba | 52 | |
13ce1681 CM |
53 | function Get (E : Env_Handle; Key: String) |
54 | return Smart_Pointers.Smart_Pointer is | |
55 | ||
56 | use String_Mal_Hash; | |
57 | C : Cursor; | |
09c532ba | 58 | |
13ce1681 CM |
59 | begin |
60 | ||
61 | if Debug then | |
62 | Ada.Text_IO.Put_Line | |
63 | ("Envs: Finding " & Key & | |
64 | " at level " & Natural'Image (Deref (E).Level)); | |
65 | end if; | |
09c532ba | 66 | |
13ce1681 CM |
67 | C := Find (Deref (E).The_Map, |
68 | Ada.Strings.Unbounded.To_Unbounded_String (Key)); | |
09c532ba | 69 | |
13ce1681 CM |
70 | if C = No_Element then |
71 | ||
72 | if Is_Null (Deref (E).Outer_Env) then | |
73 | raise Not_Found; | |
09c532ba | 74 | else |
13ce1681 | 75 | return Get (Deref (E).Outer_Env, Key); |
09c532ba CM |
76 | end if; |
77 | ||
13ce1681 CM |
78 | else |
79 | return Element (C); | |
80 | end if; | |
09c532ba | 81 | |
c4b822cd | 82 | end Get; |
9a6f4925 CM |
83 | |
84 | ||
efaad1ce CM |
85 | procedure Set_Outer |
86 | (E : Env_Handle; Outer_Env : Env_Handle) is | |
87 | begin | |
88 | -- Attempt to avoid making loops. | |
89 | if Deref (E).Level /= 0 then | |
90 | Deref (E).Outer_Env := Outer_Env; | |
91 | end if; | |
92 | end Set_Outer; | |
93 | ||
94 | ||
95 | function To_String (E : Env_Handle) return String is | |
96 | use String_Mal_Hash, Ada.Strings.Unbounded; | |
97 | C : Cursor; | |
98 | Res : Unbounded_String; | |
99 | begin | |
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) & ", "); | |
103 | C := Next (C); | |
104 | end loop; | |
105 | return To_String (Res); | |
106 | end To_String; | |
107 | ||
108 | ||
13ce1681 | 109 | -- Sym and Exprs are lists. Bind Sets Keys in Syms to the corresponding |
c3244bcf | 110 | -- expression in Exprs. Returns true if all the parameters were bound. |
b5bad5ea | 111 | function Bind (Env : Env_Handle; Syms, Exprs : Types.List_Mal_Type) |
c3244bcf | 112 | return Boolean is |
13ce1681 CM |
113 | use Types; |
114 | S, Expr : List_Mal_Type; | |
51fa7633 | 115 | First_Sym : Sym_Ptr; |
13ce1681 CM |
116 | begin |
117 | S := Syms; | |
118 | Expr := Exprs; | |
a90ea3c7 | 119 | while not Is_Null (S) loop |
c3244bcf | 120 | |
51fa7633 | 121 | First_Sym := Deref_Sym (Car (S)); |
c3244bcf | 122 | |
51fa7633 | 123 | if First_Sym.Get_Sym = "&" then |
a90ea3c7 | 124 | S := Deref_List (Cdr (S)).all; |
51fa7633 | 125 | First_Sym := Deref_Sym (Car (S)); |
b5bad5ea | 126 | Set (Env, First_Sym.Get_Sym, New_List_Mal_Type (Expr)); |
c3244bcf | 127 | return True; |
a90ea3c7 | 128 | end if; |
c3244bcf | 129 | |
b5bad5ea | 130 | Set (Env, First_Sym.Get_Sym, Car (Expr)); |
13ce1681 | 131 | S := Deref_List (Cdr (S)).all; |
a90ea3c7 | 132 | exit when Is_Null (Expr); |
13ce1681 | 133 | Expr := Deref_List (Cdr (Expr)).all; |
c3244bcf | 134 | |
13ce1681 | 135 | end loop; |
c3244bcf | 136 | return Is_Null (S); |
13ce1681 CM |
137 | end Bind; |
138 | ||
139 | ||
13ce1681 CM |
140 | function Deref (SP : Env_Handle) return Env_Ptr is |
141 | begin | |
142 | return Env_Ptr (Smart_Pointers.Deref (Smart_Pointers.Smart_Pointer (SP))); | |
143 | end Deref; | |
144 | ||
145 | ||
9a6f4925 | 146 | end Envs; |