1 // [The "BSD licence"] 2 // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. The name of the author may not be used to endorse or promote products 14 // derived from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #import "ANTLRBitSet.h" 28 29 @implementation ANTLRBitSet 30 #pragma mark Class Methods 31 32 + (ANTLRBitSet *) newBitSet 33 { 34 return [[ANTLRBitSet alloc] init]; 35 } 36 37 + (ANTLRBitSet *) newBitSetWithType:(TokenType)type 38 { 39 return [[ANTLRBitSet alloc] initWithType:type]; 40 } 41 42 /** Construct a ANTLRBitSet given the size 43 * @param nbits The size of the ANTLRBitSet in bits 44 */ 45 + (ANTLRBitSet *) newBitSetWithNBits:(NSUInteger)nbits 46 { 47 return [[ANTLRBitSet alloc] initWithNBits:nbits]; 48 } 49 50 + (ANTLRBitSet *) newBitSetWithArray:(AMutableArray *)types 51 { 52 return [[ANTLRBitSet alloc] initWithArrayOfBits:types]; 53 } 54 55 + (ANTLRBitSet *) newBitSetWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount 56 { 57 return [[ANTLRBitSet alloc] initWithBits:theBits Count:longCount]; 58 } 59 60 61 + (ANTLRBitSet *) of:(NSUInteger) el 62 { 63 ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:(el + 1)]; 64 [s add:el]; 65 return s; 66 } 67 68 + (ANTLRBitSet *) of:(NSUInteger) a And2:(NSUInteger) b 69 { 70 NSInteger c = (((a>b)?a:b)+1); 71 ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:c]; 72 [s add:a]; 73 [s add:b]; 74 return s; 75 } 76 77 + (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c 78 { 79 NSUInteger d = ((a>b)?a:b); 80 d = ((c>d)?c:d)+1; 81 ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:d]; 82 [s add:a]; 83 [s add:b]; 84 [s add:c]; 85 return s; 86 } 87 88 + (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c And4:(NSUInteger)d 89 { 90 NSUInteger e = ((a>b)?a:b); 91 NSUInteger f = ((c>d)?c:d); 92 e = ((e>f)?e:f)+1; 93 ANTLRBitSet *s = [ANTLRBitSet newBitSetWithNBits:e]; 94 [s add:a]; 95 [s add:b]; 96 [s add:c]; 97 [s add:d]; 98 return s; 99 } 100 101 // initializer 102 #pragma mark Initializer 103 104 - (ANTLRBitSet *) init 105 { 106 if ((self = [super init]) != nil) { 107 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 108 } 109 return self; 110 } 111 112 - (ANTLRBitSet *) initWithType:(TokenType)type 113 { 114 if ((self = [super init]) != nil) { 115 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 116 if ((CFIndex)type >= CFBitVectorGetCount(bitVector)) 117 CFBitVectorSetCount(bitVector, type+1); 118 CFBitVectorSetBitAtIndex(bitVector, type, 1); 119 } 120 return self; 121 } 122 123 - (ANTLRBitSet *) initWithNBits:(NSUInteger)nbits 124 { 125 if ((self = [super init]) != nil) { 126 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 127 CFBitVectorSetCount( bitVector, nbits ); 128 } 129 return self; 130 } 131 132 - (ANTLRBitSet *) initWithBitVector:(CFMutableBitVectorRef)theBitVector 133 { 134 if ((self = [super init]) != nil) { 135 bitVector = theBitVector; 136 } 137 return self; 138 } 139 140 // Initialize the bit vector with a constant array of ulonglongs like ANTLR generates. 141 // Converts to big endian, because the underlying CFBitVector works like that. 142 - (ANTLRBitSet *) initWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount 143 { 144 if ((self = [super init]) != nil) { 145 unsigned int longNo; 146 // unsigned long long swappedBits = 0LL; 147 CFIndex bitIdx; 148 bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 ); 149 CFBitVectorSetCount( bitVector, sizeof(unsigned long long)*8*longCount ); 150 151 for (longNo = 0; longNo < longCount; longNo++) { 152 for (bitIdx = 0; bitIdx < (CFIndex)sizeof(unsigned long long)*8; bitIdx++) { 153 // swappedBits = CFSwapInt64HostToBig(theBits[longNo]); 154 // if (swappedBits & (1LL << bitIdx)) { 155 if (theBits[longNo] & (1LL << bitIdx)) { 156 CFBitVectorSetBitAtIndex(bitVector, bitIdx+(longNo*(sizeof(unsigned long long)*8)), 1); 157 } 158 } 159 } 160 } 161 return self; 162 } 163 164 // Initialize bit vector with an array of anything. Just test the boolValue and set the corresponding bit. 165 // Note: This is big-endian! 166 - (ANTLRBitSet *) initWithArrayOfBits:(NSArray *)theArray 167 { 168 if ((self = [super init]) != nil) { 169 bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 ); 170 id value; 171 int bit = 0; 172 for (value in theArray) { 173 if ([value boolValue] == YES) { 174 [self add:bit]; 175 //CFBitVectorSetBitAtIndex(bitVector, bit, 1); 176 } 177 bit++; 178 } 179 } 180 return self; 181 } 182 183 - (void)dealloc 184 { 185 #ifdef DEBUG_DEALLOC 186 NSLog( @"called dealloc in ANTLRBitSet" ); 187 #endif 188 CFRelease(bitVector); 189 [super dealloc]; 190 } 191 192 // operations 193 #pragma mark Operations 194 // return a copy of (self|aBitSet) 195 - (ANTLRBitSet *) or:(ANTLRBitSet *) aBitSet 196 { 197 ANTLRBitSet *bitsetCopy = [self mutableCopyWithZone:nil]; 198 [bitsetCopy orInPlace:aBitSet]; 199 return bitsetCopy; 200 } 201 202 // perform a bitwise OR operation in place by changing underlying bit vector, growing it if necessary 203 - (void) orInPlace:(ANTLRBitSet *) aBitSet 204 { 205 CFIndex selfCnt = CFBitVectorGetCount(bitVector); 206 CFMutableBitVectorRef otherBitVector = [aBitSet _bitVector]; 207 CFIndex otherCnt = CFBitVectorGetCount(otherBitVector); 208 CFIndex maxBitCnt = selfCnt > otherCnt ? selfCnt : otherCnt; 209 CFBitVectorSetCount(bitVector,maxBitCnt); // be sure to grow the CFBitVector manually! 210 211 CFIndex currIdx; 212 for (currIdx = 0; currIdx < maxBitCnt; currIdx++) { 213 if (CFBitVectorGetBitAtIndex(bitVector, currIdx) | CFBitVectorGetBitAtIndex(otherBitVector, currIdx)) { 214 CFBitVectorSetBitAtIndex(bitVector, currIdx, 1); 215 } 216 } 217 } 218 219 // set a bit, grow the bit vector if necessary 220 - (void) add:(NSUInteger) bit 221 { 222 if ((CFIndex)bit >= CFBitVectorGetCount(bitVector)) 223 CFBitVectorSetCount(bitVector, bit+1); 224 CFBitVectorSetBitAtIndex(bitVector, bit, 1); 225 } 226 227 // unset a bit 228 - (void) remove:(NSUInteger) bit 229 { 230 CFBitVectorSetBitAtIndex(bitVector, bit, 0); 231 } 232 233 - (void) setAllBits:(BOOL) aState 234 { 235 for( NSInteger bit=0; bit < CFBitVectorGetCount(bitVector); bit++ ) { 236 CFBitVectorSetBitAtIndex(bitVector, bit, aState); 237 } 238 } 239 240 // returns the number of bits in the bit vector. 241 - (NSInteger) numBits 242 { 243 // return CFBitVectorGetCount(bitVector); 244 return CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0, CFBitVectorGetCount(bitVector)), 1); 245 } 246 247 // returns the number of bits in the bit vector. 248 - (NSUInteger) size 249 { 250 return CFBitVectorGetCount(bitVector); 251 } 252 253 - (void) setSize:(NSUInteger) nBits 254 { 255 CFBitVectorSetCount( bitVector, nBits ); 256 } 257 258 #pragma mark Informational 259 // return a bitmask representation of this bitvector for easy operations 260 - (unsigned long long) bitMask:(NSUInteger) bitNumber 261 { 262 return 1LL << bitNumber; 263 } 264 265 // test a bit (no pun intended) 266 - (BOOL) member:(NSUInteger) bitNumber 267 { 268 return CFBitVectorGetBitAtIndex(bitVector,bitNumber) ? YES : NO; 269 } 270 271 // are all bits off? 272 - (BOOL) isNil 273 { 274 return ((CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0,CFBitVectorGetCount(bitVector)), 1) == 0) ? YES : NO); 275 } 276 277 // debugging aid. GDB invokes this automagically 278 // return a string representation of the bit vector, indicating by their bitnumber which bits are set 279 - (NSString *) description 280 { 281 CFIndex length = CFBitVectorGetCount(bitVector); 282 CFIndex currBit; 283 NSMutableString *descString = [NSMutableString stringWithString:@"{"]; 284 BOOL haveInsertedBit = NO; 285 for (currBit = 0; currBit < length; currBit++) { 286 if ( CFBitVectorGetBitAtIndex(bitVector, currBit) ) { 287 if (haveInsertedBit) { 288 [descString appendString:@","]; 289 } 290 [descString appendFormat:@"%d", currBit]; 291 haveInsertedBit = YES; 292 } 293 } 294 [descString appendString:@"}"]; 295 return descString; 296 } 297 298 // return a string representation of the bit vector, indicating by their bitnumber which bits are set 299 - (NSString *) toString 300 { 301 302 return [self description]; 303 } 304 305 // NSCopying 306 #pragma mark NSCopying support 307 308 - (id) mutableCopyWithZone:(NSZone *) theZone 309 { 310 ANTLRBitSet *newBitSet = [[ANTLRBitSet allocWithZone:theZone] initWithBitVector:CFBitVectorCreateMutableCopy(kCFAllocatorDefault,0,bitVector)]; 311 return newBitSet; 312 } 313 314 - (CFMutableBitVectorRef) _bitVector 315 { 316 return bitVector; 317 } 318 319 @synthesize bitVector; 320 @end 321 322 NSInteger max(NSInteger a, NSInteger b) 323 { 324 return (a>b)?a:b; 325 } 326 327