1 // 2 // ANTLRHashMap.m 3 // ANTLR 4 // 5 // Copyright (c) 2010 Alan Condit 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions 10 // are met: 11 // 1. Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 2. Redistributions in binary form must reproduce the above copyright 14 // notice, this list of conditions and the following disclaimer in the 15 // documentation and/or other materials provided with the distribution. 16 // 3. The name of the author may not be used to endorse or promote products 17 // derived from this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 #define SUCCESS (0) 31 #define FAILURE (-1) 32 33 #import "ANTLRHashMap.h" 34 35 static NSInteger itIndex; 36 37 /* 38 * Start of ANTLRHashMap 39 */ 40 @implementation ANTLRHashMap 41 42 @synthesize Scope; 43 @synthesize LastHash; 44 45 +(id)newANTLRHashMap 46 { 47 return [[ANTLRHashMap alloc] init]; 48 } 49 50 +(id)newANTLRHashMapWithLen:(NSInteger)aBuffSize 51 { 52 return [[ANTLRHashMap alloc] initWithLen:aBuffSize]; 53 } 54 55 -(id)init 56 { 57 NSInteger idx; 58 59 if ((self = [super init]) != nil) { 60 fNext = nil; 61 Scope = 0; 62 ptr = 0; 63 BuffSize = HASHSIZE; 64 buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain]; 65 ptrBuffer = (ANTLRMapElement **) [buffer mutableBytes]; 66 if ( fNext != nil ) { 67 Scope = ((ANTLRHashMap *)fNext)->Scope+1; 68 for( idx = 0; idx < BuffSize; idx++ ) { 69 ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx]; 70 } 71 } 72 mode = 0; 73 } 74 return( self ); 75 } 76 77 -(id)initWithLen:(NSInteger)aBuffSize 78 { 79 NSInteger idx; 80 81 if ((self = [super init]) != nil) { 82 fNext = nil; 83 BuffSize = aBuffSize; 84 Scope = 0; 85 ptr = 0; 86 buffer = [[NSMutableData dataWithLength:(NSUInteger)BuffSize * sizeof(id)] retain]; 87 ptrBuffer = (ANTLRMapElement **) [buffer mutableBytes]; 88 if ( fNext != nil ) { 89 Scope = ((ANTLRHashMap *)fNext)->Scope+1; 90 for( idx = 0; idx < BuffSize; idx++ ) { 91 ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx]; 92 } 93 } 94 mode = 0; 95 } 96 return( self ); 97 } 98 99 -(void)dealloc 100 { 101 #ifdef DEBUG_DEALLOC 102 NSLog( @"called dealloc in ANTLRHashMap" ); 103 #endif 104 ANTLRMapElement *tmp, *rtmp; 105 NSInteger idx; 106 107 if ( self.fNext != nil ) { 108 for( idx = 0; idx < BuffSize; idx++ ) { 109 tmp = ptrBuffer[idx]; 110 while ( tmp && tmp != [((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) { 111 rtmp = tmp; 112 // tmp = [tmp getfNext]; 113 tmp = (ANTLRMapElement *)tmp.fNext; 114 [rtmp release]; 115 } 116 } 117 } 118 if ( buffer ) [buffer release]; 119 [super dealloc]; 120 } 121 122 - (NSInteger)count 123 { 124 NSInteger aCnt = 0; 125 126 for (NSInteger i = 0; i < BuffSize; i++) { 127 if ( ptrBuffer[i] != nil ) { 128 aCnt++; 129 } 130 } 131 return aCnt; 132 } 133 134 - (NSInteger) size 135 { 136 NSInteger aSize = 0; 137 138 for (NSInteger i = 0; i < BuffSize; i++) { 139 if ( ptrBuffer[i] != nil ) { 140 aSize += sizeof(id); 141 } 142 } 143 return aSize; 144 } 145 146 147 -(void)deleteANTLRHashMap:(ANTLRMapElement *)np 148 { 149 ANTLRMapElement *tmp, *rtmp; 150 NSInteger idx; 151 152 if ( self.fNext != nil ) { 153 for( idx = 0; idx < BuffSize; idx++ ) { 154 tmp = ptrBuffer[idx]; 155 while ( tmp && tmp != (ANTLRLinkBase *)[((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) { 156 rtmp = tmp; 157 tmp = [tmp getfNext]; 158 [rtmp release]; 159 } 160 } 161 } 162 } 163 164 -(ANTLRHashMap *)PushScope:(ANTLRHashMap **)map 165 { 166 NSInteger idx; 167 ANTLRHashMap *htmp; 168 169 htmp = [ANTLRHashMap newANTLRHashMap]; 170 if ( *map != nil ) { 171 ((ANTLRHashMap *)htmp)->fNext = *map; 172 [htmp setScope:[((ANTLRHashMap *)htmp->fNext) getScope]+1]; 173 for( idx = 0; idx < BuffSize; idx++ ) { 174 htmp->ptrBuffer[idx] = ((ANTLRHashMap *)htmp->fNext)->ptrBuffer[idx]; 175 } 176 } 177 // gScopeLevel++; 178 *map = htmp; 179 return( htmp ); 180 } 181 182 -(ANTLRHashMap *)PopScope:(ANTLRHashMap **)map 183 { 184 NSInteger idx; 185 ANTLRMapElement *tmp; 186 ANTLRHashMap *htmp; 187 188 htmp = *map; 189 if ( (*map)->fNext != nil ) { 190 *map = (ANTLRHashMap *)htmp->fNext; 191 for( idx = 0; idx < BuffSize; idx++ ) { 192 if ( htmp->ptrBuffer[idx] == nil || 193 htmp->ptrBuffer[idx] == (*map)->ptrBuffer[idx] ) { 194 break; 195 } 196 tmp = htmp->ptrBuffer[idx]; 197 /* 198 * must deal with parms, locals and labels at some point 199 * can not forget the debuggers 200 */ 201 htmp->ptrBuffer[idx] = [tmp getfNext]; 202 [tmp release]; 203 } 204 *map = (ANTLRHashMap *)htmp->fNext; 205 // gScopeLevel--; 206 } 207 return( htmp ); 208 } 209 210 #ifdef USERDOC 211 /* 212 * HASH hash entry to get index to table 213 * NSInteger hash( ANTLRHashMap *self, char *s ); 214 * 215 * Inputs: char *s string to find 216 * 217 * Returns: NSInteger hashed value 218 * 219 * Last Revision 9/03/90 220 */ 221 #endif 222 -(NSInteger)hash:(NSString *)s /* form hash value for string s */ 223 { 224 NSInteger hashval; 225 const char *tmp; 226 227 tmp = [s cStringUsingEncoding:NSASCIIStringEncoding]; 228 for( hashval = 0; *tmp != '\0'; ) 229 hashval += *tmp++; 230 self->LastHash = hashval % BuffSize; 231 return( self->LastHash ); 232 } 233 234 #ifdef USERDOC 235 /* 236 * FINDSCOPE search hashed list for entry 237 * ANTLRHashMap *findscope( ANTLRHashMap *self, NSInteger scope ); 238 * 239 * Inputs: NSInteger scope -- scope level to find 240 * 241 * Returns: ANTLRHashMap pointer to ptrBuffer of proper scope level 242 * 243 * Last Revision 9/03/90 244 */ 245 #endif 246 -(ANTLRHashMap *)findscope:(NSInteger)scope 247 { 248 if ( self->Scope == scope ) { 249 return( self ); 250 } 251 else if ( fNext ) { 252 return( [((ANTLRHashMap *)fNext) findscope:scope] ); 253 } 254 return( nil ); /* not found */ 255 } 256 257 #ifdef USERDOC 258 /* 259 * LOOKUP search hashed list for entry 260 * ANTLRMapElement *lookup( ANTLRHashMap *self, char *s, NSInteger scope ); 261 * 262 * Inputs: char *s string to find 263 * 264 * Returns: ANTLRMapElement * pointer to entry 265 * 266 * Last Revision 9/03/90 267 */ 268 #endif 269 -(id)lookup:(NSString *)s Scope:(NSInteger)scope 270 { 271 ANTLRMapElement *np; 272 273 for( np = self->ptrBuffer[[self hash:s]]; np != nil; np = [np getfNext] ) { 274 if ( [s isEqualToString:[np getName]] ) { 275 return( np ); /* found it */ 276 } 277 } 278 return( nil ); /* not found */ 279 } 280 281 #ifdef USERDOC 282 /* 283 * INSTALL search hashed list for entry 284 * NSInteger install( ANTLRHashMap *self, ANTLRMapElement *sym, NSInteger scope ); 285 * 286 * Inputs: ANTLRMapElement *sym -- symbol ptr to install 287 * NSInteger scope -- level to find 288 * 289 * Returns: Boolean TRUE if installed 290 * FALSE if already in table 291 * 292 * Last Revision 9/03/90 293 */ 294 #endif 295 -(ANTLRMapElement *)install:(ANTLRMapElement *)sym Scope:(NSInteger)scope 296 { 297 ANTLRMapElement *np; 298 299 np = [self lookup:[sym getName] Scope:scope ]; 300 if ( np == nil ) { 301 [sym retain]; 302 [sym setFNext:self->ptrBuffer[ self->LastHash ]]; 303 self->ptrBuffer[ self->LastHash ] = sym; 304 return( self->ptrBuffer[ self->LastHash ] ); 305 } 306 return( nil ); /* not found */ 307 } 308 309 #ifdef USERDOC 310 /* 311 * RemoveSym search hashed list for entry 312 * NSInteger RemoveSym( ANTLRHashMap *self, char *s ); 313 * 314 * Inputs: char *s string to find 315 * 316 * Returns: NSInteger indicator of SUCCESS OR FAILURE 317 * 318 * Last Revision 9/03/90 319 */ 320 #endif 321 -(NSInteger)RemoveSym:(NSString *)s 322 { 323 ANTLRMapElement *np, *tmp; 324 NSInteger idx; 325 326 idx = [self hash:s]; 327 for ( tmp = self->ptrBuffer[idx], np = self->ptrBuffer[idx]; np != nil; np = [np getfNext] ) { 328 if ( [s isEqualToString:[np getName]] ) { 329 tmp = [np getfNext]; /* get the next link */ 330 [np release]; 331 return( SUCCESS ); /* report SUCCESS */ 332 } 333 tmp = [np getfNext]; // BAD!!!!!! 334 } 335 return( FAILURE ); /* not found */ 336 } 337 338 -(void)delete_chain:(ANTLRMapElement *)np 339 { 340 if ( [np getfNext] != nil ) 341 [self delete_chain:[np getfNext]]; 342 [np dealloc]; 343 } 344 345 #ifdef DONTUSEYET 346 -(NSInteger)bld_symtab:(KW_TABLE *)toknams 347 { 348 NSInteger i; 349 ANTLRMapElement *np; 350 351 for( i = 0; *(toknams[i].name) != '\0'; i++ ) { 352 // install symbol in ptrBuffer 353 np = [ANTLRMapElement newANTLRMapElement:[NSString stringWithFormat:@"%s", toknams[i].name]]; 354 // np->fType = toknams[i].toknum; 355 [self install:np Scope:0]; 356 } 357 return( SUCCESS ); 358 } 359 #endif 360 361 -(ANTLRMapElement *)getptrBufferEntry:(NSInteger)idx 362 { 363 return( ptrBuffer[idx] ); 364 } 365 366 -(ANTLRMapElement **)getptrBuffer 367 { 368 return( ptrBuffer ); 369 } 370 371 -(void)setptrBuffer:(ANTLRMapElement *)np Index:(NSInteger)idx 372 { 373 if ( idx < BuffSize ) { 374 [np retain]; 375 ptrBuffer[idx] = np; 376 } 377 } 378 379 -(NSInteger)getScope 380 { 381 return( Scope ); 382 } 383 384 -(void)setScopeScope:(NSInteger)i 385 { 386 Scope = i; 387 } 388 389 - (ANTLRMapElement *)getTType:(NSString *)name 390 { 391 return [self lookup:name Scope:0]; 392 } 393 394 /* 395 * works only for maplist indexed not by name but by TokenNumber 396 */ 397 - (ANTLRMapElement *)getNameInList:(NSInteger)ttype 398 { 399 ANTLRMapElement *np; 400 NSInteger aTType; 401 402 aTType = ttype % BuffSize; 403 for( np = self->ptrBuffer[aTType]; np != nil; np = [np getfNext] ) { 404 if ( [(NSNumber *)np.node integerValue] == ttype ) { 405 return( np ); /* found it */ 406 } 407 } 408 return( nil ); /* not found */ 409 } 410 411 - (ANTLRLinkBase *)getName:(NSString *)name 412 { 413 return [self lookup:name Scope:0]; /* nil if not found */ 414 } 415 416 - (void)putNode:(NSString *)name TokenType:(NSInteger)ttype 417 { 418 ANTLRMapElement *np; 419 420 // install symbol in ptrBuffer 421 np = [ANTLRMapElement newANTLRMapElementWithName:[NSString stringWithString:name] Type:ttype]; 422 // np->fType = toknams[i].toknum; 423 [self install:np Scope:0]; 424 } 425 426 - (NSInteger)getMode 427 { 428 return mode; 429 } 430 431 - (void)setMode:(NSInteger)aMode 432 { 433 mode = aMode; 434 } 435 436 - (void) addObject:(id)aRule 437 { 438 NSInteger idx; 439 440 idx = [self count]; 441 if ( idx >= BuffSize ) { 442 idx %= BuffSize; 443 } 444 ptrBuffer[idx] = aRule; 445 } 446 447 /* this may have to handle linking into the chain 448 */ 449 - (void) insertObject:(id)aRule atIndex:(NSInteger)idx 450 { 451 if ( idx >= BuffSize ) { 452 idx %= BuffSize; 453 } 454 if ( aRule != ptrBuffer[idx] ) { 455 if ( ptrBuffer[idx] ) [ptrBuffer[idx] release]; 456 [aRule retain]; 457 } 458 ptrBuffer[idx] = aRule; 459 } 460 461 - (id)objectAtIndex:(NSInteger)idx 462 { 463 if ( idx >= BuffSize ) { 464 idx %= BuffSize; 465 } 466 return ptrBuffer[idx]; 467 } 468 469 /* this will never link into the chain 470 */ 471 - (void) setObject:(id)aRule atIndex:(NSInteger)idx 472 { 473 if ( idx >= BuffSize ) { 474 idx %= BuffSize; 475 } 476 if ( aRule != ptrBuffer[idx] ) { 477 if ( ptrBuffer[idx] ) [ptrBuffer[idx] release]; 478 [aRule retain]; 479 } 480 ptrBuffer[idx] = aRule; 481 } 482 483 - (void)putName:(NSString *)name Node:(id)aNode 484 { 485 ANTLRMapElement *np; 486 487 np = [self lookup:name Scope:0 ]; 488 if ( np == nil ) { 489 np = [ANTLRMapElement newANTLRMapElementWithName:name Node:aNode]; 490 if ( ptrBuffer[LastHash] ) 491 [ptrBuffer[LastHash] release]; 492 [np retain]; 493 np.fNext = ptrBuffer[ LastHash ]; 494 ptrBuffer[ LastHash ] = np; 495 } 496 return; 497 } 498 499 - (NSEnumerator *)objectEnumerator 500 { 501 #pragma mark fix this its broken 502 NSEnumerator *anEnumerator; 503 504 itIndex = 0; 505 return anEnumerator; 506 } 507 508 - (BOOL)hasNext 509 { 510 if (self && [self count] < BuffSize-1) { 511 return YES; 512 } 513 return NO; 514 } 515 516 - (ANTLRMapElement *)nextObject 517 { 518 if (self && itIndex < BuffSize-1) { 519 return ptrBuffer[itIndex]; 520 } 521 return nil; 522 } 523 524 @synthesize BuffSize; 525 @synthesize count; 526 @synthesize ptr; 527 @synthesize ptrBuffer; 528 @synthesize buffer; 529 @end 530