blob: a23426b058f2916aa15e56ecd7ddd74407532d81 [file] [log] [blame]
//
// ANTLRHashMap.m
// ANTLR
//
// Copyright (c) 2010 Alan Condit
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SUCCESS (0)
#define FAILURE (-1)
#import "ANTLRHashMap.h"
static NSInteger itIndex;
/*
* Start of ANTLRHashMap
*/
@implementation ANTLRHashMap
@synthesize Scope;
@synthesize LastHash;
+(id)newANTLRHashMap
{
ANTLRHashMap *aNewANTLRHashMap;
aNewANTLRHashMap = [[ANTLRHashMap alloc] init];
return( aNewANTLRHashMap );
}
+(id)newANTLRHashMapWithLen:(NSInteger)aBuffSize
{
ANTLRHashMap *aNewANTLRHashMap;
aNewANTLRHashMap = [[ANTLRHashMap alloc] initWithLen:aBuffSize];
return( aNewANTLRHashMap );
}
-(id)init
{
NSInteger idx;
if ((self = [super init]) != nil) {
fNext = nil;
BuffSize = HASHSIZE;
Scope = 0;
if ( fNext != nil ) {
Scope = ((ANTLRHashMap *)fNext)->Scope+1;
for( idx = 0; idx < BuffSize; idx++ ) {
ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx];
}
}
mode = 0;
}
return( self );
}
-(id)initWithLen:(NSInteger)aBuffSize
{
NSInteger idx;
if ((self = [super init]) != nil) {
fNext = nil;
BuffSize = aBuffSize;
Scope = 0;
if ( fNext != nil ) {
Scope = ((ANTLRHashMap *)fNext)->Scope+1;
for( idx = 0; idx < BuffSize; idx++ ) {
ptrBuffer[idx] = ((ANTLRHashMap *)fNext)->ptrBuffer[idx];
}
}
mode = 0;
}
return( self );
}
-(void)dealloc
{
ANTLRMapElement *tmp, *rtmp;
NSInteger idx;
if ( self.fNext != nil ) {
for( idx = 0; idx < BuffSize; idx++ ) {
tmp = ptrBuffer[idx];
while ( tmp && tmp != [((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
rtmp = tmp;
// tmp = [tmp getfNext];
tmp = (ANTLRMapElement *)tmp.fNext;
[rtmp dealloc];
}
}
}
[super dealloc];
}
- (NSInteger)count
{
id anElement;
NSInteger aCnt = 0;
for (NSInteger i = 0; i < BuffSize; i++) {
if ((anElement = ptrBuffer[i]) != nil) {
aCnt++;
}
}
return aCnt;
}
- (NSInteger) size
{
id anElement;
NSInteger aSize = 0;
for (NSInteger i = 0; i < BuffSize; i++) {
if ((anElement = ptrBuffer[i]) != nil) {
aSize += sizeof(id);
}
}
return aSize;
}
-(void)deleteANTLRHashMap:(ANTLRMapElement *)np
{
ANTLRMapElement *tmp, *rtmp;
NSInteger idx;
if ( self.fNext != nil ) {
for( idx = 0; idx < BuffSize; idx++ ) {
tmp = ptrBuffer[idx];
while ( tmp && tmp != (ANTLRLinkBase *)[((ANTLRHashMap *)fNext) getptrBufferEntry:idx] ) {
rtmp = tmp;
tmp = [tmp getfNext];
[rtmp dealloc];
}
}
}
}
-(ANTLRHashMap *)PushScope:(ANTLRHashMap **)map
{
NSInteger idx;
ANTLRHashMap *htmp;
htmp = [ANTLRHashMap newANTLRHashMap];
if ( *map != nil ) {
((ANTLRHashMap *)htmp)->fNext = *map;
[htmp setScope:[((ANTLRHashMap *)htmp->fNext) getScope]+1];
for( idx = 0; idx < BuffSize; idx++ ) {
htmp->ptrBuffer[idx] = ((ANTLRHashMap *)htmp->fNext)->ptrBuffer[idx];
}
}
// gScopeLevel++;
*map = htmp;
return( htmp );
}
-(ANTLRHashMap *)PopScope:(ANTLRHashMap **)map
{
NSInteger idx;
ANTLRMapElement *tmp;
ANTLRHashMap *htmp;
htmp = *map;
if ( (*map)->fNext != nil ) {
*map = (ANTLRHashMap *)htmp->fNext;
for( idx = 0; idx < BuffSize; idx++ ) {
if ( htmp->ptrBuffer[idx] == nil ||
htmp->ptrBuffer[idx] == (*map)->ptrBuffer[idx] ) {
break;
}
tmp = htmp->ptrBuffer[idx];
/*
* must deal with parms, locals and labels at some point
* can not forget the debuggers
*/
htmp->ptrBuffer[idx] = [tmp getfNext];
[ tmp dealloc];
}
*map = (ANTLRHashMap *)htmp->fNext;
// gScopeLevel--;
}
return( htmp );
}
#ifdef USERDOC
/*
* HASH hash entry to get index to table
* NSInteger hash( ANTLRHashMap *self, char *s );
*
* Inputs: char *s string to find
*
* Returns: NSInteger hashed value
*
* Last Revision 9/03/90
*/
#endif
-(NSInteger)hash:(NSString *)s /* form hash value for string s */
{
NSInteger hashval;
const char *tmp;
tmp = [s cStringUsingEncoding:NSASCIIStringEncoding];
for( hashval = 0; *tmp != '\0'; )
hashval += *tmp++;
self->LastHash = hashval % BuffSize;
return( self->LastHash );
}
#ifdef USERDOC
/*
* FINDSCOPE search hashed list for entry
* ANTLRHashMap *findscope( ANTLRHashMap *self, NSInteger scope );
*
* Inputs: NSInteger scope -- scope level to find
*
* Returns: ANTLRHashMap pointer to ptrBuffer of proper scope level
*
* Last Revision 9/03/90
*/
#endif
-(ANTLRHashMap *)findscope:(NSInteger)scope
{
if ( self->Scope == scope ) {
return( self );
}
else if ( fNext ) {
return( [((ANTLRHashMap *)fNext) findscope:scope] );
}
return( nil ); /* not found */
}
#ifdef USERDOC
/*
* LOOKUP search hashed list for entry
* ANTLRMapElement *lookup( ANTLRHashMap *self, char *s, NSInteger scope );
*
* Inputs: char *s string to find
*
* Returns: ANTLRMapElement * pointer to entry
*
* Last Revision 9/03/90
*/
#endif
-(id)lookup:(NSString *)s Scope:(NSInteger)scope
{
ANTLRMapElement *np;
for( np = self->ptrBuffer[[self hash:s]]; np != nil; np = [np getfNext] ) {
if ( [s isEqualToString:[np getName]] ) {
return( np ); /* found it */
}
}
return( nil ); /* not found */
}
#ifdef USERDOC
/*
* INSTALL search hashed list for entry
* NSInteger install( ANTLRHashMap *self, ANTLRMapElement *sym, NSInteger scope );
*
* Inputs: ANTLRMapElement *sym -- symbol ptr to install
* NSInteger scope -- level to find
*
* Returns: Boolean TRUE if installed
* FALSE if already in table
*
* Last Revision 9/03/90
*/
#endif
-(ANTLRMapElement *)install:(ANTLRMapElement *)sym Scope:(NSInteger)scope
{
ANTLRMapElement *np;
np = [self lookup:[sym getName] Scope:scope ];
if ( np == nil ) {
[sym retain];
[sym setFNext:self->ptrBuffer[ self->LastHash ]];
self->ptrBuffer[ self->LastHash ] = sym;
return( self->ptrBuffer[ self->LastHash ] );
}
return( nil ); /* not found */
}
#ifdef USERDOC
/*
* RemoveSym search hashed list for entry
* NSInteger RemoveSym( ANTLRHashMap *self, char *s );
*
* Inputs: char *s string to find
*
* Returns: NSInteger indicator of SUCCESS OR FAILURE
*
* Last Revision 9/03/90
*/
#endif
-(NSInteger)RemoveSym:(NSString *)s
{
ANTLRMapElement *np, *tmp;
NSInteger idx;
idx = [self hash:s];
for ( tmp = self->ptrBuffer[idx], np = self->ptrBuffer[idx]; np != nil; np = [np getfNext] ) {
if ( [s isEqualToString:[np getName]] ) {
tmp = [np getfNext]; /* get the next link */
[np dealloc];
return( SUCCESS ); /* report SUCCESS */
}
tmp = [np getfNext]; // BAD!!!!!!
}
return( FAILURE ); /* not found */
}
-(void)delete_chain:(ANTLRMapElement *)np
{
if ( [np getfNext] != nil )
[self delete_chain:[np getfNext]];
[np dealloc];
}
#ifdef DONTUSEYET
-(NSInteger)bld_symtab:(KW_TABLE *)toknams
{
NSInteger i;
ANTLRMapElement *np;
for( i = 0; *(toknams[i].name) != '\0'; i++ ) {
// install symbol in ptrBuffer
np = [ANTLRMapElement newANTLRMapElement:[NSString stringWithFormat:@"%s", toknams[i].name]];
// np->fType = toknams[i].toknum;
[self install:np Scope:0];
}
return( SUCCESS );
}
#endif
-(ANTLRMapElement *)getptrBufferEntry:(NSInteger)idx
{
return( ptrBuffer[idx] );
}
-(ANTLRMapElement **)getptrBuffer
{
return( ptrBuffer );
}
-(void)setptrBuffer:(ANTLRMapElement *)np Index:(NSInteger)idx
{
if ( idx < BuffSize ) {
[np retain];
ptrBuffer[idx] = np;
}
}
-(NSInteger)getScope
{
return( Scope );
}
-(void)setScopeScope:(NSInteger)i
{
Scope = i;
}
- (ANTLRMapElement *)getTType:(NSString *)name
{
return [self lookup:name Scope:0];
}
/*
* works only for maplist indexed not by name but by TokenNumber
*/
- (ANTLRMapElement *)getNameInList:(NSInteger)ttype
{
ANTLRMapElement *np;
NSInteger aTType;
aTType = ttype % BuffSize;
for( np = self->ptrBuffer[ttype]; np != nil; np = [np getfNext] ) {
if ( [np.index integerValue] == ttype ) {
return( np ); /* found it */
}
}
return( nil ); /* not found */
}
- (ANTLRLinkBase *)getName:(NSString *)name
{
return [self lookup:name Scope:0]; /* nil if not found */
}
- (void)putNode:(NSString *)name TokenType:(NSInteger)ttype
{
ANTLRMapElement *np;
// install symbol in ptrBuffer
np = [ANTLRMapElement newANTLRMapElementWithName:[NSString stringWithString:name] Type:ttype];
// np->fType = toknams[i].toknum;
[self install:np Scope:0];
}
- (NSInteger)getMode
{
return mode;
}
- (void)setMode:(NSInteger)aMode
{
mode = aMode;
}
- (void) addObject:(id)aRule
{
NSInteger idx;
idx = [self count];
if ( idx >= BuffSize ) {
idx %= BuffSize;
}
ptrBuffer[idx] = aRule;
}
/* this may have to handle linking into the chain
*/
- (void) insertObject:(id)aRule atIndex:(NSInteger)idx
{
if ( idx >= BuffSize ) {
idx %= BuffSize;
}
if (aRule != ptrBuffer[idx]) {
if (ptrBuffer[idx] != nil) [ptrBuffer[idx] release];
[aRule retain];
}
ptrBuffer[idx] = aRule;
}
- (id)objectAtIndex:(NSInteger)idx
{
if ( idx >= BuffSize ) {
idx %= BuffSize;
}
return ptrBuffer[idx];
}
/* this will never link into the chain
*/
- (void) setObject:(id)aRule atIndex:(NSInteger)idx
{
if ( idx >= BuffSize ) {
idx %= BuffSize;
}
if (aRule != ptrBuffer[idx]) {
if (ptrBuffer[idx] != nil) [ptrBuffer[idx] release];
[aRule retain];
}
ptrBuffer[idx] = aRule;
}
- (void)putName:(NSString *)name Node:(id)aNode
{
ANTLRMapElement *np;
np = [self lookup:name Scope:0 ];
if ( np == nil ) {
np = [ANTLRMapElement newANTLRMapElementWithName:name Node:aNode];
if (ptrBuffer[LastHash] != nil)
[ptrBuffer[LastHash] release];
[np retain];
np.fNext = ptrBuffer[ LastHash ];
ptrBuffer[ LastHash ] = np;
}
return;
}
- (NSEnumerator *)objectEnumerator
{
NSEnumerator *anEnumerator;
itIndex = 0;
return anEnumerator;
}
- (BOOL)hasNext
{
if (self && [self count] < BuffSize-1) {
return YES;
}
return NO;
}
- (ANTLRMapElement *)nextObject
{
if (self && itIndex < BuffSize-1) {
return ptrBuffer[itIndex];
}
return nil;
}
@end