Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / array.c
blob398dd70fb808f47c26d83e3681a904d94130268b
1 #include "shotgun/lib/shotgun.h"
2 #include "shotgun/lib/object.h"
3 #include "shotgun/lib/tuple.h"
5 // TODO - Support >32bit counts?
6 OBJECT array_new(STATE, size_t count) {
7 OBJECT tup, obj;
8 tup = tuple_new(state, count < 8 ? 8 : count);
9 obj = array_allocate(state);
10 array_set_total(obj, I2N(0));
11 array_set_start(obj, I2N(0));
12 array_set_tuple(obj, tup);
13 return obj;
16 OBJECT array_from_tuple(STATE, OBJECT tuple) {
17 OBJECT tup, ary;
18 size_t count;
19 count = NUM_FIELDS(tuple);
20 tup = tuple_new(state, count);
21 object_copy_fields(state, tuple, tup);
22 ary = array_new(state, count);
23 array_set_total(ary, I2N(count));
24 array_set_tuple(ary, tup);
25 return ary;
28 // TODO - Support >32bit counts?
29 OBJECT array_set(STATE, OBJECT self, size_t idx, OBJECT val) {
30 OBJECT nt, tup;
31 size_t cur, oidx;
33 tup = array_get_tuple(self);
34 cur = NUM_FIELDS(tup);
36 oidx = idx;
37 idx += N2I(array_get_start(self));
39 if(idx >= cur) {
40 size_t new_size = (cur == 0) ? 1 : cur;
42 /* geometric expansion to fit idx in */
43 while (new_size <= idx) {
44 new_size *= 2;
47 nt = tuple_new(state, new_size);
48 object_copy_fields_from(state, tup, nt, 0, cur);
49 array_set_tuple(self, nt);
50 tup = nt;
53 tuple_put(state, tup, idx, val);
54 if(N2I(array_get_total(self)) <= oidx) {
55 array_set_total(self, ML2N(oidx+1));
57 return val;
60 // TODO - Support >32bit counts?
61 OBJECT array_get(STATE, OBJECT self, size_t idx) {
62 if(idx >= N2I(array_get_total(self))) {
63 return Qnil;
66 idx += N2I(array_get_start(self));
68 return tuple_at(state, array_get_tuple(self), idx);
71 OBJECT array_append(STATE, OBJECT self, OBJECT val) {
72 size_t idx;
73 idx = N2I(array_get_total(self));
74 return array_set(state, self, idx, val);
77 OBJECT array_pop(STATE, OBJECT self) {
78 size_t idx;
79 OBJECT val;
81 idx = N2I(array_get_total(self)) - 1;
82 val = array_get(state, self, idx);
83 array_set(state, self, idx, Qnil);
85 array_set_total(self, ML2N(idx));
86 return val;