Skip to content

Commit f07bbd0

Browse files
author
livecodeali
committed
[[ Bug 16434 ]] Make 7.1 array ops match those of 6.7
1 parent fc49076 commit f07bbd0

2 files changed

Lines changed: 57 additions & 46 deletions

File tree

engine/src/exec-array.cpp

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -562,18 +562,6 @@ void MCArraysExecSplitAsSet(MCExecContext& ctxt, MCStringRef p_string, MCStringR
562562

563563
////////////////////////////////////////////////////////////////////////////////
564564

565-
//
566-
// Semantics of 'union tLeft with tRight [recursively]'
567-
//
568-
// repeat for each key tKey in tRight
569-
// if tKey is not among the keys of tLeft then
570-
// put tRight[tKey] into tLeft[tKey]
571-
// else if tRecursive then
572-
// union tLeft[tKey] with tRight[tKey] recursively
573-
// end if
574-
// end repeat
575-
//
576-
577565
void MCArraysDoUnion(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, bool p_recursive, MCValueRef& r_result)
578566
{
579567
if (!MCValueIsArray(p_src))
@@ -636,31 +624,25 @@ void MCArraysDoUnion(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, bo
636624
r_result = MCValueRetain(*t_result);
637625
}
638626

639-
//
640-
// Semantics of 'intersect tLeft with tRight [recursively]'
641-
//
642-
// repeat for each key tKey in tLeft
643-
// if tKey is not among the keys of tRight then
644-
// delete variable tLeft[tKey]
645-
// else if tRecursive then
646-
// intersect tLeft[tKey] with tRight[tKey] recursively
647-
// end if
648-
// end repeat
649-
//
650-
651-
void MCArraysDoIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, bool p_recursive, MCValueRef& r_result)
627+
void MCArraysDoIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, bool p_recursive, bool p_top_level, MCValueRef& r_result)
652628
{
653-
if (!MCValueIsArray(p_dst))
629+
// Existing 6.7 behavior, is to clobber the left on the top level if either side converts to empty array
630+
if (p_top_level)
654631
{
655-
r_result = MCValueRetain(p_dst);
656-
return;
657-
632+
if (!MCValueIsArray(p_dst) || !MCValueIsArray(p_src))
633+
{
634+
r_result = MCValueRetain(kMCEmptyString);
635+
return;
636+
}
658637
}
659-
660-
if (!MCValueIsArray(p_src))
638+
// And preserve the left in the recursive case if either side converts to empty array
639+
else
661640
{
662-
r_result = MCValueRetain(kMCEmptyString);
663-
return;
641+
if (!MCValueIsArray(p_dst) || !MCValueIsArray(p_src))
642+
{
643+
r_result = MCValueRetain(p_dst);
644+
return;
645+
}
664646
}
665647

666648
MCArrayRef t_dst_array;
@@ -669,6 +651,25 @@ void MCArraysDoIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src
669651
MCArrayRef t_src_array;
670652
t_src_array = (MCArrayRef)p_src;
671653

654+
// Existing 6.7 behavior, is to clobber the left on the top level if either side converts to empty array
655+
if (p_top_level)
656+
{
657+
if (MCArrayIsEmpty(t_dst_array) || MCArrayIsEmpty(t_src_array))
658+
{
659+
r_result = MCValueRetain(kMCEmptyString);
660+
return;
661+
}
662+
}
663+
// And preserve the left in the recursive case if either side converts to empty array
664+
else
665+
{
666+
if (MCArrayIsEmpty(t_dst_array) || MCArrayIsEmpty(t_src_array))
667+
{
668+
r_result = MCValueRetain(p_dst);
669+
return;
670+
}
671+
}
672+
672673
MCAutoArrayRef t_result;
673674
if (!MCArrayMutableCopy(t_dst_array, &t_result))
674675
return;
@@ -680,14 +681,14 @@ void MCArraysDoIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src
680681
t_iterator = 0;
681682

682683
while(MCArrayIterate(t_dst_array, t_iterator, t_key, t_dst_value))
683-
{
684+
{
684685
bool t_key_exists;
685686
t_key_exists = MCArrayFetchValue(t_src_array, ctxt . GetCaseSensitive(), t_key, t_src_value);
686687

687688
if (t_key_exists && !p_recursive)
688689
continue;
689690

690-
if (!t_key_exists)
691+
if (!t_key_exists)
691692
{
692693
if (!MCArrayRemoveValue(*t_result, ctxt . GetCaseSensitive(), t_key))
693694
{
@@ -698,15 +699,15 @@ void MCArraysDoIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src
698699
else if (p_recursive)
699700
{
700701
MCAutoValueRef t_recursive_result;
701-
MCArraysDoIntersect(ctxt, t_dst_value, t_src_value, true, &t_recursive_result);
702+
MCArraysDoIntersect(ctxt, t_dst_value, t_src_value, true, false, &t_recursive_result);
702703

703704
if (ctxt . HasError())
704705
return;
705706

706707
if (!MCArrayStoreValue(*t_result, ctxt . GetCaseSensitive(), t_key, *t_recursive_result))
707708
return;
708709
}
709-
}
710+
}
710711

711712
r_result = MCValueRetain(*t_result);
712713
}
@@ -718,7 +719,7 @@ void MCArraysExecUnion(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src,
718719

719720
void MCArraysExecIntersect(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, MCValueRef& r_result)
720721
{
721-
MCArraysDoIntersect(ctxt, p_dst, p_src, false, r_result);
722+
MCArraysDoIntersect(ctxt, p_dst, p_src, false, true, r_result);
722723
}
723724

724725
void MCArraysExecUnionRecursive(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, MCValueRef& r_result)
@@ -728,7 +729,7 @@ void MCArraysExecUnionRecursive(MCExecContext& ctxt, MCValueRef p_dst, MCValueRe
728729

729730
void MCArraysExecIntersectRecursive(MCExecContext& ctxt, MCValueRef p_dst, MCValueRef p_src, MCValueRef& r_result)
730731
{
731-
MCArraysDoIntersect(ctxt, p_dst, p_src, true, r_result);
732+
MCArraysDoIntersect(ctxt, p_dst, p_src, true, true, r_result);
732733
}
733734

734735
////////////////////////////////////////////////////////////////////////////////

tests/lcs/core/array/setoperations.livecodescript

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,22 @@ end TestNestedArrayRecursiveUnion
112112
/*
113113
Semantics of array intersect:
114114
115-
function ArrayIntersect(pLeft, pRight, pRecursive)
115+
function ArrayIntersect(pLeft, pRight, pRecursive, pTopLevel)
116+
if pTopLevel then
117+
if the keys of pRight is empty or the keys of pLeft is empty then
118+
return empty
119+
end if
120+
else
121+
if the keys of pRight is empty or the keys of pLeft is empty then
122+
return pLeft
123+
end if
124+
end if
125+
116126
repeat for each key tKey in pLeft
117127
if tKey is not among the keys of pRight then
118128
delete variable pLeft[tKey]
119129
else if pRecursive then
120-
put ArrayIntersect(pLeft[tKey], pRight[tKey], true) into pLeft[tKey]
130+
put ArrayIntersect(pLeft[tKey], pRight[tKey], true, false) into pLeft[tKey]
121131
end if
122132
end repeat
123133
@@ -130,13 +140,13 @@ on TestArrayIntersect
130140
local tString1
131141
put "a" into tString1
132142
intersect tString1 with "b"
133-
TestAssert "intersect: left non-array, right non-array", tString1 is "a"
143+
TestAssert "intersect: left non-array, right non-array", tString1 is empty
134144

135145
local tString2, tFixedArray
136146
put "a" into tString2
137147
put "b" into tFixedArray[1]
138148
intersect tString2 with tFixedArray
139-
TestAssert "intersect: left non-array, right array", tString2 is "a"
149+
TestAssert "intersect: left non-array, right array", tString2 is empty
140150

141151
local tArray1
142152
put "a" into tArray1[1]
@@ -188,15 +198,15 @@ on TestNestedArrayRecursiveIntersect
188198
local tLeftArray2, tRightArray2
189199
put "a" into tLeftArray2[1]
190200
put "b" into tRightArray2[1][1]
191-
201+
192202
intersect tLeftArray2 with tRightArray2 recursively
193203
TestAssert "recursive intersect: left value non-array, right value array", tLeftArray2[1] is "a"
194204

195205
local tLeftArray3, tRightArray3
196206
put "a" into tLeftArray3[1][1]
197207
put "b" into tRightArray3[1]
198208
intersect tLeftArray3 with tRightArray3 recursively
199-
TestAssert "recursive intersect: left value array, right value non-array", tLeftArray3[1] is empty
209+
TestAssert "recursive intersect: left value array, right value non-array", tLeftArray3[1][1] is "a"
200210

201211
local tLeftArray4, tRightArray4
202212
put "a" into tLeftArray4[1][1]
@@ -208,4 +218,4 @@ on TestNestedArrayRecursiveIntersect
208218
TestAssert "recursive intersect: left value array, right value array, key present in right not left", tLeftArray4[1][3] is empty
209219
TestAssert "recursive intersect: left value array, right value array, key present in left and right", tLeftArray4[1][2] is "b"
210220

211-
end TestNestedArrayRecursiveIntersect
221+
end TestNestedArrayRecursiveIntersect

0 commit comments

Comments
 (0)