Skip to content

Commit ee5367b

Browse files
committed
[[ StdMlc ]] Add iterators for array elements and keys
1 parent 0c06f39 commit ee5367b

File tree

4 files changed

+213
-7
lines changed

4 files changed

+213
-7
lines changed

libscript/src/array.mlc

Lines changed: 135 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,35 @@ public foreign handler MCArrayStoreElementOfCaseless(in Value as any, inout Targ
1515

1616
public foreign handler MCArrayEvalEmpty(out Value as array) as undefined binds to "<builtin>"
1717

18+
public foreign handler MCArrayRepeatForEachElement(inout Iterator as optional pointer, out Iterand as any, in Container as array) as bool binds to "<builtin>"
19+
public foreign handler MCArrayRepeatForEachKey(inout Iterator as optional pointer, out Iterand as string, in Container as array) as bool binds to "<builtin>"
20+
1821
--
1922

2023
/*
2124
Summary: Returns the keys of an array.
2225
Target: An expression which evaluates to an array.
2326
output: A list whose elements are the keys of <Target>.
24-
Note that the list is not ordered in any way.
27+
28+
Example:
29+
variable tArray as array
30+
put the empty array into tArray
31+
put "value1" into tArray["key1"]
32+
put "value2" into tArray["key2"]
33+
put "value3" into tArray["key3"]
34+
35+
variable tKeys as list
36+
put the keys of tArray into tKeys
37+
sort tKeys in ascending order
38+
39+
variable tKeysString as string
40+
combine tKeys with "," into tKeysString
41+
// tKeysString is "key1,key2,key3"
42+
43+
References:com.livecode.sort
44+
45+
Description:
46+
>*Note:* The resulting list is not necessarily ordered in any way. Use the <com.livecode.sort> library to sort the keys.
2547
*/
2648

2749
syntax KeysOf is prefix operator with precedence 2
@@ -34,7 +56,24 @@ end syntax
3456
Summary: Returns the elements of an array.
3557
Target: An expression which evaluates to an array.
3658
output: A list whose elements are the elements of <Target>.
37-
Note that the list is not ordered in any way.
59+
60+
Example:
61+
variable tArray as array
62+
put the empty array into tArray
63+
put 1 into tArray["key1"]
64+
put 2 into tArray["key2"]
65+
put 3 into tArray["key3"]
66+
67+
variable tElements as list
68+
put the elements of tArray into tElements
69+
sort tElements in ascending numeric order
70+
71+
// tElements is [1, 2, 3]
72+
73+
References:com.livecode.sort
74+
75+
Description:
76+
>*Note:* The resulting list is not necessarily ordered in any way. Use the <com.livecode.sort> library to sort the elements.
3877
*/
3978

4079
syntax ElementsOf is prefix operator with precedence 2
@@ -48,6 +87,16 @@ end syntax
4887
/*
4988
Summary: Returns the number of elements in <Target>
5089
Target: An expression which evaluates to an array.
90+
91+
Example:
92+
variable tArray as array
93+
put the empty array into tArray
94+
put 1 into tArray["key1"]
95+
put 2 into tArray["key2"]
96+
put 3 into tArray["key3"]
97+
98+
variable tVar as integer
99+
put the number of elements in tArray into tVar -- tVar contains 3
51100
*/
52101

53102
syntax CountElementsOf is prefix operator with precedence 1
@@ -94,11 +143,19 @@ end syntax
94143
/*
95144

96145
Summary: Designates the element with key <Key> in <Target>.
97-
Key: An expression which evaluates to an integer, string, or list of integers.
146+
Index: An expression which evaluates to a string.
98147
Target: An expression which evaluates to an array.
99-
output: Either locates the element container with the given key for use as the target
100-
container of another operation, or evaluates the element with the given key
101-
as the source of another operation.
148+
149+
Example:
150+
variable tArray as array
151+
put the empty array into tArray
152+
put "value" into tArray["key"]
153+
154+
variable tVar as string
155+
put tArray["key"] into tVar -- tVar contains "value"
156+
157+
Description:
158+
Either locates the element container with the given key for use as the target container of another operation, or evaluates the element with the given key as the source of another operation.
102159
*/
103160

104161
syntax SingletonElementOf is postfix operator with precedence 1
@@ -110,10 +167,82 @@ end syntax
110167

111168
--
112169

170+
/*
171+
172+
Summary: Designates the array with zero elements
173+
174+
Example:
175+
variable tVar as array
176+
variable tCount as int
177+
put the empty array into tVar
178+
put the number of elements in tVar into tCount -- tCount is 0
179+
180+
Description:
181+
Use ```the empty array``` to initialise an array variable.
182+
183+
*/
184+
113185
syntax EmptyArray is expression
114186
"the" "empty" "array"
115187
begin
116188
MCArrayEvalEmpty(output)
117189
end syntax
118190

191+
--
192+
193+
/*
194+
Summary: Repeat over the elements of an array.
195+
Iterand: An expression of the form 'tVar in tArray'
196+
197+
Example:
198+
variable tArray as array
199+
put the empty array into tArray
200+
put 1 into tArray["key1"]
201+
put 2 into tArray["key2"]
202+
put 3 into tArray["key3"]
203+
204+
variable tSum as number
205+
put 0 into tSum
206+
repeat for each element tElement in tArray
207+
add tElement to tSum
208+
end repeat
209+
210+
// tSum is 6
211+
*/
212+
213+
syntax RepeatForEachElement is iterator
214+
"element" <Iterand: Expression>
215+
begin
216+
MCArrayRepeatForEachElement(iterator, Iterand, container)
217+
end syntax
218+
219+
/*
220+
Summary: Repeat over the keys of an array.
221+
Iterand: An expression of the form 'tVar in tArray'
222+
223+
Example:
224+
variable tArray as array
225+
put the empty array into tArray
226+
put 1 into tArray["abc"]
227+
put 2 into tArray["def"]
228+
put 3 into tArray["ghi"]
229+
230+
variable tString as string
231+
put "" into tString
232+
233+
variable tKey as string
234+
repeat for each key tKey in tArray
235+
put tKey after tString
236+
end repeat
237+
238+
variable tBool as bool
239+
put tString contains "abc" into tBool -- tBool is true
240+
*/
241+
242+
syntax RepeatForEachKey is iterator
243+
"key" <Iterand: Expression>
244+
begin
245+
MCArrayRepeatForEachKey(iterator, Iterand, container)
246+
end syntax
247+
119248
end module

libscript/src/list.mlc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,6 @@ Use ```the empty list``` to initialise a list variable.
553553

554554
*/
555555

556-
557556
syntax EmptyList is expression
558557
"the" "empty" "list"
559558
begin

libscript/src/module-array.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,54 @@ extern "C" MC_DLLEXPORT void MCArrayStoreElementOfCaseless(MCValueRef p_value, M
137137
extern "C" MC_DLLEXPORT void MCArrayEvalEmpty(MCArrayRef& r_output)
138138
{
139139
r_output = MCValueRetain(kMCEmptyArray);
140+
}
141+
142+
extern "C" bool MCArrayRepeatForEachElement(void*& x_iterator, MCValueRef& r_iterand, MCArrayRef p_array)
143+
{
144+
MCValueRef t_value;
145+
// If this is a numerical array, do it in order
146+
/* if (MCArrayIsSequence(p_array))
147+
{
148+
uindex_t t_offset;
149+
t_offset = (uindex_t)x_iterator;
150+
151+
if (t_offset == MCArrayGetCount(p_array))
152+
return false;
153+
154+
if (!MCArrayFetchValueAtIndex(p_array, t_offset, t_value))
155+
return false;
156+
}
157+
else */
158+
{
159+
MCNameRef t_key;
160+
161+
uintptr_t t_ptr;
162+
t_ptr = (uintptr_t)x_iterator;
163+
164+
if (!MCArrayIterate(p_array, t_ptr, t_key, t_value))
165+
return false;
166+
167+
x_iterator = (void *)(t_ptr);
168+
}
169+
170+
r_iterand = MCValueRetain(t_value);
171+
return true;
172+
}
173+
174+
extern "C" bool MCArrayRepeatForEachKey(void*& x_iterator, MCStringRef& r_iterand, MCArrayRef p_array)
175+
{
176+
MCNameRef t_key;
177+
MCValueRef t_value;
178+
179+
uintptr_t t_offset;
180+
t_offset = (uintptr_t)x_iterator;
181+
182+
if (!MCArrayIterate(p_array, t_offset, t_key, t_value))
183+
return false;
184+
185+
r_iterand = MCValueRetain(MCNameGetString(t_key));
186+
187+
x_iterator = (void *)(t_offset);
188+
189+
return true;
140190
}

toolchain/lc-compile/test.mlc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,34 @@ public handler testArray(inout xResults as list)
281281

282282
testLog("Array", "ElementOf", tArray["key1"] is "value1", xResults)
283283

284+
variable tNewArray as array
285+
put the empty array into tNewArray
286+
put 1 into tNewArray["abc"]
287+
put 2 into tNewArray["def"]
288+
put 3 into tNewArray["ghi"]
289+
290+
variable tString as string
291+
put "" into tString
292+
293+
variable tKey as string
294+
repeat for each key tKey in tNewArray
295+
put tKey after tString
296+
end repeat
297+
298+
testLog("Array", "RepeatForEachKey1", tString contains "abc", xResults)
299+
testLog("Array", "RepeatForEachKey1", tString contains "def", xResults)
300+
testLog("Array", "RepeatForEachKey1", tString contains "ghi", xResults)
301+
302+
variable tSum as number
303+
put 0 into tSum
304+
305+
variable tElement
306+
repeat for each element tElement in tNewArray
307+
add tElement to tSum
308+
end repeat
309+
310+
testLog("Array", "RepeatForEachElement", tSum is 6, xResults)
311+
284312
end handler
285313

286314
public handler testBitwise(inout xResults as list)

0 commit comments

Comments
 (0)