Skip to content

Commit 419ad07

Browse files
author
runrevali
committed
[[ LC Builder ]] Add non-homogeneous sort errors and implement generic sort
1 parent 197c38b commit 419ad07

File tree

5 files changed

+247
-159
lines changed

5 files changed

+247
-159
lines changed

libfoundation/include/foundation.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2797,8 +2797,11 @@ MC_DLLEXPORT bool MCProperListFirstIndexOfList(MCProperListRef list, MCProperLis
27972797

27982798
MC_DLLEXPORT bool MCProperListIsEqualTo(MCProperListRef list, MCProperListRef p_other);
27992799

2800-
bool MCProperListBeginsWithList(MCProperListRef list, MCProperListRef p_prefix);
2801-
bool MCProperListEndsWithList(MCProperListRef list, MCProperListRef p_suffix);
2800+
MC_DLLEXPORT bool MCProperListBeginsWithList(MCProperListRef list, MCProperListRef p_prefix);
2801+
MC_DLLEXPORT bool MCProperListEndsWithList(MCProperListRef list, MCProperListRef p_suffix);
2802+
2803+
MC_DLLEXPORT bool MCProperListIsListOfType(MCProperListRef list, MCValueTypeCode p_type);
2804+
MC_DLLEXPORT bool MCProperListIsHomogeneous(MCProperListRef list, MCValueTypeCode& r_type);
28022805

28032806
////////////////////////////////////////////////////////////////////////////////
28042807

libfoundation/src/foundation-proper-list.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,53 @@ bool MCProperListEndsWithList(MCProperListRef self, MCProperListRef p_suffix)
671671

672672
////////////////////////////////////////////////////////////////////////////////
673673

674+
bool MCProperListIsListOfType(MCProperListRef self, MCValueTypeCode p_type)
675+
{
676+
// If the list is indirect, get the contents.
677+
MCProperListRef t_contents;
678+
if (!__MCProperListIsIndirect(self))
679+
t_contents = self;
680+
else
681+
t_contents = self -> contents;
682+
683+
for(uindex_t i = 0; i < t_contents -> length; i++)
684+
{
685+
if (MCValueGetTypeCode(t_contents -> list[i]) != p_type)
686+
return false;
687+
}
688+
689+
return true;
690+
}
691+
692+
bool MCProperListIsHomogeneous(MCProperListRef self, MCValueTypeCode& r_type)
693+
{
694+
if (MCProperListIsEmpty(self))
695+
{
696+
r_type = kMCValueTypeCodeNull;
697+
return true;
698+
}
699+
700+
// If the list is indirect, get the contents.
701+
MCProperListRef t_contents;
702+
if (!__MCProperListIsIndirect(self))
703+
t_contents = self;
704+
else
705+
t_contents = self -> contents;
706+
707+
MCValueTypeCode t_type;
708+
t_type = MCValueGetTypeCode(self -> list[0]);
709+
710+
if (MCProperListIsListOfType(self, t_type))
711+
{
712+
r_type = t_type;
713+
return true;
714+
}
715+
716+
return false;
717+
}
718+
719+
////////////////////////////////////////////////////////////////////////////////
720+
674721
void __MCProperListDestroy(__MCProperList *self)
675722
{
676723
if (__MCProperListIsIndirect(self))

libscript/src/module-sort.cpp

Lines changed: 89 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -22,70 +22,17 @@ static compare_t MCSortCompareText(void *context, MCValueRef p_left, MCValueRef
2222
// Since there are no default type conversions, sort all strings before anything else.
2323
MCStringOptions t_options = *(MCStringOptions *)context;
2424

25-
bool t_left_string, t_right_string;
26-
t_left_string = MCValueGetTypeCode(p_left) == kMCValueTypeCodeString;
27-
t_right_string = MCValueGetTypeCode(p_right) == kMCValueTypeCodeString;
28-
29-
if (t_left_string)
30-
{
31-
if (!t_right_string)
32-
return 0;
33-
34-
return MCStringCompareTo((MCStringRef)p_left, (MCStringRef)p_right, t_options);
35-
}
36-
else
37-
{
38-
if (t_right_string)
39-
return 1;
40-
41-
return 0;
42-
}
25+
return MCStringCompareTo((MCStringRef)p_left, (MCStringRef)p_right, t_options);
4326
}
4427

4528
static compare_t MCSortCompareBinary(void *context, MCValueRef p_left, MCValueRef p_right)
4629
{
47-
// Since there are no default type conversions, sort all data before anything else.
48-
bool t_left_data, t_right_data;
49-
t_left_data = MCValueGetTypeCode(p_left) == kMCValueTypeCodeData;
50-
t_right_data = MCValueGetTypeCode(p_right) == kMCValueTypeCodeData;
51-
52-
if (t_left_data)
53-
{
54-
if (!t_right_data)
55-
return 0;
56-
57-
return MCDataCompareTo((MCDataRef)p_left, (MCDataRef)p_right);
58-
}
59-
else
60-
{
61-
if (t_right_data)
62-
return 1;
63-
64-
return 0;
65-
}
30+
return MCDataCompareTo((MCDataRef)p_left, (MCDataRef)p_right);
6631
}
6732

6833
static compare_t MCSortCompareNumeric(void *context, MCValueRef p_left, MCValueRef p_right)
6934
{
70-
// Since there are no default type conversions, sort all numbers before anything else.
71-
bool t_left_data, t_right_data;
72-
t_left_data = MCValueGetTypeCode(p_left) == kMCValueTypeCodeNumber;
73-
t_right_data = MCValueGetTypeCode(p_right) == kMCValueTypeCodeNumber;
74-
75-
if (t_left_data)
76-
{
77-
if (!t_right_data)
78-
return 0;
79-
80-
return (MCNumberFetchAsReal((MCNumberRef)p_left) < MCNumberFetchAsReal((MCNumberRef)p_right)) ? -1 : 1;
81-
}
82-
else
83-
{
84-
if (t_right_data)
85-
return 1;
86-
87-
return 0;
88-
}
35+
return (MCNumberFetchAsReal((MCNumberRef)p_left) < MCNumberFetchAsReal((MCNumberRef)p_right)) ? -1 : 1;
8936
}
9037

9138
static compare_t MCSortCompareDateTime(void *context, MCValueRef p_left, MCValueRef p_right)
@@ -94,16 +41,37 @@ static compare_t MCSortCompareDateTime(void *context, MCValueRef p_left, MCValue
9441
return 0;
9542
}
9643

97-
extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingText(MCProperListRef& x_target)
44+
extern "C" MC_DLLEXPORT void MCSortExecSortList(MCProperListRef& x_target, bool p_descending)
9845
{
46+
MCValueTypeCode t_type;
47+
if (!MCProperListIsHomogeneous(x_target, t_type))
48+
{
49+
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("list is not homogeneous"), nil);
50+
return;
51+
}
52+
9953
MCAutoProperListRef t_mutable_list;
10054
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
10155
return;
10256

103-
// For now, just compare caseless.
104-
MCStringOptions t_option;
105-
t_option = kMCStringOptionCompareCaseless;
106-
MCProperListStableSort(*t_mutable_list, false, MCSortCompareText, &t_option);
57+
switch (t_type)
58+
{
59+
case kMCValueTypeCodeString:
60+
// For now, just compare caseless.
61+
MCStringOptions t_option;
62+
t_option = kMCStringOptionCompareCaseless;
63+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareText, &t_option);
64+
break;
65+
case kMCValueTypeCodeData:
66+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareBinary, nil);
67+
break;
68+
case kMCValueTypeCodeNumber:
69+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareNumeric, nil);
70+
break;
71+
default:
72+
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("list type does not have default comparison operator"), nil);
73+
return;
74+
}
10775

