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 130 131 132 133
|
/**
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 <Foundation/NSException.h>
#import <Foundation/NSDebug.h>
@implementation STStack
+ stackWithSize:(NSUInteger)newSize
{
return AUTORELEASE([[self alloc] initWithSize:newSize]);
}
- initWithSize:(NSUInteger)newSize
{
if ((self = [super init]) != nil)
{
size = newSize;
pointer = 0;
stack = NSZoneMalloc( NSDefaultMallocZone(), size * sizeof(id) );
}
return self;
}
- (void)invalidPointer:(NSUInteger)ptr
{
[NSException raise:STInternalInconsistencyException
format:@"%@: invalid pointer %lu (sp=%lu size=%lu)",
self,
(unsigned long)ptr,
(unsigned long)pointer,
(unsigned long)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:(NSUInteger)newPointer
{
CHECK_POINTER(newPointer);
pointer=newPointer;
}
*/
- (NSUInteger)pointer
{
return pointer;
}
- (void)push:(id)value
{
CHECK_POINTER(pointer);
NSDebugLLog(@"STStack",@"stack:%p %02lu push '%@'",
self,(unsigned long)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:(NSUInteger)index
{
id value;
CHECK_POINTER(pointer-index-1);
value = stack[pointer - index - 1];
NSDebugLLog(@"STStack",@"stack:%p %02li from top %li '%@'",
self,(unsigned long)pointer,(unsigned long)index,value);
return CONVERT_NIL(value);
}
- (id)pop
{
CHECK_POINTER(pointer-1);
NSDebugLLog(@"STStack",@"stack:%p %02li pop '%@'",
self,(unsigned long)pointer,stack[pointer-1]);
pointer --;
return CONVERT_NIL(stack[pointer]);
}
- (void)popCount:(NSUInteger)count
{
CHECK_POINTER(pointer-count);
NSDebugLLog(@"STStack",@"stack:%p %02lu pop count %lu (%li)",self,
(unsigned long)pointer,(unsigned long)count,
(long)(pointer-count));
pointer -= count;
}
- (void)empty
{
pointer = 0;
}
@end
|