-
Notifications
You must be signed in to change notification settings - Fork 0
/
stack.h
67 lines (54 loc) · 1.83 KB
/
stack.h
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
#ifndef _STACK_H
#define _STACK_H
#include <stdint.h>
#include <string.h>
#include "cell.h"
#include "exception.h"
#ifndef STACK_EMPTY
#define STACK_EMPTY (-1)
#endif
extern void throw (intptr_t);
typedef struct _stack {
int32_t top;
int underflow;
int overflow;
#define STACK_SIZE (256)
cell values[STACK_SIZE];
} Stack;
static inline void stack_init (Stack *stack, int underflow, int overflow) {
memset(stack, 0, sizeof (Stack));
stack->top = STACK_EMPTY;
stack->underflow = underflow;
stack->overflow = overflow;
}
static inline void stack_push (Stack *stack, cell value) {
if (stack->top >= STACK_SIZE - 1) throw(stack->overflow);
stack->values[++stack->top] = value;
}
static inline cell stack_pop (Stack *stack) {
if (stack->top <= STACK_EMPTY) throw(stack->underflow);
return stack->values[stack->top--];
}
static inline cell stack_peek (const Stack *stack) {
if (stack->top <= STACK_EMPTY) throw(stack->underflow);
return stack->values[stack->top];
}
static inline uintptr_t stack_count (const Stack *stack) {
return (stack->top >= 0 ? stack->top + 1 : 0);
}
static inline void stack_pick (Stack *stack, unsigned int n) {
if (stack->top >= STACK_SIZE - 1) throw(stack->overflow);
if (stack->top <= STACK_EMPTY + n) throw(stack->underflow);
stack->values[stack->top + 1] = stack->values[stack->top - n];
++ stack->top;
}
static inline void stack_roll (Stack *stack, unsigned int n) {
if (stack->top >= STACK_SIZE - 1) throw(stack->overflow);
if (stack->top <= STACK_EMPTY + n) throw(stack->underflow);
register cell a = stack->values[stack->top - n];
memmove(&stack->values[stack->top - n], // dst
&stack->values[1 + stack->top - n], // src
n * sizeof(cell)); // len
stack->values[stack->top] = a;
}
#endif