Home | History | Annotate | Download | only in Framework
      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