1 with Ada
.Containers
.Hashed_Maps
;
2 with Ada
.Strings
.Unbounded
.Hash
;
4 with Ada
.IO_Exceptions
;
11 procedure Step2_Eval
is
15 -- primitive functions on Smart_Pointer,
16 function "+" is new Arith_Op
("+", "+");
17 function "-" is new Arith_Op
("-", "-");
18 function "*" is new Arith_Op
("*", "*");
19 function "/" is new Arith_Op
("/", "/");
21 -- Take a list with two parameters and produce a single result
22 -- using the Op access-to-function parameter.
24 (Op
: Binary_Func_Access
; LH
: Mal_Handle
)
26 Left
, Right
: Mal_Handle
;
27 L
, Rest_List
: List_Mal_Type
;
29 L
:= Deref_List
(LH
).all;
31 Rest_List
:= Deref_List
(Cdr
(L
)).all;
32 Right
:= Car
(Rest_List
);
33 return Op
(Left
, Right
);
37 function Plus
(Rest_Handle
: Mal_Handle
)
38 return Types
.Mal_Handle
is
40 return Reduce2
(Step2_Eval
."+"'Unrestricted_Access, Rest_Handle);
44 function Minus (Rest_Handle : Mal_Handle)
45 return Types.Mal_Handle is
47 return Reduce2 (Step2_Eval."-"'Unrestricted_Access
, Rest_Handle
);
51 function Mult
(Rest_Handle
: Mal_Handle
)
52 return Types
.Mal_Handle
is
54 return Reduce2
(Step2_Eval
."*"'Unrestricted_Access, Rest_Handle);
58 function Divide (Rest_Handle : Mal_Handle)
59 return Types.Mal_Handle is
61 return Reduce2 (Step2_Eval."/"'Unrestricted_Access
, Rest_Handle
);
65 package String_Mal_Hash
is new Ada
.Containers
.Hashed_Maps
66 (Key_Type
=> Ada
.Strings
.Unbounded
.Unbounded_String
,
67 Element_Type
=> Smart_Pointers
.Smart_Pointer
,
68 Hash
=> Ada
.Strings
.Unbounded
.Hash
,
69 Equivalent_Keys
=> Ada
.Strings
.Unbounded
."=",
70 "=" => Smart_Pointers
."=");
72 Not_Found
: exception;
74 function Get
(M
: String_Mal_Hash
.Map
; K
: String) return Mal_Handle
is
78 C
:= Find
(M
, Ada
.Strings
.Unbounded
.To_Unbounded_String
(K
));
79 if C
= No_Element
then
87 Repl_Env
: String_Mal_Hash
.Map
;
90 function Eval
(Param
: Types
.Mal_Handle
; Env
: String_Mal_Hash
.Map
)
91 return Types
.Mal_Handle
;
94 Debug
: Boolean := False;
97 function Read
(Param
: String) return Types
.Mal_Handle
is
99 return Reader
.Read_Str
(Param
);
104 (Ast
: Mal_Handle
; Env
: String_Mal_Hash
.Map
)
107 function Call_Eval
(A
: Mal_Handle
) return Mal_Handle
is
109 return Eval
(A
, Env
);
114 case Deref
(Ast
).Sym_Type
is
119 Sym
: Mal_String
:= Deref_Sym
(Ast
).Get_Sym
;
121 -- if keyword, return it. Otherwise look it up in the environment.
125 return Get
(Env
, Sym
);
129 raise Not_Found
with ("'" & Sym
& "' not found");
134 return Map
(Call_Eval
'Unrestricted_Access, Deref_List_Class
(Ast
).all);
136 when others => return Ast
;
143 function Eval
(Param
: Mal_Handle
; Env
: String_Mal_Hash
.Map
)
145 First_Elem
: Mal_Handle
;
149 Ada
.Text_IO
.Put_Line
("Evaling " & Deref
(Param
).To_String
);
152 if Deref
(Param
).Sym_Type
= List
and then
153 Deref_List
(Param
).Get_List_Type
= List_List
then
156 Evaled_H
, First_Param
: Mal_Handle
;
157 Evaled_List
: List_Mal_Type
;
158 Param_List
: List_Mal_Type
;
160 Param_List
:= Deref_List
(Param
).all;
162 -- Deal with empty list..
163 if Param_List
.Length
= 0 then
167 Evaled_H
:= Eval_Ast
(Param
, Env
);
168 Evaled_List
:= Deref_List
(Evaled_H
).all;
169 First_Param
:= Car
(Evaled_List
);
170 return Call_Func
(Deref_Func
(First_Param
).all, Cdr
(Evaled_List
));
173 else -- Not a List_List
175 return Eval_Ast
(Param
, Env
);
182 function Print
(Param
: Types
.Mal_Handle
) return String is
184 return Printer
.Pr_Str
(Param
);
188 function Rep
(Param
: String; Env
: String_Mal_Hash
.Map
) return String is
189 AST
, Evaluated_AST
: Types
.Mal_Handle
;
194 if Types
.Is_Null
(AST
) then
197 Evaluated_AST
:= Eval
(AST
, Env
);
198 return Print
(Evaluated_AST
);
204 S
: String (1..Reader
.Max_Line_Len
);
209 String_Mal_Hash
.Include
210 (Container
=> Repl_Env
,
211 Key
=> Ada
.Strings
.Unbounded
.To_Unbounded_String
("+"),
212 New_Item
=> New_Func_Mal_Type
("+", Plus
'Unrestricted_access));
214 String_Mal_Hash
.Include
215 (Container
=> Repl_Env
,
216 Key
=> Ada
.Strings
.Unbounded
.To_Unbounded_String
("-"),
217 New_Item
=> New_Func_Mal_Type
("-", Minus
'Unrestricted_access));
219 String_Mal_Hash
.Include
220 (Container
=> Repl_Env
,
221 Key
=> Ada
.Strings
.Unbounded
.To_Unbounded_String
("*"),
222 New_Item
=> New_Func_Mal_Type
("*", Mult
'Unrestricted_access));
224 String_Mal_Hash
.Include
225 (Container
=> Repl_Env
,
226 Key
=> Ada
.Strings
.Unbounded
.To_Unbounded_String
("/"),
227 New_Item
=> New_Func_Mal_Type
("/", Divide
'Unrestricted_access));
231 Ada
.Text_IO
.Put
("user> ");
232 Ada
.Text_IO
.Get_Line
(S
, Last
);
233 Ada
.Text_IO
.Put_Line
(Rep
(S
(1..Last
), Repl_Env
));
235 when Ada
.IO_Exceptions
.End_Error
=> raise;
238 (Ada
.Text_IO
.Standard_Error
,
239 Ada
.Exceptions
.Exception_Information
(E
));
244 when Ada
.IO_Exceptions
.End_Error
=> null;
245 -- i.e. exit without textual output