10876
MCAutoProperListRef t_sorted_list;
10977
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
@@ -112,16 +80,32 @@ extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingText(MCProperListRef& x_
11280
MCValueAssign(x_target, *t_sorted_list);
11381
}
11482

115-
extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingText(MCProperListRef& x_target)
83+
extern "C" MC_DLLEXPORT void MCSortExecSortListAscending(MCProperListRef& x_target)
84+
{
85+
MCSortExecSortList(x_target, false);
86+
}
87+
88+
extern "C" MC_DLLEXPORT void MCSortExecSortListDescending(MCProperListRef& x_target)
89+
{
90+
MCSortExecSortList(x_target, true);
91+
}
92+
93+
extern "C" MC_DLLEXPORT void MCSortExecSortListText(MCProperListRef& x_target, bool p_descending)
11694
{
95+
if (!MCProperListIsListOfType(x_target, kMCValueTypeCodeString))
96+
{
97+
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("list contains non-string element"), nil);
98+
return;
99+
}
100+
117101
MCAutoProperListRef t_mutable_list;
118102
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
119103
return;
120104

121105
// For now, just compare caseless.
122106
MCStringOptions t_option;
123107
t_option = kMCStringOptionCompareCaseless;
124-
MCProperListStableSort(*t_mutable_list, true, MCSortCompareText, &t_option);
108+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareText, &t_option);
125109

126110
MCAutoProperListRef t_sorted_list;
127111
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
@@ -130,13 +114,29 @@ extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingText(MCProperListRef& x
130114
MCValueAssign(x_target, *t_sorted_list);
131115
}
132116

133-
extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingBinary(MCProperListRef& x_target)
117+
extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingText(MCProperListRef& x_target)
134118
{
119+
MCSortExecSortListText(x_target, false);
120+
}
121+
122+
extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingText(MCProperListRef& x_target)
123+
{
124+
MCSortExecSortListText(x_target, true);
125+
}
126+
127+
extern "C" MC_DLLEXPORT void MCSortExecSortListBinary(MCProperListRef& x_target, bool p_descending)
128+
{
129+
if (!MCProperListIsListOfType(x_target, kMCValueTypeCodeData))
130+
{
131+
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("list contains non-data element"), nil);
132+
return;
133+
}
134+
135135
MCAutoProperListRef t_mutable_list;
136136
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
137137
return;
138138

