1*16467b97STreehugger Robot// 2*16467b97STreehugger Robot// BufferedTreeNodeStream.m 3*16467b97STreehugger Robot// ANTLR 4*16467b97STreehugger Robot// 5*16467b97STreehugger Robot// [The "BSD licence"] 6*16467b97STreehugger Robot// Copyright (c) 2010 Ian Michell 2010 Alan Condit 7*16467b97STreehugger Robot// All rights reserved. 8*16467b97STreehugger Robot// 9*16467b97STreehugger Robot// Redistribution and use in source and binary forms, with or without 10*16467b97STreehugger Robot// modification, are permitted provided that the following conditions 11*16467b97STreehugger Robot// are met: 12*16467b97STreehugger Robot// 1. Redistributions of source code must retain the above copyright 13*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer. 14*16467b97STreehugger Robot// 2. Redistributions in binary form must reproduce the above copyright 15*16467b97STreehugger Robot// notice, this list of conditions and the following disclaimer in the 16*16467b97STreehugger Robot// documentation and/or other materials provided with the distribution. 17*16467b97STreehugger Robot// 3. The name of the author may not be used to endorse or promote products 18*16467b97STreehugger Robot// derived from this software without specific prior written permission. 19*16467b97STreehugger Robot// 20*16467b97STreehugger Robot// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21*16467b97STreehugger Robot// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22*16467b97STreehugger Robot// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23*16467b97STreehugger Robot// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24*16467b97STreehugger Robot// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25*16467b97STreehugger Robot// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*16467b97STreehugger Robot// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*16467b97STreehugger Robot// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*16467b97STreehugger Robot// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29*16467b97STreehugger Robot// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*16467b97STreehugger Robot 31*16467b97STreehugger Robot#import "BufferedTreeNodeStream.h" 32*16467b97STreehugger Robot#import "StreamEnumerator.h" 33*16467b97STreehugger Robot#import "CommonTreeAdaptor.h" 34*16467b97STreehugger Robot 35*16467b97STreehugger Robotextern NSInteger debug; 36*16467b97STreehugger Robot 37*16467b97STreehugger Robot#ifdef DONTUSENOMO 38*16467b97STreehugger Robot@implementation TreeStreamIterator 39*16467b97STreehugger Robot+ newTreeStreamIteratorWithNodes:(BufferedTreeNodeStream *)theStream 40*16467b97STreehugger Robot{ 41*16467b97STreehugger Robot return[[TreeStreamIterator alloc] initWithStream:theStream]; 42*16467b97STreehugger Robot} 43*16467b97STreehugger Robot 44*16467b97STreehugger Robot- (id) initWithStream:(BufferedTreeNodeStream *)theStream 45*16467b97STreehugger Robot{ 46*16467b97STreehugger Robot if ((self = [super init]) != nil) { 47*16467b97STreehugger Robot idx = 0; 48*16467b97STreehugger Robot input = theStream; 49*16467b97STreehugger Robot nodes = [theStream getNodes]; 50*16467b97STreehugger Robot } 51*16467b97STreehugger Robot return self; 52*16467b97STreehugger Robot} 53*16467b97STreehugger Robot 54*16467b97STreehugger Robot- (BOOL) hasNext 55*16467b97STreehugger Robot{ 56*16467b97STreehugger Robot return idx < [nodes count]; 57*16467b97STreehugger Robot} 58*16467b97STreehugger Robot 59*16467b97STreehugger Robot- (id) next 60*16467b97STreehugger Robot{ 61*16467b97STreehugger Robot NSInteger current = idx; 62*16467b97STreehugger Robot idx++; 63*16467b97STreehugger Robot if (current < [nodes count]) { 64*16467b97STreehugger Robot } 65*16467b97STreehugger Robot return [nodes getEof]; 66*16467b97STreehugger Robot} 67*16467b97STreehugger Robot 68*16467b97STreehugger Robot- (void) remove 69*16467b97STreehugger Robot{ 70*16467b97STreehugger Robot @throw [RuntimeException newException:@"cannot remove nodes from stream"]; 71*16467b97STreehugger Robot} 72*16467b97STreehugger Robot 73*16467b97STreehugger Robot@end 74*16467b97STreehugger Robot#endif 75*16467b97STreehugger Robot 76*16467b97STreehugger Robot@implementation BufferedTreeNodeStream 77*16467b97STreehugger Robot 78*16467b97STreehugger Robot@synthesize up; 79*16467b97STreehugger Robot@synthesize down; 80*16467b97STreehugger Robot@synthesize eof; 81*16467b97STreehugger Robot@synthesize nodes; 82*16467b97STreehugger Robot@synthesize root; 83*16467b97STreehugger Robot@synthesize tokens; 84*16467b97STreehugger Robot@synthesize adaptor; 85*16467b97STreehugger Robot@synthesize uniqueNavigationNodes; 86*16467b97STreehugger Robot@synthesize index; 87*16467b97STreehugger Robot@synthesize lastMarker; 88*16467b97STreehugger Robot@synthesize calls; 89*16467b97STreehugger Robot@synthesize e; 90*16467b97STreehugger Robot@synthesize currentSymbol; 91*16467b97STreehugger Robot 92*16467b97STreehugger Robot+ (BufferedTreeNodeStream *) newBufferedTreeNodeStream:(CommonTree *) aTree 93*16467b97STreehugger Robot{ 94*16467b97STreehugger Robot return [((BufferedTreeNodeStream *)[BufferedTreeNodeStream alloc]) initWithTree:(CommonTree *)aTree]; 95*16467b97STreehugger Robot} 96*16467b97STreehugger Robot 97*16467b97STreehugger Robot+ (BufferedTreeNodeStream *) newBufferedTreeNodeStream:(id<TreeAdaptor>)adaptor Tree:(CommonTree *)aTree 98*16467b97STreehugger Robot{ 99*16467b97STreehugger Robot return [[BufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(CommonTree *)aTree]; 100*16467b97STreehugger Robot} 101*16467b97STreehugger Robot 102*16467b97STreehugger Robot+ (BufferedTreeNodeStream *) newBufferedTreeNodeStream:(id<TreeAdaptor>)adaptor Tree:(CommonTree *)aTree withBufferSize:(NSInteger)initialBufferSize 103*16467b97STreehugger Robot{ 104*16467b97STreehugger Robot return [[BufferedTreeNodeStream alloc] initWithTreeAdaptor:adaptor Tree:(CommonTree *)aTree WithBufferSize:initialBufferSize]; 105*16467b97STreehugger Robot} 106*16467b97STreehugger Robot 107*16467b97STreehugger Robot-(BufferedTreeNodeStream *) init 108*16467b97STreehugger Robot{ 109*16467b97STreehugger Robot self = [super init]; 110*16467b97STreehugger Robot if (self) { 111*16467b97STreehugger Robot index = -1; 112*16467b97STreehugger Robot uniqueNavigationNodes = NO; 113*16467b97STreehugger Robot root = [[CommonTree alloc] init]; 114*16467b97STreehugger Robot // tokens = tree; 115*16467b97STreehugger Robot adaptor = [[[CommonTreeAdaptor alloc] init] retain]; 116*16467b97STreehugger Robot nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 117*16467b97STreehugger Robot down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain]; 118*16467b97STreehugger Robot up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain]; 119*16467b97STreehugger Robot eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain]; 120*16467b97STreehugger Robot } 121*16467b97STreehugger Robot return self; 122*16467b97STreehugger Robot} 123*16467b97STreehugger Robot 124*16467b97STreehugger Robot- (BufferedTreeNodeStream *)initWithTree:(CommonTree *) aTree 125*16467b97STreehugger Robot{ 126*16467b97STreehugger Robot self = [super init]; 127*16467b97STreehugger Robot if (self) { 128*16467b97STreehugger Robot index = -1; 129*16467b97STreehugger Robot uniqueNavigationNodes = NO; 130*16467b97STreehugger Robot root = aTree; 131*16467b97STreehugger Robot // tokens = aTree; 132*16467b97STreehugger Robot adaptor = [[[CommonTreeAdaptor alloc] init] retain]; 133*16467b97STreehugger Robot nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 134*16467b97STreehugger Robot down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain]; 135*16467b97STreehugger Robot up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain]; 136*16467b97STreehugger Robot eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain]; 137*16467b97STreehugger Robot } 138*16467b97STreehugger Robot return self; 139*16467b97STreehugger Robot} 140*16467b97STreehugger Robot 141*16467b97STreehugger Robot-(BufferedTreeNodeStream *) initWithTreeAdaptor:(CommonTreeAdaptor *)anAdaptor Tree:(CommonTree *)aTree 142*16467b97STreehugger Robot{ 143*16467b97STreehugger Robot self = [super init]; 144*16467b97STreehugger Robot if (self) { 145*16467b97STreehugger Robot index = -1; 146*16467b97STreehugger Robot uniqueNavigationNodes = NO; 147*16467b97STreehugger Robot root = aTree; 148*16467b97STreehugger Robot // tokens = aTree; 149*16467b97STreehugger Robot adaptor = [anAdaptor retain]; 150*16467b97STreehugger Robot nodes = [[AMutableArray arrayWithCapacity:DEFAULT_INITIAL_BUFFER_SIZE] retain]; 151*16467b97STreehugger Robot down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain]; 152*16467b97STreehugger Robot up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain]; 153*16467b97STreehugger Robot eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain]; 154*16467b97STreehugger Robot } 155*16467b97STreehugger Robot return self; 156*16467b97STreehugger Robot} 157*16467b97STreehugger Robot 158*16467b97STreehugger Robot-(BufferedTreeNodeStream *) initWithTreeAdaptor:(CommonTreeAdaptor *)anAdaptor Tree:(CommonTree *)aTree WithBufferSize:(NSInteger)bufferSize 159*16467b97STreehugger Robot{ 160*16467b97STreehugger Robot self = [super init]; 161*16467b97STreehugger Robot if (self) { 162*16467b97STreehugger Robot // down = [adaptor createToken:TokenTypeDOWN withText:@"DOWN"]; 163*16467b97STreehugger Robot // up = [adaptor createToken:TokenTypeDOWN withText:@"UP"]; 164*16467b97STreehugger Robot // eof = [adaptor createToken:TokenTypeDOWN withText:@"EOF"]; 165*16467b97STreehugger Robot index = -1; 166*16467b97STreehugger Robot uniqueNavigationNodes = NO; 167*16467b97STreehugger Robot root = aTree; 168*16467b97STreehugger Robot // tokens = aTree; 169*16467b97STreehugger Robot adaptor = [anAdaptor retain]; 170*16467b97STreehugger Robot nodes = [[AMutableArray arrayWithCapacity:bufferSize] retain]; 171*16467b97STreehugger Robot down = [[adaptor createTree:TokenTypeDOWN Text:@"DOWN"] retain]; 172*16467b97STreehugger Robot up = [[adaptor createTree:TokenTypeUP Text:@"UP"] retain]; 173*16467b97STreehugger Robot eof = [[adaptor createTree:TokenTypeEOF Text:@"EOF"] retain]; 174*16467b97STreehugger Robot } 175*16467b97STreehugger Robot return self; 176*16467b97STreehugger Robot} 177*16467b97STreehugger Robot 178*16467b97STreehugger Robot- (void)dealloc 179*16467b97STreehugger Robot{ 180*16467b97STreehugger Robot#ifdef DEBUG_DEALLOC 181*16467b97STreehugger Robot NSLog( @"called dealloc in BufferedTreeNodeStream" ); 182*16467b97STreehugger Robot#endif 183*16467b97STreehugger Robot if ( adaptor ) [adaptor release]; 184*16467b97STreehugger Robot if ( nodes ) [nodes release]; 185*16467b97STreehugger Robot if ( root ) [root release]; 186*16467b97STreehugger Robot if ( down ) [down release]; 187*16467b97STreehugger Robot if ( up ) [up release]; 188*16467b97STreehugger Robot if ( eof ) [eof release]; 189*16467b97STreehugger Robot [super dealloc]; 190*16467b97STreehugger Robot} 191*16467b97STreehugger Robot 192*16467b97STreehugger Robot- (id) copyWithZone:(NSZone *)aZone 193*16467b97STreehugger Robot{ 194*16467b97STreehugger Robot BufferedTreeNodeStream *copy; 195*16467b97STreehugger Robot 196*16467b97STreehugger Robot copy = [[[self class] allocWithZone:aZone] init]; 197*16467b97STreehugger Robot if ( up ) 198*16467b97STreehugger Robot copy.up = [up copyWithZone:aZone]; 199*16467b97STreehugger Robot if ( down ) 200*16467b97STreehugger Robot copy.down = [down copyWithZone:aZone]; 201*16467b97STreehugger Robot if ( eof ) 202*16467b97STreehugger Robot copy.eof = [eof copyWithZone:aZone]; 203*16467b97STreehugger Robot if ( nodes ) 204*16467b97STreehugger Robot copy.nodes = [nodes copyWithZone:aZone]; 205*16467b97STreehugger Robot if ( root ) 206*16467b97STreehugger Robot copy.root = [root copyWithZone:aZone]; 207*16467b97STreehugger Robot if ( tokens ) 208*16467b97STreehugger Robot copy.tokens = [tokens copyWithZone:aZone]; 209*16467b97STreehugger Robot if ( adaptor ) 210*16467b97STreehugger Robot copy.adaptor = [adaptor copyWithZone:aZone]; 211*16467b97STreehugger Robot copy.uniqueNavigationNodes = self.uniqueNavigationNodes; 212*16467b97STreehugger Robot copy.index = self.index; 213*16467b97STreehugger Robot copy.lastMarker = self.lastMarker; 214*16467b97STreehugger Robot if ( calls ) 215*16467b97STreehugger Robot copy.calls = [calls copyWithZone:aZone]; 216*16467b97STreehugger Robot return copy; 217*16467b97STreehugger Robot} 218*16467b97STreehugger Robot 219*16467b97STreehugger Robot// protected methods. DO NOT USE 220*16467b97STreehugger Robot#pragma mark Protected Methods 221*16467b97STreehugger Robot-(void) fillBuffer 222*16467b97STreehugger Robot{ 223*16467b97STreehugger Robot [self fillBufferWithTree:root]; 224*16467b97STreehugger Robot // if (debug > 1) NSLog("revIndex=%@", tokenTypeToStreamIndexesMap); 225*16467b97STreehugger Robot index = 0; // buffer of nodes intialized now 226*16467b97STreehugger Robot} 227*16467b97STreehugger Robot 228*16467b97STreehugger Robot-(void) fillBufferWithTree:(CommonTree *) aTree 229*16467b97STreehugger Robot{ 230*16467b97STreehugger Robot BOOL empty = [adaptor isNil:(id<BaseTree>)aTree]; 231*16467b97STreehugger Robot if (!empty) { 232*16467b97STreehugger Robot [nodes addObject:aTree]; 233*16467b97STreehugger Robot } 234*16467b97STreehugger Robot NSInteger n = [adaptor getChildCount:aTree]; 235*16467b97STreehugger Robot if (!empty && n > 0) { 236*16467b97STreehugger Robot [self addNavigationNode:TokenTypeDOWN]; 237*16467b97STreehugger Robot } 238*16467b97STreehugger Robot for (NSInteger c = 0; c < n; c++) { 239*16467b97STreehugger Robot id child = [adaptor getChild:aTree At:c]; 240*16467b97STreehugger Robot [self fillBufferWithTree:child]; 241*16467b97STreehugger Robot } 242*16467b97STreehugger Robot if (!empty && n > 0) { 243*16467b97STreehugger Robot [self addNavigationNode:TokenTypeUP]; 244*16467b97STreehugger Robot } 245*16467b97STreehugger Robot} 246*16467b97STreehugger Robot 247*16467b97STreehugger Robot-(NSInteger) getNodeIndex:(CommonTree *) node 248*16467b97STreehugger Robot{ 249*16467b97STreehugger Robot if (index == -1) { 250*16467b97STreehugger Robot [self fillBuffer]; 251*16467b97STreehugger Robot } 252*16467b97STreehugger Robot for (NSUInteger i = 0; i < [nodes count]; i++) { 253*16467b97STreehugger Robot id t = [nodes objectAtIndex:i]; 254*16467b97STreehugger Robot if (t == node) { 255*16467b97STreehugger Robot return i; 256*16467b97STreehugger Robot } 257*16467b97STreehugger Robot } 258*16467b97STreehugger Robot return -1; 259*16467b97STreehugger Robot} 260*16467b97STreehugger Robot 261*16467b97STreehugger Robot-(void) addNavigationNode:(NSInteger) type 262*16467b97STreehugger Robot{ 263*16467b97STreehugger Robot id navNode = nil; 264*16467b97STreehugger Robot if (type == TokenTypeDOWN) { 265*16467b97STreehugger Robot if (self.uniqueNavigationNodes) { 266*16467b97STreehugger Robot navNode = [adaptor createToken:TokenTypeDOWN Text:@"DOWN"]; 267*16467b97STreehugger Robot } 268*16467b97STreehugger Robot else { 269*16467b97STreehugger Robot navNode = down; 270*16467b97STreehugger Robot } 271*16467b97STreehugger Robot 272*16467b97STreehugger Robot } 273*16467b97STreehugger Robot else { 274*16467b97STreehugger Robot if (self.uniqueNavigationNodes) { 275*16467b97STreehugger Robot navNode = [adaptor createToken:TokenTypeUP Text:@"UP"]; 276*16467b97STreehugger Robot } 277*16467b97STreehugger Robot else { 278*16467b97STreehugger Robot navNode = up; 279*16467b97STreehugger Robot } 280*16467b97STreehugger Robot } 281*16467b97STreehugger Robot [nodes addObject:navNode]; 282*16467b97STreehugger Robot} 283*16467b97STreehugger Robot 284*16467b97STreehugger Robot-(id) get:(NSUInteger) i 285*16467b97STreehugger Robot{ 286*16467b97STreehugger Robot if (index == -1) { 287*16467b97STreehugger Robot [self fillBuffer]; 288*16467b97STreehugger Robot } 289*16467b97STreehugger Robot return [nodes objectAtIndex:i]; 290*16467b97STreehugger Robot} 291*16467b97STreehugger Robot 292*16467b97STreehugger Robot-(id) LT:(NSInteger) k 293*16467b97STreehugger Robot{ 294*16467b97STreehugger Robot if (index == -1) { 295*16467b97STreehugger Robot [self fillBuffer]; 296*16467b97STreehugger Robot } 297*16467b97STreehugger Robot if (k == 0) { 298*16467b97STreehugger Robot return nil; 299*16467b97STreehugger Robot } 300*16467b97STreehugger Robot if (k < 0) { 301*16467b97STreehugger Robot return [self LB:-k]; 302*16467b97STreehugger Robot } 303*16467b97STreehugger Robot if ((index + k - 1) >= [nodes count]) { 304*16467b97STreehugger Robot return eof; 305*16467b97STreehugger Robot } 306*16467b97STreehugger Robot return [nodes objectAtIndex:(index + k - 1)]; 307*16467b97STreehugger Robot} 308*16467b97STreehugger Robot 309*16467b97STreehugger Robot-(id) getCurrentSymbol 310*16467b97STreehugger Robot{ 311*16467b97STreehugger Robot return [self LT:1]; 312*16467b97STreehugger Robot} 313*16467b97STreehugger Robot 314*16467b97STreehugger Robot-(id) LB:(NSInteger) k 315*16467b97STreehugger Robot{ 316*16467b97STreehugger Robot if (k == 0) { 317*16467b97STreehugger Robot return nil; 318*16467b97STreehugger Robot } 319*16467b97STreehugger Robot if ((index - k) < 0) { 320*16467b97STreehugger Robot return nil; 321*16467b97STreehugger Robot } 322*16467b97STreehugger Robot return [nodes objectAtIndex:(index - k)]; 323*16467b97STreehugger Robot} 324*16467b97STreehugger Robot 325*16467b97STreehugger Robot- (CommonTree *)getTreeSource 326*16467b97STreehugger Robot{ 327*16467b97STreehugger Robot return root; 328*16467b97STreehugger Robot} 329*16467b97STreehugger Robot 330*16467b97STreehugger Robot-(NSString *)getSourceName 331*16467b97STreehugger Robot{ 332*16467b97STreehugger Robot return [[self getTokenStream] getSourceName]; 333*16467b97STreehugger Robot} 334*16467b97STreehugger Robot 335*16467b97STreehugger Robot- (id<TokenStream>)getTokenStream 336*16467b97STreehugger Robot{ 337*16467b97STreehugger Robot return tokens; 338*16467b97STreehugger Robot} 339*16467b97STreehugger Robot 340*16467b97STreehugger Robot- (void) setTokenStream:(id<TokenStream>)newtokens 341*16467b97STreehugger Robot{ 342*16467b97STreehugger Robot tokens = newtokens; 343*16467b97STreehugger Robot} 344*16467b97STreehugger Robot 345*16467b97STreehugger Robot- (id<TreeAdaptor>)getTreeAdaptor 346*16467b97STreehugger Robot{ 347*16467b97STreehugger Robot return adaptor; 348*16467b97STreehugger Robot} 349*16467b97STreehugger Robot 350*16467b97STreehugger Robot- (void) setTreeAdaptor:(id<TreeAdaptor>)anAdaptor 351*16467b97STreehugger Robot{ 352*16467b97STreehugger Robot adaptor = anAdaptor; 353*16467b97STreehugger Robot} 354*16467b97STreehugger Robot 355*16467b97STreehugger Robot- (BOOL)getUniqueNavigationNodes 356*16467b97STreehugger Robot{ 357*16467b97STreehugger Robot return uniqueNavigationNodes; 358*16467b97STreehugger Robot} 359*16467b97STreehugger Robot 360*16467b97STreehugger Robot- (void) setUniqueNavigationNodes:(BOOL)aVal 361*16467b97STreehugger Robot{ 362*16467b97STreehugger Robot uniqueNavigationNodes = aVal; 363*16467b97STreehugger Robot} 364*16467b97STreehugger Robot 365*16467b97STreehugger Robot-(void) consume 366*16467b97STreehugger Robot{ 367*16467b97STreehugger Robot if (index == -1) { 368*16467b97STreehugger Robot [self fillBuffer]; 369*16467b97STreehugger Robot } 370*16467b97STreehugger Robot index++; 371*16467b97STreehugger Robot} 372*16467b97STreehugger Robot 373*16467b97STreehugger Robot-(NSInteger) LA:(NSInteger) i 374*16467b97STreehugger Robot{ 375*16467b97STreehugger Robot return [adaptor getType:[self LT:i]]; 376*16467b97STreehugger Robot} 377*16467b97STreehugger Robot 378*16467b97STreehugger Robot-(NSInteger) mark 379*16467b97STreehugger Robot{ 380*16467b97STreehugger Robot if (index == -1) { 381*16467b97STreehugger Robot [self fillBuffer]; 382*16467b97STreehugger Robot } 383*16467b97STreehugger Robot lastMarker = self.index; 384*16467b97STreehugger Robot return lastMarker; 385*16467b97STreehugger Robot} 386*16467b97STreehugger Robot 387*16467b97STreehugger Robot-(void) release:(NSInteger) marker 388*16467b97STreehugger Robot{ 389*16467b97STreehugger Robot // do nothing 390*16467b97STreehugger Robot} 391*16467b97STreehugger Robot 392*16467b97STreehugger Robot-(void) rewind:(NSInteger) marker 393*16467b97STreehugger Robot{ 394*16467b97STreehugger Robot [self seek:marker]; 395*16467b97STreehugger Robot} 396*16467b97STreehugger Robot 397*16467b97STreehugger Robot-(void) rewind 398*16467b97STreehugger Robot{ 399*16467b97STreehugger Robot [self seek:lastMarker]; 400*16467b97STreehugger Robot} 401*16467b97STreehugger Robot 402*16467b97STreehugger Robot-(void) seek:(NSInteger) i 403*16467b97STreehugger Robot{ 404*16467b97STreehugger Robot if (index == -1) { 405*16467b97STreehugger Robot [self fillBuffer]; 406*16467b97STreehugger Robot } 407*16467b97STreehugger Robot index = i; 408*16467b97STreehugger Robot} 409*16467b97STreehugger Robot 410*16467b97STreehugger Robot-(void) push:(NSInteger) i 411*16467b97STreehugger Robot{ 412*16467b97STreehugger Robot if (calls == nil) { 413*16467b97STreehugger Robot calls = [IntArray newArrayWithLen:INITIAL_CALL_STACK_SIZE]; 414*16467b97STreehugger Robot } 415*16467b97STreehugger Robot [calls push:index]; 416*16467b97STreehugger Robot [self seek:i]; 417*16467b97STreehugger Robot} 418*16467b97STreehugger Robot 419*16467b97STreehugger Robot-(NSInteger) pop 420*16467b97STreehugger Robot{ 421*16467b97STreehugger Robot NSInteger ret = [calls pop]; 422*16467b97STreehugger Robot [self seek:ret]; 423*16467b97STreehugger Robot return ret; 424*16467b97STreehugger Robot} 425*16467b97STreehugger Robot 426*16467b97STreehugger Robot-(void) reset 427*16467b97STreehugger Robot{ 428*16467b97STreehugger Robot index = 0; 429*16467b97STreehugger Robot lastMarker = 0; 430*16467b97STreehugger Robot if (calls != nil) { 431*16467b97STreehugger Robot [calls reset]; 432*16467b97STreehugger Robot } 433*16467b97STreehugger Robot} 434*16467b97STreehugger Robot 435*16467b97STreehugger Robot-(NSUInteger) count 436*16467b97STreehugger Robot{ 437*16467b97STreehugger Robot if (index == -1) { 438*16467b97STreehugger Robot [self fillBuffer]; 439*16467b97STreehugger Robot } 440*16467b97STreehugger Robot return [nodes count]; 441*16467b97STreehugger Robot} 442*16467b97STreehugger Robot 443*16467b97STreehugger Robot-(NSUInteger) size 444*16467b97STreehugger Robot{ 445*16467b97STreehugger Robot return [self count]; 446*16467b97STreehugger Robot} 447*16467b97STreehugger Robot 448*16467b97STreehugger Robot-(NSEnumerator *) objectEnumerator 449*16467b97STreehugger Robot{ 450*16467b97STreehugger Robot if (e == nil) { 451*16467b97STreehugger Robot e = [[StreamEnumerator alloc] initWithNodes:nodes andEOF:eof]; 452*16467b97STreehugger Robot } 453*16467b97STreehugger Robot return e; 454*16467b97STreehugger Robot} 455*16467b97STreehugger Robot 456*16467b97STreehugger Robot-(void) replaceChildren:(CommonTree *) parent From:(NSInteger)startIdx To:(NSInteger)stopIdx With:(CommonTree *)aTree 457*16467b97STreehugger Robot{ 458*16467b97STreehugger Robot if (parent != nil) { 459*16467b97STreehugger Robot [adaptor replaceChildren:parent From:startIdx To:stopIdx With:aTree]; 460*16467b97STreehugger Robot } 461*16467b97STreehugger Robot} 462*16467b97STreehugger Robot 463*16467b97STreehugger Robot-(NSString *) toTokenTypeString 464*16467b97STreehugger Robot{ 465*16467b97STreehugger Robot if (index == -1) 466*16467b97STreehugger Robot { 467*16467b97STreehugger Robot [self fillBuffer]; 468*16467b97STreehugger Robot } 469*16467b97STreehugger Robot NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 470*16467b97STreehugger Robot for (NSUInteger i= 0; i < [nodes count]; i++) { 471*16467b97STreehugger Robot CommonTree * aTree = (CommonTree *)[self get:i]; 472*16467b97STreehugger Robot [buf appendFormat:@" %d", [adaptor getType:aTree]]; 473*16467b97STreehugger Robot } 474*16467b97STreehugger Robot return buf; 475*16467b97STreehugger Robot} 476*16467b97STreehugger Robot 477*16467b97STreehugger Robot-(NSString *) toTokenString:(NSInteger)aStart ToEnd:(NSInteger)aStop 478*16467b97STreehugger Robot{ 479*16467b97STreehugger Robot if (index == -1) { 480*16467b97STreehugger Robot [self fillBuffer]; 481*16467b97STreehugger Robot } 482*16467b97STreehugger Robot NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 483*16467b97STreehugger Robot for (NSUInteger i = aStart; i < [nodes count] && i <= aStop; i++) { 484*16467b97STreehugger Robot CommonTree * t = (CommonTree *)[self get:i]; 485*16467b97STreehugger Robot [buf appendFormat:@" %d", [adaptor getType:t]]; 486*16467b97STreehugger Robot } 487*16467b97STreehugger Robot return buf; 488*16467b97STreehugger Robot} 489*16467b97STreehugger Robot 490*16467b97STreehugger Robot-(NSString *) toStringFromNode:(id)aStart ToNode:(id)aStop 491*16467b97STreehugger Robot{ 492*16467b97STreehugger Robot if (aStart == nil || aStop == nil) { 493*16467b97STreehugger Robot return nil; 494*16467b97STreehugger Robot } 495*16467b97STreehugger Robot if (index == -1) { 496*16467b97STreehugger Robot [self fillBuffer]; 497*16467b97STreehugger Robot } 498*16467b97STreehugger Robot 499*16467b97STreehugger Robot // if we have a token stream, use that to dump text in order 500*16467b97STreehugger Robot if ([self getTokenStream] != nil) { 501*16467b97STreehugger Robot NSInteger beginTokenIndex = [adaptor getTokenStartIndex:aStart]; 502*16467b97STreehugger Robot NSInteger endTokenIndex = [adaptor getTokenStopIndex:aStop]; 503*16467b97STreehugger Robot 504*16467b97STreehugger Robot if ([adaptor getType:aStop] == TokenTypeUP) { 505*16467b97STreehugger Robot endTokenIndex = [adaptor getTokenStopIndex:aStart]; 506*16467b97STreehugger Robot } 507*16467b97STreehugger Robot else if ([adaptor getType:aStop] == TokenTypeEOF) { 508*16467b97STreehugger Robot endTokenIndex = [self count] - 2; //don't use EOF 509*16467b97STreehugger Robot } 510*16467b97STreehugger Robot [tokens toStringFromStart:beginTokenIndex ToEnd:endTokenIndex]; 511*16467b97STreehugger Robot } 512*16467b97STreehugger Robot // walk nodes looking for aStart 513*16467b97STreehugger Robot CommonTree * aTree = nil; 514*16467b97STreehugger Robot NSUInteger i = 0; 515*16467b97STreehugger Robot for (; i < [nodes count]; i++) { 516*16467b97STreehugger Robot aTree = [nodes objectAtIndex:i]; 517*16467b97STreehugger Robot if (aTree == aStart) { 518*16467b97STreehugger Robot break; 519*16467b97STreehugger Robot } 520*16467b97STreehugger Robot } 521*16467b97STreehugger Robot NSMutableString *buf = [NSMutableString stringWithCapacity:10]; 522*16467b97STreehugger Robot aTree = [nodes objectAtIndex:i]; // why? 523*16467b97STreehugger Robot while (aTree != aStop) { 524*16467b97STreehugger Robot NSString *text = [adaptor getText:aTree]; 525*16467b97STreehugger Robot if (text == nil) { 526*16467b97STreehugger Robot text = [NSString stringWithFormat:@" %d", [adaptor getType:aTree]]; 527*16467b97STreehugger Robot } 528*16467b97STreehugger Robot [buf appendString:text]; 529*16467b97STreehugger Robot i++; 530*16467b97STreehugger Robot aTree = [nodes objectAtIndex:i]; 531*16467b97STreehugger Robot } 532*16467b97STreehugger Robot NSString *text = [adaptor getText:aStop]; 533*16467b97STreehugger Robot if (text == nil) { 534*16467b97STreehugger Robot text = [NSString stringWithFormat:@" %d", [adaptor getType:aStop]]; 535*16467b97STreehugger Robot } 536*16467b97STreehugger Robot [buf appendString:text]; 537*16467b97STreehugger Robot return buf; 538*16467b97STreehugger Robot} 539*16467b97STreehugger Robot 540*16467b97STreehugger Robot// getters and setters 541*16467b97STreehugger Robot- (AMutableArray *) getNodes 542*16467b97STreehugger Robot{ 543*16467b97STreehugger Robot return nodes; 544*16467b97STreehugger Robot} 545*16467b97STreehugger Robot 546*16467b97STreehugger Robot- (id) eof 547*16467b97STreehugger Robot{ 548*16467b97STreehugger Robot return eof; 549*16467b97STreehugger Robot} 550*16467b97STreehugger Robot 551*16467b97STreehugger Robot- (void) setEof:(id)theEOF 552*16467b97STreehugger Robot{ 553*16467b97STreehugger Robot eof = theEOF; 554*16467b97STreehugger Robot} 555*16467b97STreehugger Robot 556*16467b97STreehugger Robot@end 557