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 35static 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