139-
MCProperListStableSort(*t_mutable_list, false, MCSortCompareBinary, nil);
139+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareBinary, nil);
140140

141141
MCAutoProperListRef t_sorted_list;
142142
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
@@ -145,13 +145,29 @@ extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingBinary(MCProperListRef&
145145
MCValueAssign(x_target, *t_sorted_list);
146146
}
147147

148+
extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingBinary(MCProperListRef& x_target)
149+
{
150+
MCSortExecSortListBinary(x_target, false);
151+
}
152+
148153
extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingBinary(MCProperListRef& x_target)
149154
{
155+
MCSortExecSortListBinary(x_target, true);
156+
}
157+
158+
extern "C" MC_DLLEXPORT void MCSortExecSortListNumeric(MCProperListRef& x_target, bool p_descending)
159+
{
160+
if (!MCProperListIsListOfType(x_target, kMCValueTypeCodeNumber))
161+
{
162+
MCErrorCreateAndThrow(kMCGenericErrorTypeInfo, "reason", MCSTR("list contains non-numeric element"), nil);
163+
return;
164+
}
165+
150166
MCAutoProperListRef t_mutable_list;
151167
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
152168
return;
153169

154-
MCProperListStableSort(*t_mutable_list, true, MCSortCompareBinary, nil);
170+
MCProperListStableSort(*t_mutable_list, p_descending, MCSortCompareNumeric, nil);
155171

156172
MCAutoProperListRef t_sorted_list;
157173
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
@@ -162,35 +178,15 @@ extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingBinary(MCProperListRef&
162178

163179
extern "C" MC_DLLEXPORT void MCSortExecSortListAscendingNumeric(MCProperListRef& x_target)
164180
{
165-
MCAutoProperListRef t_mutable_list;
166-
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
167-
return;
168-
169-
MCProperListStableSort(*t_mutable_list, false, MCSortCompareNumeric, nil);
170-
171-
MCAutoProperListRef t_sorted_list;
172-
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
173-
return;
174-
175-
MCValueAssign(x_target, *t_sorted_list);
181+
MCSortExecSortListNumeric(x_target, false);
176182
}
177183

178184
extern "C" MC_DLLEXPORT void MCSortExecSortListDescendingNumeric(MCProperListRef& x_target)
179185
{
180-
MCAutoProperListRef t_mutable_list;
181-
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
182-
return;
183-
184-
MCProperListStableSort(*t_mutable_list, true, MCSortCompareNumeric, nil);
185-
186-
MCAutoProperListRef t_sorted_list;
187-
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
188-
return;
189-
190-
MCValueAssign(x_target, *t_sorted_list);
186+
MCSortExecSortListNumeric(x_target, true);
191187
}
192188

193-
void MCSortExecSortListAscendingDateTime(MCProperListRef& x_target)
189+
void MCSortExecSortListDateTime(MCProperListRef& x_target, bool p_descending)
194190
{
195191
MCAutoProperListRef t_mutable_list;
196192
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
@@ -205,34 +201,15 @@ void MCSortExecSortListAscendingDateTime(MCProperListRef& x_target)
205201
MCValueAssign(x_target, *t_sorted_list);
206202
}
207203

208-
void MCSortExecSortListDescendingDateTime(MCProperListRef& x_target)
204+
void MCSortExecSortListAscendingDateTime(MCProperListRef& x_target)
209205
{
210-
MCAutoProperListRef t_mutable_list;
211-
if (!MCProperListMutableCopy(x_target, &t_mutable_list))
212-
return;
213-
214-
MCProperListStableSort(*t_mutable_list, true, MCSortCompareDateTime, nil);
215-
216-
MCAutoProperListRef t_sorted_list;
217-
if (!MCProperListCopy(*t_mutable_list, &t_sorted_list))
218-
return;
219-
220-
MCValueAssign(x_target, *t_sorted_list);
206+
MCSortExecSortListDateTime(x_target, false);
221207
}
222208

223-
/*
224-
225-
void MCSortExecSortStringListAscendingNumeric(MCProperListRef<MCStringRef>& x_target)
226-
{
227-
MCProperListSort(x_target, true, kMCProperListSortTypeNumeric);
228-
}
229-
230-
void MCSortExecSortStringListDescendingNumeric(MCProperListRef<MCStringRef>& x_target)
209+
void MCSortExecSortListDescendingDateTime(MCProperListRef& x_target)
231210
{
232-
MCProperListSort(x_target, false, kMCProperListSortTypeNumeric);
211+
MCSortExecSortListDateTime(x_target, true);
233212
}
234-
235-
*/
236213

237214
////////////////////////////////////////////////////////////////////////////////////////////////////
238215

0 commit comments

Comments
 (0)