public
Description: The Nu programming language.
Homepage: http://programming.nu
Clone URL: git://github.com/timburks/nu.git
select: and filter: methods now treat 0 (zero) as false values.

The cond, if, unless, etc. operators already were treating
zero as false which greatly simplifies the use of C functions
and Objective-C methods that return 0 to indicate false.
This change set extends that to also apply to the select:
and find: methods of NuEnumerable and NuCell and also adds
unit tests for both groups of enumeration methods.

While preparing the tests, I noticed that I had not added
a mapSelector: to NuCell when I recently added it to
NuEnumerable, so to correct that inconsistency a
(NuCell mapSelector:) is now included and tested.
timburks (author)
Wed Apr 30 17:08:12 -0700 2008
commit  7730e3e43e1b9f70c589df63c0f973bb9fd26710
tree    d1b780509255d91ea8fa01469ead95ce4e87ff37
parent  851b1e299f6a23fed9b87f127537d924e99af58d
...
284
285
286
287
 
288
289
290
...
307
308
309
310
 
311
312
313
...
341
342
343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
345
346
...
284
285
286
 
287
288
289
290
...
307
308
309
 
310
311
312
313
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
0
@@ -284,7 +284,7 @@ extern char *nu_parsedFilename(int i);
0
         while (cursor && (cursor != Nu__null)) {
0
             [args setCar:[cursor car]];
0
             id result = [block evalWithArguments:args context:Nu__null];
0
- if (result && (result != Nu__null)) {
0
+ if (nu_valueIsTrue(result)) {
0
                 [resultCursor setCdr:[NuCell cellWithCar:[cursor car] cdr:[resultCursor cdr]]];
0
                 resultCursor = [resultCursor cdr];
0
             }
0
@@ -307,7 +307,7 @@ extern char *nu_parsedFilename(int i);
0
         while (cursor && (cursor != Nu__null)) {
0
             [args setCar:[cursor car]];
0
             id result = [block evalWithArguments:args context:Nu__null];
0
- if (result && (result != Nu__null)) {
0
+ if (nu_valueIsTrue(result)) {
0
                 [args release];
0
                 return [cursor car];
0
             }
0
@@ -341,6 +341,25 @@ extern char *nu_parsedFilename(int i);
0
     return result;
0
 }
0
 
0
+- (id) mapSelector:(SEL) sel
0
+{
0
+ NuCell *parent = [[NuCell alloc] init];
0
+ id args = [[NuCell alloc] init];
0
+ id cursor = self;
0
+ id resultCursor = parent;
0
+ while (cursor && (cursor != Nu__null)) {
0
+ id object = [cursor car];
0
+ id result = [object performSelector:sel];
0
+ [resultCursor setCdr:[NuCell cellWithCar:result cdr:[resultCursor cdr]]];
0
+ cursor = [cursor cdr];
0
+ resultCursor = [resultCursor cdr];
0
+ }
0
+ [args release];
0
+ NuCell *result = [parent cdr];
0
+ [parent release];
0
+ return result;
0
+}
0
+
0
 - (id) reduce:(NuBlock *) block from:(id) initial
0
 {
0
     id result = initial;
...
61
62
63
 
 
 
 
 
 
 
 
 
 
64
65
66
...
71
72
73
74
 
75
76
77
...
89
90
91
92
 
93
94
95
...
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
...
81
82
83
 
84
85
86
87
...
99
100
101
 
102
103
104
105
0
@@ -61,6 +61,16 @@ limitations under the License.
0
     return self;
0
 }
0
 
0
+static bool nu_valueIsTrue(id value)
0
+{
0
+ bool result = value && (value != Nu__null);
0
+ if (result && nu_objectIsKindOfClass(value, [NSNumber class])) {
0
+ if ([value doubleValue] == 0.0)
0
+ result = false;
0
+ }
0
+ return result;
0
+}
0
+
0
 - (NSArray *) select:(NuBlock *) block
0
 {
0
     NSMutableArray *selected = [[NSMutableArray alloc] init];
0
@@ -71,7 +81,7 @@ limitations under the License.
0
         while ((object = [enumerator nextObject])) {
0
             [args setCar:object];
0
             id result = [block evalWithArguments:args context:Nu__null];
0
- if (result && (result != Nu__null)) {
0
+ if (nu_valueIsTrue(result)) {
0
                 [selected addObject:object];
0
             }
0
         }
0
@@ -89,7 +99,7 @@ limitations under the License.
0
         while ((object = [enumerator nextObject])) {
0
             [args setCar:object];
0
             id result = [block evalWithArguments:args context:Nu__null];
0
- if (result && (result != Nu__null)) {
0
+ if (nu_valueIsTrue(result)) {
0
                 [args release];
0
                 return object;
0
             }
...
31
32
33
 
 
 
 
 
 
 
 
 
 
34
35
36
...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
0
@@ -31,6 +31,16 @@ limitations under the License.
0
 
0
 id Nu__null = 0;
0
 
0
+bool nu_valueIsTrue(id value)
0
+{
0
+ bool result = value && (value != Nu__null);
0
+ if (result && nu_objectIsKindOfClass(value, [NSNumber class])) {
0
+ if ([value doubleValue] == 0.0)
0
+ result = false;
0
+ }
0
+ return result;
0
+}
0
+
0
 @interface NuApplication : NSObject
0
 {
0
     NSMutableArray *arguments;
...
33
34
35
 
 
 
...
33
34
35
36
37
38
0
@@ -33,3 +33,6 @@ limitations under the License.
0
 
0
 @interface NuContinueException : NSException {}
0
 @end
0
+
0
+// use this to test a value for "truth"
0
+bool nu_valueIsTrue(id value);
...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
...
220
221
222
223
 
224
225
226
...
290
291
292
293
 
294
295
296
...
299
300
301
302
 
303
304
305
...
318
319
320
321
 
322
323
324
...
358
359
360
361
 
362
363
364
...
391
392
393
394
 
395
396
397
...
431
432
433
434
 
435
436
437
...
1071
1072
1073
1074
 
1075
1076
1077
...
1089
1090
1091
1092
 
1093
1094
1095
...
1108
1109
1110
1111
 
1112
1113
1114
...
51
52
53
 
 
 
 
 
 
 
 
 
 
54
55
56
...
210
211
212
 
213
214
215
216
...
280
281
282
 
283
284
285
286
...
289
290
291
 
292
293
294
295
...
308
309
310
 
311
312
313
314
...
348
349
350
 
351
352
353
354
...
381
382
383
 
384
385
386
387
...
421
422
423
 
424
425
426
427
...
1061
1062
1063
 
1064
1065
1066
1067
...
1079
1080
1081
 
1082
1083
1084
1085
...
1098
1099
1100
 
1101
1102
1103
1104
0
@@ -51,16 +51,6 @@ limitations under the License.
0
 
0
 @end
0
 
0
-static bool valueIsTrue(id value)
0
-{
0
- bool result = value && (value != Nu__null);
0
- if (result && nu_objectIsKindOfClass(value, [NSNumber class])) {
0
- if ([value doubleValue] == 0.0)
0
- result = false;
0
- }
0
- return result;
0
-}
0
-
0
 @implementation NuOperator : NSObject
0
 - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context {return nil;}
0
 - (id) evalWithArguments:(id)cdr context:(NSMutableDictionary *)context {return [self callWithArguments:cdr context:context];}
0
@@ -220,7 +210,7 @@ static bool valueIsTrue(id value)
0
     while (pairs != Nu__null) {
0
         id condition = [[pairs car] car];
0
         id test = [condition evalWithContext:context];
0
- if (valueIsTrue(test)) {
0
+ if (nu_valueIsTrue(test)) {
0
             value = test;
0
             id cursor = [[pairs car] cdr];
0
             while (cursor && (cursor != Nu__null)) {
0
@@ -290,7 +280,7 @@ static bool valueIsTrue(id value)
0
     id result = Nu__null;
0
     id test = [[cdr car] evalWithContext:context];
0
 
0
- bool testIsTrue = flip ^ valueIsTrue(test);
0
+ bool testIsTrue = flip ^ nu_valueIsTrue(test);
0
     bool noneIsTrue = !testIsTrue;
0
 
0
     id expressions = [cdr cdr];
0
@@ -299,7 +289,7 @@ static bool valueIsTrue(id value)
0
         if (nu_objectIsKindOfClass(nextExpression, [NuCell class])) {
0
             /*if ([nextExpression car] == elseifSymbol) {
0
                 test = [[[[expressions car] cdr] car] evalWithContext:context];
0
- testIsTrue = noneIsTrue && valueIsTrue(test);
0
+ testIsTrue = noneIsTrue && nu_valueIsTrue(test);
0
                 noneIsTrue = noneIsTrue && !testIsTrue;
0
                 if (testIsTrue)
0
                     // skip the test:
0
@@ -318,7 +308,7 @@ static bool valueIsTrue(id value)
0
         else {
0
             /*if (nextExpression == elseifSymbol) {
0
                 test = [[[expressions cdr] car] evalWithContext:context];
0
- testIsTrue = noneIsTrue && valueIsTrue(test);
0
+ testIsTrue = noneIsTrue && nu_valueIsTrue(test);
0
                 noneIsTrue = noneIsTrue && !testIsTrue;
0
                 expressions = [expressions cdr]; // skip the test
0
             }
0
@@ -358,7 +348,7 @@ static bool valueIsTrue(id value)
0
 {
0
     id result = Nu__null;
0
     id test = [[cdr car] evalWithContext:context];
0
- while (valueIsTrue(test)) {
0
+ while (nu_valueIsTrue(test)) {
0
         @try
0
         {
0
             id expressions = [cdr cdr];
0
@@ -391,7 +381,7 @@ static bool valueIsTrue(id value)
0
 {
0
     id result = Nu__null;
0
     id test = [[cdr car] evalWithContext:context];
0
- while (!valueIsTrue(test)) {
0
+ while (!nu_valueIsTrue(test)) {
0
         @try
0
         {
0
             id expressions = [cdr cdr];
0
@@ -431,7 +421,7 @@ static bool valueIsTrue(id value)
0
     [loopinit evalWithContext:context];
0
     // evaluate the loop condition
0
     id test = [looptest evalWithContext:context];
0
- while (valueIsTrue(test)) {
0
+ while (nu_valueIsTrue(test)) {
0
         @try
0
         {
0
             id expressions = [cdr cdr];
0
@@ -1071,7 +1061,7 @@ static bool valueIsTrue(id value)
0
     id value = Nu__null;
0
     while (cursor && (cursor != Nu__null)) {
0
         value = [[cursor car] evalWithContext:context];
0
- if (!valueIsTrue(value))
0
+ if (!nu_valueIsTrue(value))
0
             return Nu__null;
0
         cursor = [cursor cdr];
0
     }
0
@@ -1089,7 +1079,7 @@ static bool valueIsTrue(id value)
0
     id cursor = cdr;
0
     while (cursor && (cursor != Nu__null)) {
0
         id value = [[cursor car] evalWithContext:context];
0
- if (valueIsTrue(value))
0
+ if (nu_valueIsTrue(value))
0
             return value;
0
         cursor = [cursor cdr];
0
     }
0
@@ -1108,7 +1098,7 @@ static bool valueIsTrue(id value)
0
     id cursor = cdr;
0
     if (cursor && (cursor != Nu__null)) {
0
         id value = [[cursor car] evalWithContext:context];
0
- return valueIsTrue(value) ? Nu__null : [symbolTable symbolWithCString:"t"];
0
+ return nu_valueIsTrue(value) ? Nu__null : [symbolTable symbolWithCString:"t"];
0
     }
0
     return Nu__null;
0
 }

Comments

    No one has commented yet.