Skip to content

Commit f0816ff

Browse files
committed
First implementations of push, pop, shift and unshift for VMArray.
Most of the groundwork is in place now. Next: Fixing the bugs.
1 parent 7148fa7 commit f0816ff

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

src/6model/reprs/VMArray.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,41 +371,78 @@ static void bind_pos_boxed(PARROT_INTERP, STable *st, void *data, INTVAL index,
371371
}
372372

373373
static void push_boxed(PARROT_INTERP, STable *st, void *data, PMC *obj) {
374+
VMArrayBody *body = (VMArrayBody *) data;
374375
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
375376

376377
if(repr_data->elem_size)
377378
die_no_boxed(interp, "push");
378379

379-
/* TODO */
380+
ensure_size(interp, body, repr_data, body->elems+1);
381+
set_pos_pmc((PMC **) body->slots, body->start + body->elems-1, obj);
380382
}
381383

382384
static PMC *pop_boxed(PARROT_INTERP, STable *st, void *data) {
385+
VMArrayBody *body = (VMArrayBody *) data;
383386
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
384387

385388
if(repr_data->elem_size)
386389
die_no_boxed(interp, "pop");
387390

388-
/* TODO */
389-
return PMCNULL;
391+
if(body->elems < 1)
392+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
393+
"VMArray: Can't pop from an empty array!");
394+
395+
body->elems--;
396+
return get_pos_pmc((PMC **) body->slots, body->start + body->elems);
390397
}
391398

392399
static void unshift_boxed(PARROT_INTERP, STable *st, void *data, PMC *obj) {
400+
VMArrayBody *body = (VMArrayBody *) data;
393401
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
394402

395403
if(repr_data->elem_size)
396404
die_no_boxed(interp, "unshift");
397405

398-
/* TODO */
406+
/* If we don't have room at the beginning of the slots, make some room (8
407+
* slots) for unshifting */
408+
if (body->start < 1) {
409+
INTVAL n = 8;
410+
INTVAL elems = body->elems;
411+
INTVAL i;
412+
413+
/* Grow the array */
414+
ensure_size(interp, body, repr_data, elems + n);
415+
/* Move elements and set start */
416+
memmove(body->slots + n, body->slots, elems * sizeof (PMC *));
417+
body->start = n;
418+
body->elems = elems;
419+
/* Clear out beginning elements */
420+
for (i = 0; i < n; i++)
421+
set_pos_pmc((PMC **) body->slots, i, PMCNULL);
422+
}
423+
424+
/* Now do the unshift */
425+
body->start--;
426+
set_pos_pmc((PMC **) body->slots, body->start, obj);
427+
body->elems++;
399428
}
400429

401430
static PMC *shift_boxed(PARROT_INTERP, STable *st, void *data) {
431+
VMArrayBody *body = (VMArrayBody *) data;
402432
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
433+
PMC *value;
403434

404435
if(repr_data->elem_size)
405436
die_no_boxed(interp, "shift");
406437

407-
/* TODO */
408-
return PMCNULL;
438+
if(body->elems < 1)
439+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_OUT_OF_BOUNDS,
440+
"VMArray: Can't shift from an empty array!");
441+
442+
value = get_pos_pmc((PMC **) body->slots, body->start);
443+
body->start++;
444+
body->elems--;
445+
return value;
409446
}
410447

411448
/* Initializes the VMArray representation. */

0 commit comments

Comments
 (0)