Test that macros use closures
[jackhill/mal.git] / ada.2 / types-atoms.adb
CommitLineData
00c3a3c3 1with Err;
5a07bb53
NB
2with Types.Builtins;
3with Types.Fns;
daffc668 4
5a07bb53 5package body Types.Atoms is
daffc668 6
8185fe14 7 function Atom (Args : in T_Array) return T is
00c3a3c3
NB
8 begin
9 Err.Check (Args'Length = 1, "expected 1 parameter");
8185fe14
NB
10 declare
11 Ref : constant Atom_Ptr := new Instance;
12 begin
13 Garbage_Collected.Register (Garbage_Collected.Pointer (Ref));
14 Ref.all.Data := Args (Args'First);
15 return (Kind_Atom, Ref);
16 end;
00c3a3c3
NB
17 end Atom;
18
8185fe14 19 function Deref (Args : in T_Array) return T is
00c3a3c3 20 begin
8185fe14
NB
21 Err.Check (Args'Length = 1 and then Args (Args'First).Kind = Kind_Atom,
22 "expected an atom");
5a07bb53 23 return Args (Args'First).Atom.all.Data;
00c3a3c3 24 end Deref;
11932a6c 25
8185fe14 26 function Deref (Item : in Instance) return T
5a07bb53 27 is (Item.Data);
daffc668 28
5a07bb53 29 procedure Keep_References (Object : in out Instance) is
daffc668 30 begin
8185fe14 31 Keep (Object.Data);
5a07bb53 32 end Keep_References;
daffc668 33
8185fe14 34 function Reset (Args : in T_Array) return T is
daffc668 35 begin
8185fe14
NB
36 Err.Check (Args'Length = 2 and then Args (Args'First).Kind = Kind_Atom,
37 "expected an atom then a value");
5a07bb53 38 Args (Args'First).Atom.all.Data := Args (Args'Last);
11932a6c 39 return Args (Args'Last);
daffc668
NB
40 end Reset;
41
8185fe14 42 function Swap (Args : in T_Array) return T is
11932a6c 43 begin
8185fe14
NB
44 Err.Check (2 <= Args'Length and then Args (Args'First).Kind = Kind_Atom,
45 "expected an atom, optional arguments then a function");
11932a6c 46 declare
8185fe14
NB
47 X : T renames Args (Args'First).Atom.all.Data;
48 F : T renames Args (Args'First + 1);
49 A : constant T_Array := X & Args (Args'First + 2 .. Args'Last);
11932a6c
NB
50 begin
51 case F.Kind is
52 when Kind_Builtin =>
53 X := F.Builtin.all (A);
54 when Kind_Builtin_With_Meta =>
5a07bb53 55 X := F.Builtin_With_Meta.all.Builtin.all (A);
00c3a3c3 56 when Kind_Fn =>
5a07bb53 57 X := F.Fn.all.Apply (A);
11932a6c 58 when others =>
00c3a3c3 59 Err.Raise_With ("parameter 2 must be a function");
11932a6c
NB
60 end case;
61 return X;
62 end;
63 end Swap;
64
daffc668 65end Types.Atoms;