67
67
check_type(*op, t_integer);
68
68
if ((ulong)op->value.intval >= (ulong)(op - osbot)) {
69
/* Might be in an older stack block. */
69
/* Might be in an older stack block. */
72
if (op->value.intval < 0)
73
return_error(e_rangecheck);
74
elt = ref_stack_index(&o_stack, op->value.intval + 1);
76
return_error(e_stackunderflow);
72
if (op->value.intval < 0)
73
return_error(e_rangecheck);
74
elt = ref_stack_index(&o_stack, op->value.intval + 1);
76
return_error(e_stackunderflow);
80
80
opn = op + ~(int)op->value.intval;
81
81
ref_assign_inline(op, opn);
113
113
check_type(*op1, t_integer);
114
114
check_type(*op, t_integer);
115
115
if ((uint) op1->value.intval > (uint)(op1 - osbot)) {
117
* The data might span multiple stack blocks.
118
* There are efficient ways to handle this situation,
119
* but they're more complicated than seems worth implementing;
120
* for now, do something very simple and inefficient.
124
if (op1->value.intval < 0)
125
return_error(e_rangecheck);
126
if (op1->value.intval + 2 > (int)ref_stack_count(&o_stack))
127
return_error(e_stackunderflow);
128
count = op1->value.intval;
133
mod = op->value.intval;
139
mod += count; /* can't assume % means mod! */
141
/* Use the chain rotation algorithm mentioned below. */
142
for (i = 0, left = count; left; i++) {
143
ref *elt = ref_stack_index(&o_stack, i + 2);
149
for (j = i, left--;; j = k, elt = next, left--) {
150
k = (j + mod) % count;
153
next = ref_stack_index(&o_stack, k + 2);
154
ref_assign(elt, next);
117
* The data might span multiple stack blocks.
118
* There are efficient ways to handle this situation,
119
* but they're more complicated than seems worth implementing;
120
* for now, do something very simple and inefficient.
124
if (op1->value.intval < 0)
125
return_error(e_rangecheck);
126
if (op1->value.intval + 2 > (int)ref_stack_count(&o_stack))
127
return_error(e_stackunderflow);
128
count = op1->value.intval;
133
mod = op->value.intval;
139
mod += count; /* can't assume % means mod! */
141
/* Use the chain rotation algorithm mentioned below. */
142
for (i = 0, left = count; left; i++) {
143
ref *elt = ref_stack_index(&o_stack, i + 2);
149
for (j = i, left--;; j = k, elt = next, left--) {
150
k = (j + mod) % count;
153
next = ref_stack_index(&o_stack, k + 2);
154
ref_assign(elt, next);
161
161
count = op1->value.intval;
162
162
if (count <= 1) {
166
166
mod = op->value.intval;
173
173
* in *either* direction.
176
case 1: /* common special case */
182
ref_assign_inline(&top, op);
183
for (from = op, n = count; --n; from--)
184
ref_assign_inline(from, from - 1);
185
ref_assign_inline(from, &top);
188
case -1: /* common special case */
195
ref_assign_inline(&bot, to);
196
for (n = count; --n; to++)
197
ref_assign(to, to + 1);
198
ref_assign_inline(to, &bot);
176
case 1: /* common special case */
182
ref_assign_inline(&top, op);
183
for (from = op, n = count; --n; from--)
184
ref_assign_inline(from, from - 1);
185
ref_assign_inline(from, &top);
188
case -1: /* common special case */
195
ref_assign_inline(&bot, to);
196
for (n = count; --n; to++)
197
ref_assign(to, to + 1);
198
ref_assign_inline(to, &bot);
207
mod += count; /* can't assume % means mod! */
207
mod += count; /* can't assume % means mod! */
209
209
} else if (mod >= count)
211
211
if (mod <= count >> 1) {
212
/* Move everything up, then top elements down. */
213
if (mod >= ostop - op) {
214
o_stack.requested = mod;
215
return_error(e_stackoverflow);
219
for (to = op + mod, from = op, n = count; n--; to--, from--)
220
ref_assign(to, from);
221
memcpy((char *)(from + 1), (char *)(op + 1), mod * sizeof(ref));
212
/* Move everything up, then top elements down. */
213
if (mod >= ostop - op) {
214
o_stack.requested = mod;
215
return_error(e_stackoverflow);
219
for (to = op + mod, from = op, n = count; n--; to--, from--)
220
ref_assign(to, from);
221
memcpy((char *)(from + 1), (char *)(op + 1), mod * sizeof(ref));
223
/* Move bottom elements up, then everything down. */
225
if (mod >= ostop - op) {
226
o_stack.requested = mod;
227
return_error(e_stackoverflow);
232
memcpy((char *)(op + 1), (char *)to, mod * sizeof(ref));
233
for (from = to + mod, n = count; n--; to++, from++)
234
ref_assign(to, from);
223
/* Move bottom elements up, then everything down. */
225
if (mod >= ostop - op) {
226
o_stack.requested = mod;
227
return_error(e_stackoverflow);
232
memcpy((char *)(op + 1), (char *)to, mod * sizeof(ref));
233
for (from = to + mod, n = count; n--; to++, from++)
234
ref_assign(to, from);