5 package body Types
.Sequences
is
7 function "=" (Left
, Right
: in Instance
) return Boolean is
8 -- Should become Left.all.Data = Right.all.Data when
9 -- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89178 is fixed.
11 return Left
.Length
= Right
.Length
13 (for all I
in 1 .. Left
.Data
'Length => Left
.Data
(I
) = Right
.Data
(I
));
16 function Concat
(Args
: in T_Array
) return T
is
18 First
: Positive := 1;
21 Err
.Check
((for all A
of Args
=> A
.Kind
in Kind_Sequence
),
22 "expected sequences");
24 Sum
:= Sum
+ Arg
.Sequence
.all.Data
'Length;
27 Ref
: constant Sequence_Ptr
:= Constructor
(Sum
);
30 Last
:= First
- 1 + Arg
.Sequence
.all.Data
'Last;
31 Ref
.all.Data
(First
.. Last
) := Arg
.Sequence
.all.Data
;
34 return (Kind_List
, Ref
);
38 function Conj
(Args
: in T_Array
) return T
is
40 Err
.Check
(0 < Args
'Length, "expected at least 1 parameter");
41 case Args
(Args
'First).Kind
is
44 Data
: T_Array
renames Args
(Args
'First).Sequence
.all.Data
;
45 Last
: constant Natural := Args
'Length - 1 + Data
'Length;
46 -- Avoid exceptions until Ref is controlled.
47 Ref
: constant Sequence_Ptr
:= Constructor
(Last
);
49 if Args
(Args
'First).Kind
= Kind_List
then
50 for I
in 1 .. Args
'Length - 1 loop
51 Ref
.all.Data
(I
) := Args
(Args
'Last - I
+ 1);
53 Ref
.all.Data
(Args
'Length .. Last
) := Data
;
54 return (Kind_List
, Ref
);
56 Ref
.all.Data
:= Data
& Args
(Args
'First + 1 .. Args
'Last);
57 return (Kind_Vector
, Ref
);
61 Err
.Raise_With
("parameter 1 must be a sequence");
65 function Cons
(Args
: in T_Array
) return T
is
67 Err
.Check
(Args
'Length = 2
68 and then Args
(Args
'Last).Kind
in Kind_Sequence
,
69 "expected a value then a sequence");
71 Head
: T
renames Args
(Args
'First);
72 Tail
: T_Array
renames Args
(Args
'Last).Sequence
.all.Data
;
73 Ref
: constant Sequence_Ptr
:= Constructor
(1 + Tail
'Length);
75 Ref
.all.Data
:= Head
& Tail
;
76 return (Kind_List
, Ref
);
80 function Constructor
(Length
: in Natural) return Sequence_Ptr
is
81 Ref
: constant Sequence_Ptr
:= new Instance
(Length
);
83 Garbage_Collected
.Register
(Garbage_Collected
.Pointer
(Ref
));
87 function Count
(Args
: in T_Array
) return T
is
89 Err
.Check
(Args
'Length = 1, "expected 1 parameter");
90 case Args
(Args
'First).Kind
is
92 return (Kind_Number
, 0);
94 return (Kind_Number
, Args
(Args
'First).Sequence
.all.Data
'Length);
96 Err
.Raise_With
("parameter must be nil or a sequence");
100 function First
(Args
: in T_Array
) return T
is
102 Err
.Check
(Args
'Length = 1, "expected 1 parameter");
103 case Args
(Args
'First).Kind
is
106 when Kind_Sequence
=>
108 Data
: T_Array
renames Args
(Args
'First).Sequence
.all.Data
;
110 if Data
'Length = 0 then
113 return Data
(Data
'First);
117 Err
.Raise_With
("parameter must be nil or a sequence");
121 function Is_Empty
(Args
: in T_Array
) return T
is
123 Err
.Check
(Args
'Length = 1
124 and then Args
(Args
'First).Kind
in Kind_Sequence
,
125 "expected a sequence");
126 return (Kind_Boolean
, Args
(Args
'First).Sequence
.all.Data
'Length = 0);
129 procedure Keep_References
(Object
: in out Instance
) is
132 for M
of Object
.Data
loop
137 function List
(Args
: in T_Array
) return T
139 Ref
: constant Sequence_Ptr
:= Constructor
(Args
'Length);
141 Ref
.all.Data
:= Args
;
142 return (Kind_List
, Ref
);
145 function Map
(Args
: in T_Array
) return T
is
147 Err
.Check
(Args
'Length = 2
148 and then Args
(Args
'Last).Kind
in Kind_Sequence
,
149 "expected a function then a sequence");
151 F
: T
renames Args
(Args
'First);
152 Src
: T_Array
renames Args
(Args
'Last).Sequence
.all.Data
;
153 Ref
: constant Sequence_Ptr
:= Constructor
(Src
'Length);
157 for I
in Src
'Range loop
158 Ref
.all.Data
(I
) := F
.Builtin
.all (Src
(I
.. I
));
160 when Kind_Builtin_With_Meta
=>
161 for I
in Src
'Range loop
163 := F
.Builtin_With_Meta
.all.Builtin
.all (Src
(I
.. I
));
166 for I
in Src
'Range loop
167 Ref
.all.Data
(I
) := F
.Fn
.all.Apply
(Src
(I
.. I
));
170 Err
.Raise_With
("parameter 1 must be a function");
172 return (Kind_List
, Ref
);
176 function Nth
(Args
: in T_Array
) return T
is
178 Err
.Check
(Args
'Length = 2
179 and then Args
(Args
'First).Kind
in Kind_Sequence
180 and then Args
(Args
'Last).Kind
= Kind_Number
,
181 "expected a sequence then a number");
183 L
: T_Array
renames Args
(Args
'First).Sequence
.all.Data
;
184 I
: constant Integer := Args
(Args
'Last).Number
+ 1;
186 Err
.Check
(I
in L
'Range, "index out of bounds");
191 function Rest
(Args
: in T_Array
) return T
is
193 Err
.Check
(Args
'Length = 1, "expected 1 parameter");
194 case Args
(Args
'First).Kind
is
196 return (Kind_List
, Constructor
(0));
197 when Kind_Sequence
=>
199 A1
: T_Array
renames Args
(Args
'First).Sequence
.all.Data
;
200 Ref
: constant Sequence_Ptr
201 := Constructor
(Integer'Max (0, A1
'Length - 1));
203 Ref
.all.Data
:= A1
(A1
'First + 1 .. A1
'Last);
204 return (Kind_List
, Ref
);
207 Err
.Raise_With
("parameter must be nil or a sequence");
211 function Vector
(Args
: in T_Array
) return T
213 Ref
: constant Sequence_Ptr
:= Constructor
(Args
'Length);
215 Ref
.all.Data
:= Args
;
216 return (Kind_Vector
, Ref
);