1 with Ada
.Characters
.Latin_1
;
2 with Ada
.Strings
.Fixed
;
3 with Ada
.Strings
.Maps
.Constants
;
5 with Ada
.Unchecked_Deallocation
;
14 package ACL
renames Ada
.Characters
.Latin_1
;
16 function Nodes_Equal
(A
, B
: Mal_Handle
) return Boolean;
19 function "=" (A
, B
: Mal_Handle
) return Mal_Handle
is
21 return New_Bool_Mal_Type
(A
= B
);
25 function Compare_List_And_Vector
(A
: List_Mal_Type
; B
: List_Mal_Type
'Class)
27 First_Node
, First_Index
: Mal_Handle
;
30 First_Node
:= A
.The_List
;
32 if not Is_Null
(First_Node
) and I
< B
.Length
then
33 First_Index
:= B
.Nth
(I
);
34 if not "=" (Deref_Node
(First_Node
).Data
, First_Index
) then
37 First_Node
:= Deref_Node
(First_Node
).Next
;
40 return Is_Null
(First_Node
) and I
= B
.Length
;
43 end Compare_List_And_Vector
;
46 function "=" (A
, B
: Mal_Handle
) return Boolean is
51 if (not Is_Null
(A
) and not Is_Null
(B
)) and then
52 Deref
(A
).Sym_Type
= Deref
(B
).Sym_Type
then
54 case Deref
(A
).Sym_Type
is
56 return True; -- Both nil.
58 return (Deref_Int
(A
).Get_Int_Val
= Deref_Int
(B
).Get_Int_Val
);
60 return (Deref_Float
(A
).Get_Float_Val
= Deref_Float
(B
).Get_Float_Val
);
62 return (Deref_Bool
(A
).Get_Bool
= Deref_Bool
(B
).Get_Bool
);
64 -- When Types.Vector was added, the choice was:
65 -- 1) use interfaces (because you need a class hierachy for the containers
66 -- and a corresponding hierarchy for the cursors and Ada is single dispatch
68 -- 2) map out the combinations here and use nth to access vector items.
69 case Deref_List
(A
).Get_List_Type
is
71 case Deref_List
(B
).Get_List_Type
is
73 return Nodes_Equal
(Deref_List
(A
).The_List
, Deref_List
(B
).The_List
);
75 return Compare_List_And_Vector
76 (Deref_List
(A
).all, Deref_List_Class
(B
).all);
77 when Hashed_List
=> return False; -- Comparing a list and a hash
80 case Deref_List
(B
).Get_List_Type
is
82 return Compare_List_And_Vector
83 (Deref_List
(B
).all, Deref_List_Class
(A
).all);
85 return Vector
."=" (Deref_Vector
(A
).all, Deref_Vector
(B
).all);
86 when Hashed_List
=> return False; -- Comparing a vector and a hash
89 case Deref_List
(B
).Get_List_Type
is
90 when List_List
=> return False; -- Comparing a list and a hash
91 when Vector_List
=> return False; -- Comparing a vector and a hash
93 return Hash_Map
."=" (Deref_Hash
(A
).all, Deref_Hash
(B
).all);
97 return (Deref_String
(A
).Get_String
= Deref_String
(B
).Get_String
);
99 return (Deref_Sym
(A
).Get_Sym
= Deref_Sym
(B
).Get_Sym
);
101 return (Deref_Atom
(A
).Get_Atom
= Deref_Atom
(B
).Get_Atom
);
103 return (Deref_Func
(A
).Get_Func_Name
= Deref_Func
(B
).Get_Func_Name
);
105 return (Deref_Int
(A
).Get_Int_Val
= Deref_Int
(B
).Get_Int_Val
);
107 return (Deref_Int
(A
).Get_Int_Val
= Deref_Int
(B
).Get_Int_Val
);
109 return (Deref_Int
(A
).Get_Int_Val
= Deref_Int
(B
).Get_Int_Val
);
111 elsif Is_Null
(A
) and Is_Null
(B
) then
113 else -- either one of the args is null or the sym_types don't match
118 function Get_Meta
(T
: Mal_Type
) return Mal_Handle
is
120 if T
.Meta
= Smart_Pointers
.Null_Smart_Pointer
then
121 return New_Nil_Mal_Type
;
127 procedure Set_Meta
(T
: in out Mal_Type
'Class; SP
: Mal_Handle
) is
132 function Copy
(M
: Mal_Handle
) return Mal_Handle
is
134 return Smart_Pointers
.New_Ptr
135 (new Mal_Type
'Class'(Deref (M).all));
138 function To_String (T : Mal_Type'Class; Print_Readably : Boolean := True)
141 return To_Str (T, Print_Readably);
144 function Is_Macro_Call (T : Mal_Type'Class; Env : Envs.Env_Handle) return Boolean is
146 First_Elem, Func : Mal_Handle;
149 if T.Sym_Type /= List then
153 L := List_Mal_Type (T);
159 First_Elem := Car (L);
161 if Deref (First_Elem).Sym_Type /= Sym then
165 Func := Envs.Get (Env, Deref_Sym (First_Elem).Get_Sym);
167 if Deref (Func).Sym_Type /= Lambda then
171 return Deref_Lambda (Func).Get_Is_Macro;
174 when Envs.Not_Found => return False;
178 -- A helper function that just view converts the smart pointer.
179 function Deref (S : Mal_Handle) return Mal_Ptr is
181 return Mal_Ptr (Smart_Pointers.Deref (S));
184 -- A helper function to detect null smart pointers.
185 function Is_Null (S : Mal_Handle) return Boolean is
188 return Smart_Pointers."="(S, Null_Smart_Pointer);
192 -- To_Str on the abstract type...
193 function To_Str (T : Mal_Type; Print_Readably : Boolean := True)
196 raise Constraint_Error; -- Tha'll teach 'ee
197 return ""; -- Keeps the compiler happy.
201 function New_Nil_Mal_Type
return Mal_Handle
is
203 return Smart_Pointers
.New_Ptr
204 (new Nil_Mal_Type
'(Mal_Type with null record));
205 end New_Nil_Mal_Type;
207 overriding function Sym_Type (T : Nil_Mal_Type) return Sym_Types is
212 overriding function To_Str (T : Nil_Mal_Type; Print_Readably : Boolean := True)
219 function New_Int_Mal_Type (Int : Mal_Integer) return Mal_Handle is
221 return Smart_Pointers.New_Ptr
222 (new Int_Mal_Type'(Mal_Type
with Int_Val
=> Int
));
223 end New_Int_Mal_Type
;
225 overriding
function Sym_Type
(T
: Int_Mal_Type
) return Sym_Types
is
230 function Get_Int_Val
(T
: Int_Mal_Type
) return Mal_Integer
is
235 overriding
function To_Str
236 (T
: Int_Mal_Type
; Print_Readably
: Boolean := True)
238 Res
: Mal_String
:= Mal_Integer
'Image (T
.Int_Val
);
240 return Ada
.Strings
.Fixed
.Trim
(Res
, Ada
.Strings
.Left
);
243 function Deref_Int
(SP
: Mal_Handle
) return Int_Ptr
is
245 return Int_Ptr
(Deref
(SP
));
249 function New_Float_Mal_Type
(Floating
: Mal_Float
) return Mal_Handle
is
251 return Smart_Pointers
.New_Ptr
252 (new Float_Mal_Type
'(Mal_Type with Float_Val => Floating));
253 end New_Float_Mal_Type;
255 overriding function Sym_Type (T : Float_Mal_Type) return Sym_Types is
260 function Get_Float_Val (T : Float_Mal_Type) return Mal_Float is
265 overriding function To_Str
266 (T : Float_Mal_Type; Print_Readably : Boolean := True)
268 Res : Mal_String := Mal_Float'Image (T.Float_Val);
270 return Ada.Strings.Fixed.Trim (Res, Ada.Strings.Left);
273 function Deref_Float (SP : Mal_Handle) return Float_Ptr is
275 return Float_Ptr (Deref (SP));
279 function New_Bool_Mal_Type (Bool : Boolean) return Mal_Handle is
281 return Smart_Pointers.New_Ptr
282 (new Bool_Mal_Type'(Mal_Type
with Bool_Val
=> Bool
));
283 end New_Bool_Mal_Type
;
285 overriding
function Sym_Type
(T
: Bool_Mal_Type
) return Sym_Types
is
290 function Get_Bool
(T
: Bool_Mal_Type
) return Boolean is
295 overriding
function To_Str
296 (T
: Bool_Mal_Type
; Print_Readably
: Boolean := True)
298 Res
: Mal_String
:= Boolean'Image (T
.Bool_Val
);
300 return Ada
.Strings
.Fixed
.Translate
301 (Res
, Ada
.Strings
.Maps
.Constants
.Lower_Case_Map
);
304 function Deref_Bool
(SP
: Mal_Handle
) return Bool_Ptr
is
306 return Bool_Ptr
(Deref
(SP
));
310 function New_String_Mal_Type
(Str
: Mal_String
) return Mal_Handle
is
312 return Smart_Pointers
.New_Ptr
313 (new String_Mal_Type
' (Mal_Type with The_String =>
314 Ada.Strings.Unbounded.To_Unbounded_String (Str)));
315 end New_String_Mal_Type;
317 overriding function Sym_Type (T : String_Mal_Type) return Sym_Types is
322 function Get_String (T : String_Mal_Type) return Mal_String is
324 return Ada.Strings.Unbounded.To_String (T.The_String);
327 function Deref_String (SP : Mal_Handle) return String_Ptr is
329 return String_Ptr (Deref (SP));
333 overriding function To_Str
334 (T : String_Mal_Type; Print_Readably : Boolean := True)
336 use Ada.Strings.Unbounded;
339 Res : Unbounded_String;
342 if Print_Readably then
344 Str_Len := Length (T.The_String);
345 while I <= Str_Len loop
346 Ch := Element (T.The_String, I);
351 elsif Ch = Ada.Characters.Latin_1.LF then
359 return To_String (Res);
361 return To_String (T.The_String);
366 function New_Symbol_Mal_Type (Str : Mal_String) return Mal_Handle is
368 return Smart_Pointers.New_Ptr
369 (new Symbol_Mal_Type'(Mal_Type with The_Symbol =>
370 Ada.Strings.Unbounded.To_Unbounded_String (Str)));
371 end New_Symbol_Mal_Type;
373 overriding function Sym_Type (T : Symbol_Mal_Type) return Sym_Types is
378 function Get_Sym (T : Symbol_Mal_Type) return Mal_String is
380 return Ada.Strings.Unbounded.To_String (T.The_Symbol);
383 function Deref_Sym (S : Mal_Handle) return Sym_Ptr is
385 return Sym_Ptr (Deref (S));
388 overriding function To_Str
389 (T : Symbol_Mal_Type; Print_Readably : Boolean := True)
392 return Ada.Strings.Unbounded.To_String (T.The_Symbol);
396 function New_Atom_Mal_Type (MH : Mal_Handle) return Mal_Handle is
398 return Smart_Pointers.New_Ptr
399 (new Atom_Mal_Type'(Mal_Type with The_Atom => MH));
400 end New_Atom_Mal_Type;
402 overriding function Sym_Type (T : Atom_Mal_Type) return Sym_Types is
407 function Get_Atom (T : Atom_Mal_Type) return Mal_Handle is
412 procedure Set_Atom (T : in out Atom_Mal_Type; New_Val : Mal_Handle) is
414 T.The_Atom := New_Val;
417 function Deref_Atom (S : Mal_Handle) return Atom_Ptr is
419 return Atom_Ptr (Deref (S));
422 overriding function To_Str
423 (T : Atom_Mal_Type; Print_Readably : Boolean := True)
426 return "(atom
" & To_String (Deref (T.The_Atom).all) & ')';
430 function New_Func_Mal_Type (Str : Mal_String; F : Builtin_Func)
433 return Smart_Pointers.New_Ptr
434 (new Func_Mal_Type'(Mal_Type with
435 Func_Name => Ada.Strings.Unbounded.To_Unbounded_String (Str),
437 end New_Func_Mal_Type;
439 overriding function Sym_Type (T : Func_Mal_Type) return Sym_Types is
444 function Get_Func_Name (T : Func_Mal_Type) return Mal_String is
446 return Ada.Strings.Unbounded.To_String (T.Func_Name);
450 (FMT : Func_Mal_Type; Rest_List : Mal_Handle)
453 return FMT.Func_P (Rest_List);
456 function Deref_Func (S : Mal_Handle) return Func_Ptr is
458 return Func_Ptr (Deref (S));
461 overriding function To_Str
462 (T : Func_Mal_Type; Print_Readably : Boolean := True)
465 return Ada.Strings.Unbounded.To_String (T.Func_Name);
469 function New_Error_Mal_Type (Str : Mal_String) return Mal_Handle is
471 return Smart_Pointers.New_Ptr
472 (new Error_Mal_Type'(Mal_Type with Error_Msg =>
473 Ada.Strings.Unbounded.To_Unbounded_String (Str)));
474 end New_Error_Mal_Type;
476 overriding function Sym_Type (T : Error_Mal_Type) return Sym_Types is
481 overriding function To_Str
482 (T : Error_Mal_Type; Print_Readably : Boolean := True)
485 return Ada.Strings.Unbounded.To_String (T.Error_Msg);
489 function Nodes_Equal (A, B : Mal_Handle) return Boolean is
491 if (not Is_Null (A) and not Is_Null (B)) and then
492 Deref (A).Sym_Type = Deref (B).Sym_Type then
493 if Deref (A).Sym_Type = Node then
495 Nodes_Equal (Deref_Node (A).Data, Deref_Node (B).Data) and then
496 Nodes_Equal (Deref_Node (A).Next, Deref_Node (B).Next);
500 elsif Is_Null (A) and Is_Null (B) then
502 else -- either one of the args is null or the sym_types don't match
508 function New_Node_Mal_Type
510 Next : Mal_Handle := Smart_Pointers.Null_Smart_Pointer)
513 return Smart_Pointers.New_Ptr
515 (Mal_Type with Data => Data, Next => Next));
516 end New_Node_Mal_Type;
519 overriding function Sym_Type (T : Node_Mal_Type) return Sym_Types is
525 -- Get the first item in the list:
526 function Car (L : List_Mal_Type) return Mal_Handle is
528 if Is_Null (L.The_List) then
529 return Smart_Pointers.Null_Smart_Pointer;
531 return Deref_Node (L.The_List).Data;
536 -- Get the rest of the list (second item onwards)
537 function Cdr (L : List_Mal_Type) return Mal_Handle is
542 Res := New_List_Mal_Type (L.List_Type);
544 if Is_Null (L.The_List) or else
545 Is_Null (Deref_Node (L.The_List).Next) then
548 LP := Deref_List (Res);
549 LP.The_List := Deref_Node (L.The_List).Next;
550 LP.Last_Elem := L.Last_Elem;
556 function Length (L : List_Mal_Type) return Natural is
561 NP := Deref_Node (L.The_List);
562 while NP /= null loop
564 NP := Deref_Node (NP.Next);
570 function Is_Null (L : List_Mal_Type) return Boolean is
573 return Smart_Pointers."="(L.The_List, Null_Smart_Pointer);
577 function Null_List (L : List_Types) return List_Mal_Type is
579 return (Mal_Type with List_Type => L,
580 The_List => Smart_Pointers.Null_Smart_Pointer,
581 Last_Elem => Smart_Pointers.Null_Smart_Pointer);
586 (Func_Ptr : Func_Access;
590 Res, Old_List, First_New_Node, New_List : Mal_Handle;
595 Res := New_List_Mal_Type (List_Type => L.Get_List_Type);
597 Old_List := L.The_List;
599 if Is_Null (Old_List) then
603 First_New_Node := New_Node_Mal_Type (Func_Ptr.all (Deref_Node (Old_List).Data));
605 New_List := First_New_Node;
607 Old_List := Deref_Node (Old_List).Next;
609 while not Is_Null (Old_List) loop
611 Deref_Node (New_List).Next :=
612 New_Node_Mal_Type (Func_Ptr.all (Deref_Node (Old_List).Data));
614 New_List := Deref_Node (New_List).Next;
616 Old_List := Deref_Node (Old_List).Next;
620 LP := Deref_List (Res);
621 LP.The_List := First_New_Node;
622 LP.Last_Elem := New_List;
630 (Func_Ptr : Binary_Func_Access;
640 C_Node := Deref_Node (L.The_List);
642 if C_Node = null then
643 return Smart_Pointers.Null_Smart_Pointer;
647 while not Is_Null (C_Node.Next) loop
648 C_Node := Deref_Node (C_Node.Next);
649 Res := Func_Ptr (Res, C_Node.Data);
657 overriding function To_Str
658 (T : Node_Mal_Type; Print_Readably : Boolean := True)
661 if Is_Null (T.Data) then
662 -- Left is null and by implication so is right.
664 elsif Is_Null (T.Next) then
665 -- Left is not null but right is.
666 return To_Str (Deref (T.Data).all, Print_Readably);
668 -- Left and right are both not null.
669 return To_Str (Deref (T.Data).all, Print_Readably) &
671 To_Str (Deref (T.Next).all, Print_Readably);
676 function Cat_Str (T : Node_Mal_Type; Print_Readably : Boolean := True)
679 if Is_Null (T.Data) then
680 -- Left is null and by implication so is right.
682 elsif Is_Null (T.Next) then
683 -- Left is not null but right is.
684 return To_Str (Deref (T.Data).all, Print_Readably);
686 -- Left and right are both not null.
688 return To_Str (Deref (T.Data).all, Print_Readably) &
689 Cat_Str (Deref_Node (T.Next).all, Print_Readably);
694 function Deref_Node (SP : Mal_Handle) return Node_Ptr is
696 return Node_Ptr (Deref (SP));
700 function "=" (A, B : List_Mal_Type) return Boolean is
702 return Nodes_Equal (A.The_List, B.The_List);
705 function New_List_Mal_Type
706 (The_List : List_Mal_Type)
709 return Smart_Pointers.New_Ptr
710 (new List_Mal_Type'(Mal_Type with
711 List_Type => The_List.List_Type,
712 The_List => The_List.The_List,
713 Last_Elem => The_List.Last_Elem));
714 end New_List_Mal_Type;
717 function New_List_Mal_Type
718 (List_Type : List_Types;
719 The_First_Node : Mal_Handle := Smart_Pointers.Null_Smart_Pointer)
722 return Smart_Pointers.New_Ptr
725 List_Type => List_Type,
726 The_List => The_First_Node,
727 Last_Elem => The_First_Node));
728 end New_List_Mal_Type;
731 function Make_New_List (Handle_List : Handle_Lists) return Mal_Handle is
733 List_SP : Mal_Handle;
737 List_SP := New_List_Mal_Type (List_Type => List_List);
738 List_P := Deref_List (List_SP);
739 for I in Handle_List'Range loop
740 Append (List_P.all, Handle_List (I));
746 overriding function Sym_Type (T : List_Mal_Type) return Sym_Types is
752 function Get_List_Type (L : List_Mal_Type) return List_Types is
758 function Prepend (Op : Mal_Handle; To_List : List_Mal_Type)
761 return New_List_Mal_Type
763 New_Node_Mal_Type (Op, To_List.The_List));
767 procedure Append (To_List : in out List_Mal_Type; Op : Mal_Handle) is
773 -- If the list is null just insert the new element
774 -- else use the last_elem pointer to insert it and then update it.
775 if Is_Null (To_List.The_List) then
776 To_List.The_List := New_Node_Mal_Type (Op);
777 To_List.Last_Elem := To_List.The_List;
779 Deref_Node (To_List.Last_Elem).Next := New_Node_Mal_Type (Op);
780 To_List.Last_Elem := Deref_Node (To_List.Last_Elem).Next;
785 -- Duplicate copies the list (logically). This is to allow concatenation,
786 -- The result is always a List_List.
787 function Duplicate (The_List : List_Mal_Type) return Mal_Handle is
788 Res, Old_List, First_New_Node, New_List : Mal_Handle;
792 Res := New_List_Mal_Type (List_List);
794 Old_List := The_List.The_List;
796 if Is_Null (Old_List) then
800 First_New_Node := New_Node_Mal_Type (Deref_Node (Old_List).Data);
801 New_List := First_New_Node;
802 Old_List := Deref_Node (Old_List).Next;
804 while not Is_Null (Old_List) loop
806 Deref_Node (New_List).Next := New_Node_Mal_Type (Deref_Node (Old_List).Data);
807 New_List := Deref_Node (New_List).Next;
808 Old_List := Deref_Node (Old_List).Next;
812 LP := Deref_List (Res);
813 LP.The_List := First_New_Node;
814 LP.Last_Elem := New_List;
821 function Nth (L : List_Mal_Type; N : Natural) return Mal_Handle is
832 while not Is_Null (Next) loop
835 return Deref_Node (Next).Data;
840 Next := Deref_Node (Next).Next;
844 raise Runtime_Exception with "Nth
(list
): Index
out of range";
849 function Concat (Rest_Handle : List_Mal_Type)
850 return Types.Mal_Handle is
851 Rest_List : Types.List_Mal_Type;
852 List : Types.List_Class_Ptr;
853 Res_List_Handle, Dup_List : Mal_Handle;
854 Last_Node_P : Mal_Handle := Smart_Pointers.Null_Smart_Pointer;
856 Rest_List := Rest_Handle;
858 -- Set the result to the null list.
859 Res_List_Handle := New_List_Mal_Type (List_List);
861 while not Is_Null (Rest_List) loop
863 -- Find the next list in the list...
864 List := Deref_List_Class (Car (Rest_List));
866 -- Duplicate nodes to its contents.
867 Dup_List := Duplicate (List.all);
869 -- If we haven't inserted a list yet, then take the duplicated list whole.
870 if Is_Null (Last_Node_P) then
871 Res_List_Handle := Dup_List;
873 -- Note that the first inserted list may have been the null list
874 -- and so may the newly duplicated one...
875 Deref_Node (Last_Node_P).Next := Deref_List (Dup_List).The_List;
876 if Is_Null (Deref_List (Res_List_Handle).The_List) then
877 Deref_List (Res_list_Handle).The_List :=
878 Deref_List (Dup_List).The_List;
880 if not Is_Null (Deref_List (Dup_List).Last_Elem) then
881 Deref_List (Res_List_Handle).Last_Elem :=
882 Deref_List (Dup_List).Last_Elem;
886 Last_Node_P := Deref_List (Dup_List).Last_Elem;
888 Rest_List := Deref_List (Cdr (Rest_List)).all;
892 return Res_List_Handle;
897 procedure Add_Defs (Defs : List_Mal_Type; Env : Envs.Env_Handle) is
898 D, L : List_Mal_Type;
901 while not Is_Null (D) loop
902 L := Deref_List (Cdr (D)).all;
905 Deref_Sym (Car (D)).Get_Sym,
906 Eval_Callback.Eval.all (Car (L), Env));
907 D := Deref_List (Cdr(L)).all;
912 function Deref_List (SP : Mal_Handle) return List_Ptr is
914 return List_Ptr (Deref (SP));
918 function Deref_List_Class (SP : Mal_Handle) return List_Class_Ptr is
920 return List_Class_Ptr (Deref (SP));
921 end Deref_List_Class;
924 overriding function To_Str
925 (T : List_Mal_Type; Print_Readably : Boolean := True)
928 if Is_Null (T.The_List) then
929 return Opening (T.List_Type) &
930 Closing (T.List_Type);
932 return Opening (T.List_Type) &
933 To_String (Deref (T.The_List).all, Print_Readably) &
934 Closing (T.List_Type);
939 function Pr_Str (T : List_Mal_Type; Print_Readably : Boolean := True)
942 if Is_Null (T.The_List) then
945 return To_String (Deref_Node (T.The_List).all, Print_Readably);
950 function Cat_Str (T : List_Mal_Type; Print_Readably : Boolean := True)
953 if Is_Null (T.The_List) then
956 return Cat_Str (Deref_Node (T.The_List).all, Print_Readably);
961 function Opening (LT : List_Types) return Character is
976 function Closing (LT : List_Types) return Character is
991 function New_Lambda_Mal_Type
992 (Params : Mal_Handle; Expr : Mal_Handle; Env : Envs.Env_Handle)
995 return Smart_Pointers.New_Ptr
996 (new Lambda_Mal_Type'
1001 Is_Macro => False));
1002 end New_Lambda_Mal_Type;
1004 overriding function Sym_Type (T : Lambda_Mal_Type) return Sym_Types is
1009 function Get_Env (L : Lambda_Mal_Type) return Envs.Env_Handle is
1014 procedure Set_Env (L : in out Lambda_Mal_Type; Env : Envs.Env_Handle) is
1019 function Get_Params (L : Lambda_Mal_Type) return Mal_Handle is
1021 if Deref (L.Params).Sym_Type = List and then
1022 Deref_List (L.Params).Get_List_Type = Vector_List then
1023 -- Its a vector and we need a list...
1024 return Deref_List_Class (L.Params).Duplicate;
1030 function Get_Expr (L : Lambda_Mal_Type) return Mal_Handle is
1035 function Get_Is_Macro (L : Lambda_Mal_Type) return Boolean is
1040 procedure Set_Is_Macro (L : in out Lambda_Mal_Type; B : Boolean) is
1047 (L : Lambda_Mal_Type;
1048 Param_List : Mal_Handle)
1049 return Mal_Handle is
1051 E : Envs.Env_Handle;
1052 Param_Names : List_Mal_Type;
1057 E := Envs.New_Env (L.Env);
1059 Param_Names := Deref_List (L.Get_Params).all;
1061 if Envs.Bind (E, Param_Names, Deref_List (Param_List).all) then
1063 Res := Eval_Callback.Eval.all (L.Get_Expr, E);
1067 raise Runtime_Exception with "Bind failed
in Apply
";
1076 function Get_Macro (T : Mal_Handle; Env : Envs.Env_Handle) return Lambda_Ptr is
1078 First_Elem, Func : Mal_Handle;
1081 if Deref (T).Sym_Type /= List then
1085 L := Deref_List (T).all;
1091 First_Elem := Car (L);
1093 if Deref (First_Elem).Sym_Type /= Sym then
1097 Func := Envs.Get (Env, Deref_Sym (First_Elem).Get_Sym);
1099 if Deref (Func).Sym_Type /= Lambda then
1103 return Deref_Lambda (Func);
1106 when Envs.Not_Found => return null;
1110 overriding function To_Str
1111 (T : Lambda_Mal_Type; Print_Readably : Boolean := True)
1112 return Mal_String is
1114 -- return "(lambda
" & Ada.Strings.Unbounded.To_String (T.Rep) & ")";
1115 return "#
<function>";
1118 function Deref_Lambda (SP : Mal_Handle) return Lambda_Ptr is
1120 return Lambda_Ptr (Deref (SP));
1124 function Arith_Op (A, B : Mal_Handle) return Mal_Handle is
1126 A_Sym_Type : Sym_Types;
1127 B_Sym_Type : Sym_Types;
1132 -- both null, gotta be zero.
1133 return New_Int_Mal_Type (0);
1134 else -- A is null but B is not.
1135 return Arith_Op (New_Int_Mal_Type (0), B);
1137 elsif Is_Null (B) then
1138 -- A is not null but B is.
1139 return Arith_Op (A, New_Int_Mal_Type (0));
1142 -- else both A and B and not null.:wq
1143 A_Sym_Type := Deref (A).Sym_Type;
1144 B_Sym_Type := Deref (B).Sym_Type;
1145 if A_Sym_Type = Int and B_Sym_Type = Int then
1146 return New_Int_Mal_Type
1147 (Int_Op (Deref_Int (A).Get_Int_Val, Deref_Int (B).Get_Int_Val));
1148 elsif A_Sym_Type = Int and B_Sym_Type = Floating then
1149 return New_Float_Mal_Type
1150 (Float_Op (Mal_Float (Deref_Int (A).Get_Int_Val),
1151 Deref_Float (B).Get_Float_Val));
1152 elsif A_Sym_Type = Floating and B_Sym_Type = Int then
1153 return New_Float_Mal_Type
1154 (Float_Op (Deref_Float (A).Get_Float_Val,
1155 Mal_Float (Deref_Float (B).Get_Float_Val)));
1156 elsif A_Sym_Type = Floating and B_Sym_Type = Floating then
1157 return New_Float_Mal_Type
1158 (Float_Op (Deref_Float (A).Get_Float_Val,
1159 Deref_Float (B).Get_Float_Val));
1161 if A_Sym_Type = Error then
1163 elsif B_Sym_Type = Error then
1166 return New_Error_Mal_Type ("Invalid operands
");
1172 function Rel_Op (A, B : Mal_Handle) return Mal_Handle is
1174 A_Sym_Type : Sym_Types := Deref (A).Sym_Type;
1175 B_Sym_Type : Sym_Types := Deref (B).Sym_Type;
1177 if A_Sym_Type = Int and B_Sym_Type = Int then
1178 return New_Bool_Mal_Type
1179 (Int_Rel_Op (Deref_Int (A).Get_Int_Val, Deref_Int (B).Get_Int_Val));
1180 elsif A_Sym_Type = Int and B_Sym_Type = Floating then
1181 return New_Bool_Mal_Type
1182 (Float_Rel_Op (Mal_Float (Deref_Int (A).Get_Int_Val),
1183 Deref_Float (B).Get_Float_Val));
1184 elsif A_Sym_Type = Floating and B_Sym_Type = Int then
1185 return New_Bool_Mal_Type
1186 (Float_Rel_Op (Deref_Float (A).Get_Float_Val,
1187 Mal_Float (Deref_Float (B).Get_Float_Val)));
1189 return New_Bool_Mal_Type
1190 (Float_Rel_Op (Deref_Float (A).Get_Float_Val,
1191 Deref_Float (B).Get_Float_Val));