Commit | Line | Data |
---|---|---|
9a6f4925 | 1 | with Ada.Text_IO; |
18a94a9f | 2 | with Ada.Exceptions; |
9a6f4925 CM |
3 | with Envs; |
4 | with Smart_Pointers; | |
5 | ||
6 | package body Evaluation is | |
7 | ||
13ce1681 | 8 | use Types; |
9a6f4925 | 9 | |
13ce1681 | 10 | procedure Add_Defs (Defs : List_Mal_Type; Env : Envs.Env_Handle) is |
09c532ba CM |
11 | D, L : List_Mal_Type; |
12 | begin | |
13 | if Debug then | |
14 | Ada.Text_IO.Put_Line ("Add_Defs " & To_String (Defs)); | |
15 | end if; | |
16 | D := Defs; | |
13ce1681 | 17 | while not Is_Null (D) loop |
09c532ba CM |
18 | L := Deref_List (Cdr (D)).all; |
19 | Envs.Set | |
13ce1681 CM |
20 | (Env, |
21 | Deref_Atom (Car (D)).Get_Atom, | |
22 | Eval (Car (L), Env)); | |
09c532ba CM |
23 | D := Deref_List (Cdr(L)).all; |
24 | end loop; | |
25 | end Add_Defs; | |
26 | ||
13ce1681 | 27 | |
0571a45f | 28 | function Def_Fn (Args : List_Mal_Type; Env : Envs.Env_Handle) |
c3244bcf | 29 | return Mal_Handle is |
09c532ba CM |
30 | Name, Fn_Body, Res : Mal_Handle; |
31 | begin | |
32 | Name := Car (Args); | |
33 | pragma Assert (Deref (Name).Sym_Type = Atom, | |
34 | "Def_Fn: expected atom as name"); | |
35 | Fn_Body := Car (Deref_List (Cdr (Args)).all); | |
13ce1681 CM |
36 | Res := Eval (Fn_Body, Env); |
37 | Envs.Set (Envs.Get_Current, Deref_Atom (Name).Get_Atom, Res); | |
09c532ba CM |
38 | return Res; |
39 | end Def_Fn; | |
40 | ||
41 | ||
35171f88 CM |
42 | function Def_Macro (Args : List_Mal_Type; Env : Envs.Env_Handle) |
43 | return Mal_Handle is | |
44 | Name, Fn_Body, Res : Mal_Handle; | |
45 | Lambda_P : Lambda_Ptr; | |
46 | begin | |
47 | Name := Car (Args); | |
48 | pragma Assert (Deref (Name).Sym_Type = Atom, | |
49 | "Def_Macro: expected atom as name"); | |
50 | Fn_Body := Car (Deref_List (Cdr (Args)).all); | |
51 | Res := Eval (Fn_Body, Env); | |
52 | Lambda_P := Deref_Lambda (Res); | |
53 | Lambda_P.Set_Is_Macro (True); | |
54 | Envs.Set (Envs.Get_Current, Deref_Atom (Name).Get_Atom, Res); | |
55 | return Res; | |
56 | end Def_Macro; | |
57 | ||
58 | ||
59 | function Macro_Expand (Ast : Mal_Handle; Env : Envs.Env_Handle) | |
60 | return Mal_Handle is | |
61 | Res : Mal_Handle; | |
4356e17f | 62 | E : Envs.Env_Handle; |
35171f88 | 63 | LMT : List_Mal_Type; |
4356e17f | 64 | LP : Lambda_Ptr; |
35171f88 CM |
65 | begin |
66 | ||
67 | Res := Ast; | |
4356e17f | 68 | E := Env; |
35171f88 CM |
69 | |
70 | loop | |
71 | ||
72 | if Deref (Res).Sym_Type /= List then | |
4356e17f | 73 | exit; |
35171f88 CM |
74 | end if; |
75 | ||
76 | LMT := Deref_List (Res).all; | |
77 | ||
4356e17f CM |
78 | -- Get the macro in the list from the env |
79 | -- or return null if not applicable. | |
80 | LP := Get_Macro (Res, E); | |
35171f88 CM |
81 | |
82 | exit when LP = null or else not LP.Get_Is_Macro; | |
83 | ||
84 | declare | |
85 | Fn_List : Mal_Handle := Cdr (LMT); | |
86 | Params : List_Mal_Type; | |
35171f88 | 87 | begin |
4356e17f CM |
88 | E := Envs.New_Env (E); |
89 | ||
35171f88 CM |
90 | Params := Deref_List (LP.Get_Params).all; |
91 | if Envs.Bind (E, Params, Deref_List (Fn_List).all) then | |
92 | ||
93 | Res := Eval (LP.Get_Expr, E); | |
94 | ||
95 | end if; | |
96 | ||
97 | end; | |
98 | ||
99 | end loop; | |
100 | ||
101 | return Res; | |
102 | ||
103 | end Macro_Expand; | |
104 | ||
105 | ||
0571a45f | 106 | function Let_Processing (Args : List_Mal_Type; Env : Envs.Env_Handle) |
c3244bcf | 107 | return Mal_Handle is |
09c532ba | 108 | Defs, Expr, Res : Mal_Handle; |
4356e17f | 109 | E : Envs.Env_Handle; |
09c532ba | 110 | begin |
4356e17f | 111 | E := Envs.New_Env (Env); |
09c532ba | 112 | Defs := Car (Args); |
4356e17f | 113 | Add_Defs (Deref_List (Defs).all, E); |
09c532ba | 114 | Expr := Car (Deref_List (Cdr (Args)).all); |
4356e17f | 115 | Res := Eval (Expr, E); |
09c532ba CM |
116 | return Res; |
117 | end Let_Processing; | |
118 | ||
119 | ||
0571a45f | 120 | function Eval_As_Boolean (MH : Mal_Handle) return Boolean is |
13ce1681 CM |
121 | Res : Boolean; |
122 | begin | |
123 | case Deref (MH).Sym_Type is | |
124 | when Bool => | |
125 | Res := Deref_Bool (MH).Get_Bool; | |
126 | when Atom => | |
127 | return not (Deref_Atom (MH).Get_Atom = "nil"); | |
128 | -- when List => | |
129 | -- declare | |
130 | -- L : List_Mal_Type; | |
131 | -- begin | |
132 | -- L := Deref_List (MH).all; | |
133 | -- Res := not Is_Null (L); | |
134 | -- end; | |
135 | when others => -- Everything else | |
136 | Res := True; | |
137 | end case; | |
138 | return Res; | |
139 | end Eval_As_Boolean; | |
140 | ||
141 | ||
9a6f4925 | 142 | function Eval_Ast |
0571a45f | 143 | (Ast : Mal_Handle; Env : Envs.Env_Handle) |
c3244bcf | 144 | return Mal_Handle is |
13ce1681 | 145 | |
13ce1681 CM |
146 | function Call_Eval (A : Mal_Handle) return Mal_Handle is |
147 | begin | |
148 | return Eval (A, Env); | |
149 | end Call_Eval; | |
150 | ||
9a6f4925 | 151 | begin |
09c532ba | 152 | |
9a6f4925 | 153 | case Deref (Ast).Sym_Type is |
09c532ba | 154 | |
066c5345 | 155 | when Atom => |
09c532ba | 156 | |
066c5345 | 157 | declare |
efaad1ce | 158 | Sym : Mal_String := Deref_Atom (Ast).Get_Atom; |
066c5345 | 159 | begin |
13ce1681 | 160 | -- if keyword or nil (which may represent False)... |
05a96502 CM |
161 | if Sym(1) = ':' then |
162 | return Ast; | |
163 | else | |
13ce1681 | 164 | return Envs.Get (Env, Sym); |
05a96502 | 165 | end if; |
066c5345 CM |
166 | exception |
167 | when Envs.Not_Found => | |
18a94a9f | 168 | raise Envs.Not_Found with (" '" & Sym & "' not found "); |
066c5345 | 169 | end; |
09c532ba | 170 | |
9a6f4925 | 171 | when List => |
09c532ba | 172 | |
13ce1681 | 173 | return Map (Call_Eval'Unrestricted_Access, Deref_List (Ast).all); |
09c532ba | 174 | |
efaad1ce CM |
175 | when Lambda => |
176 | ||
177 | -- Evaluating a lambda in a different Env. | |
178 | declare | |
179 | L : Lambda_Ptr; | |
180 | New_Env : Envs.Env_Handle; | |
181 | begin | |
182 | L := Deref_Lambda (Ast); | |
183 | New_Env := Env; | |
184 | -- Make the current Lambda's env the outer of the env param. | |
185 | Envs.Set_Outer (New_Env, L.Get_Env); | |
186 | -- Make the Lambda's Env. | |
187 | L.Set_Env (New_Env); | |
188 | return Ast; | |
189 | end; | |
190 | ||
09c532ba CM |
191 | when others => return Ast; |
192 | ||
9a6f4925 | 193 | end case; |
09c532ba | 194 | |
9a6f4925 CM |
195 | end Eval_Ast; |
196 | ||
09c532ba | 197 | |
0571a45f | 198 | function Do_Processing (Do_List : List_Mal_Type; Env : Envs.Env_Handle) |
c3244bcf | 199 | return Mal_Handle is |
13ce1681 CM |
200 | D : List_Mal_Type; |
201 | Res : Mal_Handle := Smart_Pointers.Null_Smart_Pointer; | |
202 | begin | |
203 | if Debug then | |
204 | Ada.Text_IO.Put_Line ("Do-ing " & To_String (Do_List)); | |
205 | end if; | |
206 | D := Do_List; | |
207 | while not Is_Null (D) loop | |
efaad1ce | 208 | Res := Eval (Car (D), Env); |
13ce1681 CM |
209 | D := Deref_List (Cdr(D)).all; |
210 | end loop; | |
211 | return Res; | |
212 | end Do_Processing; | |
213 | ||
214 | ||
4a33fde1 | 215 | function Quasi_Quote_Processing (Param : Mal_Handle) return Mal_Handle is |
7afdd78d | 216 | Res, First_Elem, FE_0 : Mal_Handle; |
4a33fde1 CM |
217 | D, Ast : List_Mal_Type; |
218 | L : List_Ptr; | |
219 | begin | |
220 | ||
7afdd78d CM |
221 | if Debug then |
222 | Ada.Text_IO.Put_Line ("QuasiQt " & Deref (Param).To_String); | |
223 | end if; | |
224 | ||
38d0c57f CM |
225 | -- Create a New List for the result... |
226 | Res := New_List_Mal_Type (List_List); | |
227 | L := Deref_List (Res); | |
228 | ||
7afdd78d CM |
229 | -- This is the equivalent of Is_Pair |
230 | if Deref (Param).Sym_Type /= List or else | |
231 | Is_Null (Deref_List (Param).all) then | |
232 | ||
233 | -- return a new list containing: a symbol named "quote" and ast. | |
38d0c57f CM |
234 | L.Append (New_Atom_Mal_Type ("quote")); |
235 | L.Append (Param); | |
236 | return Res; | |
7afdd78d | 237 | |
4a33fde1 CM |
238 | end if; |
239 | ||
7afdd78d CM |
240 | -- Ast is a non-empty list at this point. |
241 | ||
4a33fde1 CM |
242 | Ast := Deref_List (Param).all; |
243 | ||
7afdd78d | 244 | First_Elem := Car (Ast); |
4a33fde1 | 245 | |
7afdd78d CM |
246 | -- if the first element of ast is a symbol named "unquote": |
247 | if Deref (First_Elem).Sym_Type = Atom and then | |
248 | Deref_Atom (First_Elem).Get_Atom = "unquote" then | |
4a33fde1 | 249 | |
7afdd78d CM |
250 | -- return the second element of ast.` |
251 | D := Deref_List (Cdr (Ast)).all; | |
252 | return Car (D); | |
4a33fde1 | 253 | |
7afdd78d | 254 | end if; |
4a33fde1 | 255 | |
7afdd78d CM |
256 | -- if the first element of first element of `ast` (`ast[0][0]`) |
257 | -- is a symbol named "splice-unquote" | |
258 | if Deref (First_Elem).Sym_Type = List and then | |
259 | not Is_Null (Deref_List (First_Elem).all) then | |
4a33fde1 | 260 | |
7afdd78d CM |
261 | D := Deref_List (First_Elem).all; |
262 | FE_0 := Car (D); | |
4a33fde1 | 263 | |
7afdd78d CM |
264 | if Deref (FE_0).Sym_Type = Atom and then |
265 | Deref_Atom (FE_0).Get_Atom = "splice-unquote" then | |
4a33fde1 | 266 | |
7afdd78d CM |
267 | -- return a new list containing: a symbol named "concat", |
268 | L.Append (New_Atom_Mal_Type ("concat")); | |
4a33fde1 | 269 | |
7afdd78d CM |
270 | -- the second element of first element of ast (ast[0][1]), |
271 | D := Deref_List (Cdr (D)).all; | |
272 | L.Append (Car (D)); | |
4a33fde1 | 273 | |
7afdd78d CM |
274 | -- and the result of calling quasiquote with |
275 | -- the second through last element of ast. | |
276 | L.Append (Quasi_Quote_Processing (Cdr (Ast))); | |
4a33fde1 | 277 | |
7afdd78d | 278 | return Res; |
4a33fde1 | 279 | |
4a33fde1 | 280 | end if; |
7afdd78d | 281 | |
4a33fde1 CM |
282 | end if; |
283 | ||
284 | -- otherwise: return a new list containing: a symbol named "cons", | |
285 | L.Append (New_Atom_Mal_Type ("cons")); | |
286 | ||
287 | -- the result of calling quasiquote on first element of ast (ast[0]), | |
288 | L.Append (Quasi_Quote_Processing (Car (Ast))); | |
289 | ||
290 | -- and result of calling quasiquote with the second through last element of ast. | |
291 | L.Append (Quasi_Quote_Processing (Cdr (Ast))); | |
292 | ||
293 | return Res; | |
294 | ||
295 | end Quasi_Quote_Processing; | |
296 | ||
297 | ||
18a94a9f CM |
298 | function Catch_Processing |
299 | (Try_Line : Mal_Handle; | |
54d1f71e | 300 | ExStr : Mal_Handle; |
18a94a9f CM |
301 | Env : Envs.Env_Handle) |
302 | return Mal_Handle is | |
303 | ||
304 | L, CL, CL2, CL3 : List_Mal_Type; | |
305 | C : Mal_Handle; | |
306 | New_Env : Envs.Env_Handle; | |
307 | ||
308 | begin | |
309 | ||
310 | L := Deref_List (Try_Line).all; | |
311 | C := Car (L); | |
312 | -- CL is the list with the catch in. | |
313 | CL := Deref_List (C).all; | |
314 | ||
315 | CL2 := Deref_List (Cdr (CL)).all; | |
316 | New_Env := Envs.New_Env (Env); | |
54d1f71e | 317 | Envs.Set (New_Env, Deref_Atom (Car (CL2)).Get_Atom, ExStr); |
18a94a9f CM |
318 | |
319 | CL3 := Deref_List (Cdr (CL2)).all; | |
320 | return Eval (Car (CL3), New_Env); | |
321 | end Catch_Processing; | |
322 | ||
54d1f71e | 323 | Mal_Exception_Value : Mal_Handle; |
18a94a9f | 324 | |
a3c4ba44 | 325 | function Eval (AParam : Mal_Handle; AnEnv : Envs.Env_Handle) |
c3244bcf | 326 | return Mal_Handle is |
a3c4ba44 CM |
327 | Param : Mal_Handle; |
328 | Env : Envs.Env_Handle; | |
329 | First_Elem : Mal_Handle; | |
330 | begin | |
331 | ||
332 | Param := AParam; | |
333 | Env := AnEnv; | |
334 | ||
c3244bcf | 335 | <<Tail_Call_Opt>> |
a3c4ba44 CM |
336 | |
337 | if Debug then | |
338 | Ada.Text_IO.Put_Line ("Evaling " & Deref (Param).To_String); | |
339 | end if; | |
340 | ||
35171f88 CM |
341 | Param := Macro_Expand (Param, Env); |
342 | ||
343 | if Debug then | |
344 | Ada.Text_IO.Put_Line ("After expansion " & Deref (Param).To_String); | |
345 | end if; | |
346 | ||
a3c4ba44 | 347 | if Deref (Param).Sym_Type = List and then |
c3244bcf CM |
348 | Deref_List (Param).all.Get_List_Type = List_List then |
349 | ||
350 | declare | |
351 | L : Mal_Handle := Param; | |
352 | LMT, Rest_List : List_Mal_Type; | |
353 | First_Elem, Rest_Handle : Mal_Handle; | |
354 | begin | |
355 | ||
356 | LMT := Deref_List (L).all; | |
357 | ||
358 | First_Elem := Car (LMT); | |
359 | ||
360 | Rest_Handle := Cdr (LMT); | |
361 | ||
362 | Rest_List := Deref_List (Rest_Handle).all; | |
363 | ||
364 | case Deref (First_Elem).Sym_Type is | |
365 | ||
366 | when Int | Floating | Bool | Str => | |
367 | ||
368 | return First_Elem; | |
369 | ||
370 | when Atom => | |
371 | ||
372 | declare | |
373 | Atom_P : Atom_Ptr; | |
374 | begin | |
375 | Atom_P := Deref_Atom (First_Elem); | |
376 | if Atom_P.Get_Atom = "def!" then | |
377 | return Def_Fn (Rest_List, Env); | |
35171f88 CM |
378 | elsif Atom_P.Get_Atom = "defmacro!" then |
379 | return Def_Macro (Rest_List, Env); | |
380 | elsif Atom_P.Get_Atom = "macroexpand" then | |
714a6dbe | 381 | return Macro_Expand (Car (Rest_List), Env); |
c3244bcf CM |
382 | elsif Atom_P.Get_Atom = "let*" then |
383 | return Let_Processing (Rest_List, Env); | |
384 | elsif Atom_P.Get_Atom = "do" then | |
385 | return Do_Processing (Rest_List, Env); | |
386 | elsif Atom_P.Get_Atom = "if" then | |
387 | declare | |
388 | Args : List_Mal_Type := Rest_List; | |
389 | ||
390 | Cond, True_Part, False_Part : Mal_Handle; | |
391 | Cond_Bool : Boolean; | |
392 | pragma Assert (Length (Args) = 2 or Length (Args) = 3, | |
393 | "If_Processing: not 2 or 3 parameters"); | |
394 | L : List_Mal_Type; | |
395 | begin | |
396 | ||
397 | Cond := Eval (Car (Args), Env); | |
398 | ||
399 | Cond_Bool := Eval_As_Boolean (Cond); | |
400 | ||
401 | if Cond_Bool then | |
402 | L := Deref_List (Cdr (Args)).all; | |
403 | ||
404 | Param := Car (L); | |
405 | goto Tail_Call_Opt; | |
406 | -- was: return Eval (Car (L), Env); | |
407 | else | |
408 | if Length (Args) = 3 then | |
409 | L := Deref_List (Cdr (Args)).all; | |
410 | L := Deref_List (Cdr (L)).all; | |
411 | ||
412 | Param := Car (L); | |
413 | goto Tail_Call_Opt; | |
414 | -- was: return Eval (Car (L), Env); | |
415 | else | |
416 | return New_Atom_Mal_Type ("nil"); | |
417 | end if; | |
418 | end if; | |
419 | end; | |
420 | ||
943b0146 CM |
421 | elsif Atom_P.Get_Atom = "quote" then |
422 | return Car (Rest_List); | |
4a33fde1 CM |
423 | elsif Atom_P.Get_Atom = "quasiquote" then |
424 | Param := Quasi_Quote_Processing (Car (Rest_List)); | |
425 | goto Tail_Call_Opt; | |
18a94a9f CM |
426 | elsif Atom_P.Get_Atom = "try*" then |
427 | declare | |
54d1f71e | 428 | Res : Mal_Handle; |
18a94a9f CM |
429 | begin |
430 | return Eval (Car (Rest_List), Env); | |
431 | exception | |
432 | when Mal_Exception => | |
54d1f71e | 433 | Res := Catch_Processing |
18a94a9f | 434 | (Cdr (Rest_List), |
54d1f71e | 435 | Mal_Exception_Value, |
18a94a9f | 436 | Env); |
54d1f71e CM |
437 | Mal_Exception_Value := Smart_Pointers.Null_Smart_Pointer; |
438 | return Res; | |
18a94a9f CM |
439 | when E : others => |
440 | return Catch_Processing | |
441 | (Cdr (Rest_List), | |
54d1f71e CM |
442 | New_String_Mal_Type |
443 | (Ada.Exceptions.Exception_Message (E)), | |
18a94a9f CM |
444 | Env); |
445 | end; | |
54d1f71e CM |
446 | elsif Atom_P.Get_Atom = "throw" then |
447 | Mal_Exception_Value := Eval (Car (Rest_List), Env); | |
448 | raise Mal_Exception; | |
c3244bcf CM |
449 | else -- not a special form |
450 | ||
451 | -- Apply section | |
452 | declare | |
453 | Res : Mal_Handle; | |
454 | begin | |
455 | -- Eval the atom. | |
456 | Res := Eval_Ast (L, Env); | |
457 | Param := Res; | |
458 | goto Tail_Call_Opt; | |
459 | -- was: return Eval (Res, Env); | |
460 | end; | |
461 | ||
462 | end if; | |
463 | end; | |
464 | ||
465 | when Func => | |
466 | ||
467 | return Call_Func | |
468 | (Deref_Func (First_Elem).all, | |
469 | Rest_Handle, | |
470 | Env); | |
471 | ||
472 | when Lambda => | |
473 | ||
474 | declare | |
475 | LP : Lambda_Ptr := Deref_Lambda (First_Elem); | |
476 | Fn_List : Mal_Handle := Cdr (LMT); | |
477 | Params : List_Mal_Type; | |
478 | E : Envs.Env_Handle; | |
479 | begin | |
480 | E := Envs.New_Env (LP.Get_Env); | |
481 | Params := Deref_List (LP.Get_Params).all; | |
482 | if Envs.Bind (E, Params, Deref_List (Fn_List).all) then | |
483 | ||
484 | Param := LP.Get_Expr; | |
485 | Env := E; | |
486 | goto Tail_Call_Opt; | |
487 | -- was: return Eval (LP.Get_Expr, E); | |
488 | ||
a3c4ba44 | 489 | else |
c3244bcf | 490 | return First_Elem; |
a3c4ba44 | 491 | end if; |
a3c4ba44 | 492 | |
c3244bcf | 493 | end; |
efaad1ce | 494 | |
c3244bcf | 495 | when List => |
0571a45f | 496 | |
c3244bcf CM |
497 | -- First elem in the list is a list. |
498 | -- Eval it and then insert it as first elem in the list and | |
499 | -- go again. | |
500 | declare | |
501 | Evaled_List : Mal_Handle; | |
502 | E : Envs.Env_Handle; | |
503 | begin | |
504 | Evaled_List := Eval (First_Elem, Env); | |
505 | if Is_Null (Evaled_List) then | |
506 | return Evaled_List; | |
507 | elsif Deref (Evaled_List).Sym_Type = Lambda then | |
508 | E := Deref_Lambda (Evaled_List).Get_Env; | |
509 | else | |
510 | E := Env; | |
511 | end if; | |
13ce1681 | 512 | |
c3244bcf CM |
513 | Param := Prepend (Evaled_List, Rest_List); |
514 | Env := E; | |
515 | goto Tail_Call_Opt; | |
516 | -- was: | |
517 | -- Evaled_List := Prepend (Evaled_List, Rest_List); | |
518 | -- return Eval (Evaled_List, E); | |
519 | end; | |
0571a45f | 520 | |
c3244bcf | 521 | when Error => return First_Elem; |
0571a45f | 522 | |
c3244bcf | 523 | when Node => return New_Error_Mal_Type ("Evaluating a node"); |
13ce1681 | 524 | |
c3244bcf | 525 | when Unitary => null; -- Not yet impl |
efaad1ce | 526 | |
c3244bcf | 527 | end case; |
09c532ba | 528 | |
c3244bcf | 529 | end; |
09c532ba | 530 | |
943b0146 CM |
531 | elsif Deref (Param).Sym_Type = Unitary then |
532 | declare | |
533 | UMT : Types.Unitary_Mal_Type; | |
534 | begin | |
535 | UMT := Deref_Unitary (Param).all; | |
536 | case UMT.Get_Func is | |
4a33fde1 CM |
537 | when Quote => |
538 | return UMT.Get_Op; | |
539 | when QuasiQuote => | |
540 | Param := Quasi_Quote_Processing (UMT.Get_Op); | |
541 | goto Tail_Call_Opt; | |
38d0c57f CM |
542 | when Unquote => |
543 | Param := UMT.Get_Op; | |
544 | goto Tail_Call_Opt; | |
943b0146 CM |
545 | when others => null; |
546 | end case; | |
547 | end; | |
9a6f4925 | 548 | else |
09c532ba | 549 | |
13ce1681 | 550 | return Eval_Ast (Param, Env); |
09c532ba | 551 | |
9a6f4925 | 552 | end if; |
09c532ba | 553 | |
9a6f4925 CM |
554 | end Eval; |
555 | ||
556 | ||
557 | end Evaluation; |