1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/**
STStack.m
Temporaries and stack storage.
Copyright (c) 2002 Free Software Foundation
This file is part of the StepTalk project.
*/
#import "STStack.h"
#import <StepTalk/STExterns.h>
#import <StepTalk/STCompat.h>
#import <Foundation/NSException.h>
#import <Foundation/NSDebug.h>
@implementation STStack
+ stackWithSize:(unsigned)newSize
{
return AUTORELEASE([(STStack*)[self alloc] initWithSize:newSize]);
}
- initWithSize:(unsigned)newSize
{
size = newSize;
pointer = 0;
stack = NSZoneMalloc( NSDefaultMallocZone(), size * sizeof(id) );
return [super init];
}
- (void)invalidPointer:(unsigned)ptr
{
[NSException raise:STInternalInconsistencyException
format:@"%@: invalid pointer %i (sp=%i size=%i)",
self,
ptr,
pointer,
size];
}
- (void)dealloc
{
NSZoneFree(NSDefaultMallocZone(),stack);
[super dealloc];
}
#define INDEX_IS_VALID(index) \
((index >= 0) && (index < size))
#define CHECK_POINTER(value) \
do {\
if(!INDEX_IS_VALID(value)) \
{\
[self invalidPointer:value];\
} \
}\
while(0)
/*
- (void)setPointer:(unsigned)newPointer
{
CHECK_POINTER(newPointer);
pointer=newPointer;
}
*/
- (int)pointer
{
return pointer;
}
- (void)push:(id)value
{
CHECK_POINTER(pointer);
NSDebugLLog(@"STStack",@"stack:%p %02i push '%@'",self,pointer,value);
stack[pointer++] = value;
}
- (void)duplicateTop
{
[self push:[self valueAtTop]];
}
#define CONVERT_NIL(obj) ((obj == STNil) ? nil : (obj))
- (id)valueAtTop
{
CHECK_POINTER(pointer-1);
return CONVERT_NIL(stack[pointer-1]);
}
- (id)valueFromTop:(unsigned)index
{
id value;
CHECK_POINTER(pointer-index-1);
value = stack[pointer - index - 1];
NSDebugLLog(@"STStack",@"stack:%p %02i from top %i '%@'",
self,pointer,index,value);
return CONVERT_NIL(value);
}
- (id)pop
{
CHECK_POINTER(pointer-1);
NSDebugLLog(@"STStack",@"stack:%p %02i pop '%@'",self,pointer,stack[pointer-1]);
pointer --;
return CONVERT_NIL(stack[pointer]);
}
- (void)popCount:(unsigned)count
{
CHECK_POINTER(pointer-count);
NSDebugLLog(@"STStack",@"stack:%p %02i pop count %i (%i)",self,
pointer,count,pointer-count);
pointer -= count;
}
- (void)empty
{
pointer = 0;
}
@end
|