Home | History | Annotate | Download | only in Headers
      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     ANTLRHashMap *aNewANTLRHashMap;
     48     
     49     aNewANTLRHashMap = [[ANTLRHashMap alloc] init];
     50 	return( aNewANTLRHashMap );
     51 }
     52 
     53 +(id)newANTLRHashMapWithLen:(NSInteger)aBuffSize
     54 {
     55     ANTLRHashMap *aNewANTLRHashMap;
     56     
     57     aNewANTLRHashMap = [[ANTLRHashMap alloc] initWithLen:aBuffSize];
     58 	return( aNewANTLRHashMap );
     59 }
     60 
     61 -(id)init
     62 {
     63     NSInteger idx;
     64     
     65 	if ((self = [super init]) != nil) {
     66 		fNext = nil;
     67         BuffSize = HASHSIZE;
     68 		Scope = 0;
     69 		if ( fNext != nil ) {
     70 			Scope = ((ANTLRHashMap *)fNext)->Scope+1;
     71 			for( idx = 0; idx < BuffSize; idx++ ) {
     72 				ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx];
     73 			}
     74 		}
     75         mode = 0;
     76 	}
     77     return( self );
     78 }
     79 
     80 -(id)initWithLen:(NSInteger)aBuffSize
     81 {
     82     NSInteger idx;
     83     
     84 	if ((self = [super init]) != nil) {
     85 		fNext = nil;
     86         BuffSize = aBuffSize;
     87 		Scope = 0;
     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     ANTLRMapElement *tmp, *rtmp;
    102     NSInteger idx;
    103 	
    104     if ( self.fNext != nil ) {
    105         for( idx = 0; idx < BuffSize; idx++ ) {
    106             tmp = ptrBuffer[idx];
    107             while ( tmp && tmp != [((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
    108                 rtmp = tmp;
    109                 // tmp = [tmp getfNext];
    110                 tmp = (ANTLRMapElement *)tmp.fNext;
    111                 [rtmp dealloc];
    112             }
    113         }
    114     }
    115 	[super dealloc];
    116 }
    117 
    118 - (NSInteger)count
    119 {
    120     id anElement;
    121     NSInteger aCnt = 0;
    122     
    123     for (NSInteger i = 0; i < BuffSize; i++) {
    124         if ((anElement = ptrBuffer[i]) != nil) {
    125             aCnt++;
    126         }
    127     }
    128     return aCnt;
    129 }
    130                           
    131 - (NSInteger) size
    132 {
    133     id anElement;
    134     NSInteger aSize = 0;
    135     
    136     for (NSInteger i = 0; i < BuffSize; i++) {
    137         if ((anElement = ptrBuffer[i]) != nil) {
    138             aSize += sizeof(id);
    139         }
    140     }
    141     return aSize;
    142 }
    143                                   
    144                                   
    145 -(void)deleteANTLRHashMap:(ANTLRMapElement *)np
    146 {
    147     ANTLRMapElement *tmp, *rtmp;
    148     NSInteger idx;
    149     
    150     if ( self.fNext != nil ) {
    151         for( idx = 0; idx < BuffSize; idx++ ) {
    152             tmp = ptrBuffer[idx];
    153             while ( tmp && tmp != (ANTLRLinkBase *)[((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
    154                 rtmp = tmp;
    155                 tmp = [tmp getfNext];
    156                 [rtmp dealloc];
    157             }
    158         }
    159     }
    160 }
    161 
    162 -(ANTLRHashMap *)PushScope:(ANTLRHashMap **)map
    163 {
    164     NSInteger idx;
    165     ANTLRHashMap *htmp;
    166     
    167     htmp = [ANTLRHashMap newANTLRHashMap];
    168     if ( *map != nil ) {
    169         ((ANTLRHashMap *)htmp)->fNext = *map;
    170         [htmp setScope:[((ANTLRHashMap *)htmp->fNext) getScope]+1];
    171         for( idx = 0; idx < BuffSize; idx++ ) {
    172             htmp->ptrBuffer[idx] = ((ANTLRHashMap *)htmp->fNext)->ptrBuffer[idx];
    173         }
    174     }
    175     //    gScopeLevel++;
    176     *map = htmp;
    177     return( htmp );
    178 }
    179 
    180 -(ANTLRHashMap *)PopScope:(ANTLRHashMap **)map
    181 {
    182     NSInteger idx;
    183     ANTLRMapElement *tmp;
    184 	ANTLRHashMap *htmp;
    185     
    186     htmp = *map;
    187     if ( (*map)->fNext != nil ) {
    188         *map = (ANTLRHashMap *)htmp->fNext;
    189         for( idx = 0; idx < BuffSize; idx++ ) {
    190             if ( htmp->ptrBuffer[idx] == nil ||
    191                 htmp->ptrBuffer[idx] == (*map)->ptrBuffer[idx] ) {
    192                 break;
    193             }
    194             tmp = htmp->ptrBuffer[idx];
    195             /*
    196              * must deal with parms, locals and labels at some point
    197              * can not forget the debuggers
    198              */
    199             htmp->ptrBuffer[idx] = [tmp getfNext];
    200             [ tmp dealloc];
    201         }
    202         *map = (ANTLRHashMap *)htmp->fNext;
    203         //        gScopeLevel--;
    204     }
    205     return( htmp );
    206 }
    207 
    208 #ifdef USERDOC
    209 /*
    210  *  HASH        hash entry to get index to table
    211  *  NSInteger hash( ANTLRHashMap *self, char *s );
    212  *
    213  *     Inputs:  char *s             string to find
    214  *
    215  *     Returns: NSInteger                 hashed value
    216  *
    217  *  Last Revision 9/03/90
    218  */
    219 #endif
    220 -(NSInteger)hash:(NSString *)s       /*    form hash value for string s */
    221 {
    222 	NSInteger hashval;
    223 	const char *tmp;
    224     
    225 	tmp = [s cStringUsingEncoding:NSASCIIStringEncoding];
    226 	for( hashval = 0; *tmp != '\0'; )
    227         hashval += *tmp++;
    228 	self->LastHash = hashval % BuffSize;
    229 	return( self->LastHash );
    230 }
    231 
    232 #ifdef USERDOC
    233 /*
    234  *  FINDSCOPE  search hashed list for entry
    235  *  ANTLRHashMap *findscope( ANTLRHashMap *self, NSInteger scope );
    236  *
    237  *     Inputs:  NSInteger       scope -- scope level to find
    238  *
    239  *     Returns: ANTLRHashMap   pointer to ptrBuffer of proper scope level
    240  *
    241  *  Last Revision 9/03/90
    242  */
    243 #endif
    244 -(ANTLRHashMap *)findscope:(NSInteger)scope
    245 {
    246     if ( self->Scope == scope ) {
    247         return( self );
    248     }
    249     else if ( fNext ) {
    250         return( [((ANTLRHashMap *)fNext) findscope:scope] );
    251     }
    252     return( nil );              /*   not found      */
    253 }
    254 
    255 #ifdef USERDOC
    256 /*
    257  *  LOOKUP  search hashed list for entry
    258  *  ANTLRMapElement *lookup( ANTLRHashMap *self, char *s, NSInteger scope );
    259  *
    260  *     Inputs:  char     *s          string to find
    261  *
    262  *     Returns: ANTLRMapElement  *           pointer to entry
    263  *
    264  *  Last Revision 9/03/90
    265  */
    266 #endif
    267 -(id)lookup:(NSString *)s Scope:(NSInteger)scope
    268 {
    269     ANTLRMapElement *np;
    270     
    271     for( np = self->ptrBuffer[[self hash:s]]; np != nil; np = [np getfNext] ) {
    272         if ( [s isEqualToString:[np getName]] ) {
    273             return( np );        /*   found it       */
    274         }
    275     }
    276     return( nil );              /*   not found      */
    277 }
    278 
    279 #ifdef USERDOC
    280 /*
    281  *  INSTALL search hashed list for entry
    282  *  NSInteger install( ANTLRHashMap *self, ANTLRMapElement *sym, NSInteger scope );
    283  *
    284  *     Inputs:  ANTLRMapElement    *sym   -- symbol ptr to install
    285  *              NSInteger         scope -- level to find
    286  *
    287  *     Returns: Boolean     TRUE   if installed
    288  *                          FALSE  if already in table
    289  *
    290  *  Last Revision 9/03/90
    291  */
    292 #endif
    293 -(ANTLRMapElement *)install:(ANTLRMapElement *)sym Scope:(NSInteger)scope
    294 {
    295     ANTLRMapElement *np;
    296     
    297     np = [self lookup:[sym getName] Scope:scope ];
    298     if ( np == nil ) {
    299         [sym retain];
    300         [sym setFNext:self->ptrBuffer[ self->LastHash ]];
    301         self->ptrBuffer[ self->LastHash ] = sym;
    302         return( self->ptrBuffer[ self->LastHash ] );
    303     }
    304     return( nil );            /*   not found      */
    305 }
    306 
    307 #ifdef USERDOC
    308 /*
    309  *  RemoveSym  search hashed list for entry
    310  *  NSInteger RemoveSym( ANTLRHashMap *self, char *s );
    311  *
    312  *     Inputs:  char     *s          string to find
    313  *
    314  *     Returns: NSInteger      indicator of SUCCESS OR FAILURE
    315  *
    316  *  Last Revision 9/03/90
    317  */
    318 #endif
    319 -(NSInteger)RemoveSym:(NSString *)s
    320 {
    321     ANTLRMapElement *np, *tmp;
    322     NSInteger idx;
    323     
    324     idx = [self hash:s];
    325     for ( tmp = self->ptrBuffer[idx], np = self->ptrBuffer[idx]; np != nil; np = [np getfNext] ) {
    326         if ( [s isEqualToString:[np getName]] ) {
    327             tmp = [np getfNext];             /* get the next link  */
    328             [np dealloc];
    329             return( SUCCESS );            /* report SUCCESS     */
    330         }
    331         tmp = [np getfNext];              //  BAD!!!!!!
    332     }
    333     return( FAILURE );                    /*   not found      */
    334 }
    335 
    336 -(void)delete_chain:(ANTLRMapElement *)np
    337 {
    338     if ( [np getfNext] != nil )
    339 		[self delete_chain:[np getfNext]];
    340 	[np dealloc];
    341 }
    342 
    343 #ifdef DONTUSEYET
    344 -(NSInteger)bld_symtab:(KW_TABLE *)toknams
    345 {
    346     NSInteger i;
    347     ANTLRMapElement *np;
    348     
    349     for( i = 0; *(toknams[i].name) != '\0'; i++ ) {
    350         // install symbol in ptrBuffer
    351         np = [ANTLRMapElement newANTLRMapElement:[NSString stringWithFormat:@"%s", toknams[i].name]];
    352         //        np->fType = toknams[i].toknum;
    353         [self install:np Scope:0];
    354     }
    355     return( SUCCESS );
    356 }
    357 #endif
    358 
    359 -(ANTLRMapElement *)getptrBufferEntry:(NSInteger)idx
    360 {
    361 	return( ptrBuffer[idx] );
    362 }
    363 
    364 -(ANTLRMapElement **)getptrBuffer
    365 {
    366 	return( ptrBuffer );
    367 }
    368 
    369 -(void)setptrBuffer:(ANTLRMapElement *)np Index:(NSInteger)idx
    370 {
    371 	if ( idx < BuffSize ) {
    372         [np retain];
    373 		ptrBuffer[idx] = np;
    374     }
    375 }
    376 
    377 -(NSInteger)getScope
    378 {
    379 	return( Scope );
    380 }
    381 
    382 -(void)setScopeScope:(NSInteger)i
    383 {
    384 	Scope = i;
    385 }
    386 
    387 - (ANTLRMapElement *)getTType:(NSString *)name
    388 {
    389     return [self lookup:name Scope:0];
    390 }
    391 
    392 /*
    393  * works only for maplist indexed not by name but by TokenNumber
    394  */
    395 - (ANTLRMapElement *)getNameInList:(NSInteger)ttype
    396 {
    397     ANTLRMapElement *np;
    398     NSInteger aTType;
    399 
    400     aTType = ttype % BuffSize;
    401     for( np = self->ptrBuffer[ttype]; np != nil; np = [np getfNext] ) {
    402         if ( [np.index integerValue] == ttype ) {
    403             return( np );        /*   found it       */
    404         }
    405     }
    406     return( nil );              /*   not found      */
    407 }
    408 
    409 - (ANTLRLinkBase *)getName:(NSString *)name
    410 {
    411     return [self lookup:name Scope:0]; /*  nil if not found      */    
    412 }
    413 
    414 - (void)putNode:(NSString *)name TokenType:(NSInteger)ttype
    415 {
    416     ANTLRMapElement *np;
    417     
    418     // install symbol in ptrBuffer
    419     np = [ANTLRMapElement newANTLRMapElementWithName:[NSString stringWithString:name] Type:ttype];
    420     //        np->fType = toknams[i].toknum;
    421     [self install:np Scope:0];
    422 }
    423 
    424 - (NSInteger)getMode
    425 {
    426     return mode;
    427 }
    428 
    429 - (void)setMode:(NSInteger)aMode
    430 {
    431     mode = aMode;
    432 }
    433 
    434 - (void) addObject:(id)aRule
    435 {
    436     NSInteger idx;
    437 
    438     idx = [self count];
    439     if ( idx >= BuffSize ) {
    440         idx %= BuffSize;
    441     }
    442     ptrBuffer[idx] = aRule;
    443 }
    444 
    445 /* this may have to handle linking into the chain
    446  */
    447 - (void) insertObject:(id)aRule atIndex:(NSInteger)idx
    448 {
    449     if ( idx >= BuffSize ) {
    450         idx %= BuffSize;
    451     }
    452     if (aRule != ptrBuffer[idx]) {
    453         if (ptrBuffer[idx] != nil) [ptrBuffer[idx] release];
    454         [aRule retain];
    455     }
    456     ptrBuffer[idx] = aRule;
    457 }
    458 
    459 - (id)objectAtIndex:(NSInteger)idx
    460 {
    461     if ( idx >= BuffSize ) {
    462         idx %= BuffSize;
    463     }
    464     return ptrBuffer[idx];
    465 }
    466 
    467 /* this will never link into the chain
    468  */
    469 - (void) setObject:(id)aRule atIndex:(NSInteger)idx
    470 {
    471     if ( idx >= BuffSize ) {
    472         idx %= BuffSize;
    473     }
    474     if (aRule != ptrBuffer[idx]) {
    475         if (ptrBuffer[idx] != nil) [ptrBuffer[idx] release];
    476         [aRule retain];
    477     }
    478     ptrBuffer[idx] = aRule;
    479 }
    480 
    481 - (void)putName:(NSString *)name Node:(id)aNode
    482 {
    483     ANTLRMapElement *np;
    484     
    485     np = [self lookup:name Scope:0 ];
    486     if ( np == nil ) {
    487         np = [ANTLRMapElement newANTLRMapElementWithName:name Node:aNode];
    488         if (ptrBuffer[LastHash] != nil)
    489             [ptrBuffer[LastHash] release];
    490         [np retain];
    491         np.fNext = ptrBuffer[ LastHash ];
    492         ptrBuffer[ LastHash ] = np;
    493     }
    494     return;    
    495 }
    496 
    497 - (NSEnumerator *)objectEnumerator
    498 {
    499     NSEnumerator *anEnumerator;
    500 
    501     itIndex = 0;
    502     return anEnumerator;
    503 }
    504 
    505 - (BOOL)hasNext
    506 {
    507     if (self && [self count] < BuffSize-1) {
    508         return YES;
    509     }
    510     return NO;
    511 }
    512 
    513 - (ANTLRMapElement *)nextObject
    514 {
    515     if (self && itIndex < BuffSize-1) {
    516         return ptrBuffer[itIndex];
    517     }
    518     return nil;
    519 }
    520 
    521 @end
    522