File: STStack.m

package info (click to toggle)
steptalk 0.10.0%2Bgit20200629-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,732 kB
  • sloc: objc: 12,182; yacc: 400; makefile: 40; sh: 34; csh: 4; awk: 3; lisp: 3
file content (133 lines) | stat: -rw-r--r-- 2,766 bytes parent folder | download
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