Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / list.c
blobcd9a08f19419de4279315b2daad9ef7a1cc8b641
1 #include <stdlib.h>
3 #include "shotgun/lib/shotgun.h"
4 #include "shotgun/lib/cpu.h"
5 #include "shotgun/lib/machine.h"
6 #include "shotgun/lib/tuple.h"
7 #include "shotgun/lib/methctx.h"
8 #include "shotgun/lib/object.h"
9 #include "shotgun/lib/bytearray.h"
10 #include "shotgun/lib/string.h"
11 #include "shotgun/lib/class.h"
12 #include "shotgun/lib/hash.h"
13 #include "shotgun/lib/symbol.h"
14 #include "shotgun/lib/list.h"
16 void Init_list(STATE) {
17 BASIC_CLASS(list) = rbs_class_new(state, "List", ListFields, BASIC_CLASS(object));
18 BASIC_CLASS(list_node) = rbs_class_new_with_namespace(state, "Node",
19 ListNodeFields, BASIC_CLASS(object), BASIC_CLASS(list));
22 OBJECT list_new(STATE) {
23 OBJECT lst;
25 lst = rbs_class_new_instance(state, BASIC_CLASS(list));
26 list_set_count(lst, I2N(0));
28 return lst;
31 void list_append(STATE, OBJECT self, OBJECT obj) {
32 OBJECT node, cur_front, cur_last;
34 node = rbs_class_new_instance(state, BASIC_CLASS(list_node));
35 list_node_set_object(node, obj);
36 cur_last = list_get_last(self);
38 if(!NIL_P(cur_last)) {
39 list_node_set_next(cur_last, node);
42 list_set_last(self, node);
44 cur_front = list_get_first(self);
45 if(NIL_P(cur_front)) {
46 list_set_first(self, node);
49 list_set_count(self, I2N(N2I(list_get_count(self)) + 1));
52 OBJECT list_shift(STATE, OBJECT self) {
53 OBJECT node;
55 if(list_empty_p(self)) return Qnil;
57 list_set_count(self, I2N(N2I(list_get_count(self)) - 1));
58 node = list_get_first(self);
59 list_set_first(self, list_node_get_next(node));
61 if(list_get_last(self) == node) {
62 list_set_last(self, Qnil);
64 return list_node_get_object(node);
67 int list_delete(STATE, OBJECT self, OBJECT obj) {
68 OBJECT node, lst, nxt;
69 int count, deleted;
71 deleted = 0;
72 count = 0;
73 lst = Qnil;
74 node = list_get_first(self);
75 while(!NIL_P(node)) {
76 nxt = list_node_get_next(node);
78 if(list_node_get_object(node) == obj) {
79 deleted++;
80 if(NIL_P(lst)) {
81 list_set_first(self, nxt);
82 } else {
83 list_node_set_next(lst, nxt);
85 if(list_get_last(self) == node) {
86 list_set_last(self, lst);
88 } else {
89 count++;
92 lst = node;
93 node = nxt;
96 list_set_count(self, I2N(count));
98 return deleted;