/* ArrayRepBoolean.m Copyright (c) 1998-2009 Philippe Mougin. */
/* This software is open source. See the license. */
#import "build_config.h"
#import "ArrayRepBoolean.h"
#import "BlockPrivate.h"
#import "BlockRep.h"
#import "BlockInspector.h"
#import "string.h" // memcpy()
#import "ArrayPrivate.h"
#import "FSNumber.h"
#import "FScriptFunctions.h"
#import "FSBooleanPrivate.h"
#import "ArrayRepId.h"
#import "FSCompiler.h"
#import "FSExecEngine.h"
#ifndef MAX
#define MAX(a, b) \
({typeof(a) _a = (a); typeof(b) _b = (b); \
_a > _b ? _a : _b; })
#endif
#ifndef MIN
#define MIN(a, b) \
({typeof(a) _a = (a); typeof(b) _b = (b); \
_a < _b ? _a : _b; })
#endif
@implementation ArrayRepBoolean
////////////////////////////// USER METHODS SUPPORT /////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
- (id)operator_backslash:(FSBlock*)bl // May raise
{
NSUInteger i;
id args[3];
if ([bl isCompact])
{
SEL selector = [bl selector];
NSString *selectorStr = [bl selectorStr];
FSMsgContext *msgContext = [bl msgContext];
long acu = t[0];
args[1] = (id)(selector ? selector : [FSCompiler selectorFromString:selectorStr]);
if (selector == @selector(operator_ampersand:))
{
for (i = 0; i < count && t[i]; i++);
return (i == count ? (id)fsTrue : (id)fsFalse);
}
else if (selector == @selector(operator_bar:))
{
for (i = 0; i < count && !t[i]; i++);
return (i == count ? (id)fsFalse : (id)fsTrue);
}
else if (selector == @selector(operator_plus:))
{
for (i = 1; i < count; i++) acu += (t[i] ? 1 : 0);
return [FSNumber numberWithDouble:acu];
}
else
{
args[0] = (t[0] ? (id)fsTrue : (id)fsFalse);
for (i = 1; i < count; i++)
{
args[2] = (t[i] ? (id)fsTrue : (id)fsFalse);
args[0] = sendMsg(args[0], selector, 3, args, nil, msgContext, nil); // May raise
}
} // end if
}
else
{
BlockRep *blRep = [bl blockRep];
args[0] = (t[0] ? (id)fsTrue : (id)fsFalse);
for (i = 1; i < count; i++)
{
args[2] = (t[i] ? (id)fsTrue : (id)fsFalse);
args[0] = [blRep body_notCompact_valueArgs:args count:3 block:bl];
}
}
return args[0];
}
///////////////////////////// OPTIM ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
/*-------------------------------------- double loop ----------------------------------*/
// note: for all the doubleLoop... methods, precondition contains: [[operand arrayRep] isKindOfClass:[ArrayRepBoolean class]] && ![operand isProxy]
- (FSArray *)doubleLoop_operator_ampersand:(FSArray *)operand
{
char *opData = [[operand arrayRep] booleansPtr];
char *resTab;
NSUInteger i;
NSUInteger nb = MIN(count, [operand count]);
//NSLog(@"doubleLoop_operator_ampersand:");
resTab = malloc(nb*sizeof(char));
for(i=0; i < nb; i++) resTab[i] = t[i] && opData[i];
return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
}
- (FSArray *)doubleLoop_operator_bar:(FSArray *)operand
{
char *resTab;
NSUInteger i;
NSUInteger nb = MIN(count, [operand count]);
char *opData = [[operand arrayRep] booleansPtr];
//NSLog(@"doubleLoop_operator_bar:");
resTab = malloc(nb*sizeof(char));
for(i=0; i < nb; i++)
{
resTab[i] = t[i] || opData[i];
}
return [[[FSArray alloc] initWithRepNoRetain:[[ArrayRepBoolean alloc] initWithBooleansNoCopy:resTab count:nb]] autorelease];
}
/*-------------------------------------- simple loop ----------------------------------*/
- (FSArray *)simpleLoop_not
{
char *resTab;
NSUInteger i;
//NSLog(@"simpleLoop_operator_not");
resTab = malloc(count*sizeof(char));
for(i=0;i