-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlist_ops.c
274 lines (219 loc) · 7.67 KB
/
list_ops.c
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#include <stdlib.h>
#include "noheap/llist.c"
// Define the structure for linked list nodes
struct Node {
struct Node *next;
struct Node *prev;
DCLANG_FLT data; // New member for data
};
// Function to create a linked list with a single node containing user-chosen data
void listmakefunc() {
// Allocate memory for the head node
struct Node *list = (struct Node *)dclang_malloc(sizeof(struct Node));
// Set the head node to point to itself in both directions
list->next = list;
list->prev = list;
// Push the pointer to the head node onto the stack
push((DCLANG_PTR)list);
}
void listnextfunc() {
if (data_stack_ptr < 1) {
printf("_lnext -- stack underflow; need <existing_list_node> on the stack! ");
return;
}
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
struct Node *next = list->next;
push((DCLANG_PTR) next);
}
// Function to append a node to the tail of the linked list
void listpushfunc() {
if (data_stack_ptr < 2) {
printf("lpush -- stack underflow; need <list> <value> on the stack! ");
return;
}
// Pop args
DCLANG_FLT value = dclang_pop();
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Allocate memory for the new node
struct Node *new_node = (struct Node *)dclang_malloc(sizeof(struct Node));
// Initialize the new node
new_node->data = value;
// Insert the new node before the head node (at the tail)
insque(new_node, list->prev);
}
// Function to pop a node from the tail of the linked list
void listpopfunc() {
if (data_stack_ptr < 1) {
printf("lpop -- stack underflow; need <list> on the stack! ");
return;
}
// Pop arg
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Check if the list is empty
if (list->next == list) {
printf("lpop -- list is empty! ");
return;
}
// Get the tail node
struct Node *tail_node = list->prev;
// Remove the tail node from the list
remque(tail_node);
// Push the data of the tail node onto the stack
push((DCLANG_FLT)tail_node->data);
// Free the memory of the popped node
dclang_free(tail_node);
}
// Function to set the data of a node in the linked list
void listsetfunc() {
if (data_stack_ptr < 3) {
printf("l! -- stack underflow; need <list> <slot> <value> on the stack! ");
return;
}
// Pop args
DCLANG_FLT value = dclang_pop();
DCLANG_LONG slot = (DCLANG_LONG)dclang_pop();
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Find the Nth node in the linked list
struct Node *node = list;
for (int i = 0; i < slot + 1; i++) {
if (node->next == list) {
// Reached the end of the list
printf("l! -- slot out of bounds! ");
return;
}
node = node->next;
}
// Set the data of the node
node->data = value;
}
// Function to get the data of a node in the linked list
void listgetfunc() {
if (data_stack_ptr < 2) {
printf("l@ -- stack underflow; need <list> <slot> on the stack! ");
return;
}
// Pop args
DCLANG_LONG slot = (DCLANG_LONG)dclang_pop();
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Find the Nth node in the linked list
struct Node *node = list;
for (int i = 0; i < slot + 1; i++) {
if (node->next == list) {
// Reached the end of the list
printf("l@ -- slot out of bounds! ");
return;
}
node = node->next;
}
// Push the data of the node onto the stack
push((DCLANG_FLT)node->data);
}
// Function to insert a node into a linked list before a specified node
void listinsertfunc() {
if (data_stack_ptr < 3) {
printf("lins -- stack underflow; need <list> <node_slot> <value> on the stack! ");
return;
}
// Pop args
DCLANG_FLT value = dclang_pop();
DCLANG_LONG node_slot = (DCLANG_LONG)dclang_pop();
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Allocate memory for the new node
struct Node *new_node = (struct Node *)dclang_malloc(sizeof(struct Node));
// Initialize the new node
new_node->data = value;
// Find the node before which to insert the new node
struct Node *node_before = list;
for (int i = 0; i < node_slot; i++) {
if (node_before->next == list) {
// Reached the end of the list
printf("lins -- node_slot out of bounds! ");
dclang_free(new_node);
return;
}
node_before = node_before->next;
}
// Insert the new node before the specified node
insque(new_node, node_before);
}
// Function to remove a node from a linked list at a specified node slot
void listremovefunc() {
if (data_stack_ptr < 2) {
printf("lrem -- stack underflow; need <list> <node_slot> on the stack! ");
return;
}
// Pop the node slot and list pointer and node slot from the stack
DCLANG_LONG node_slot = (DCLANG_LONG)dclang_pop();
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointers to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Find the node to remove
struct Node *node_to_remove = list;
for (int i = 0; i < node_slot + 1; i++) {
if (node_to_remove->next == list) {
// Reached the end of the list
printf("lrem -- node_slot out of bounds! ");
return;
}
node_to_remove = node_to_remove->next;
}
// Remove the specified node from the list
remque(node_to_remove);
// Free the memory of the removed node
dclang_free(node_to_remove);
}
// Function to get the size (number of nodes) in a linked list
void listsizefunc() {
if (data_stack_ptr < 1) {
printf("lsize -- stack underflow; need <list> on the stack! ");
return;
}
// Pop the list pointer from the stack
DCLANG_PTR list_ptr = dclang_pop();
// Convert pointer to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Initialize the size counter
int size = 0;
// Traverse the linked list and count each node
struct Node *current = list->next;
while (current != list) {
size++;
current = current->next;
}
// Push the size onto the stack
push((DCLANG_LONG)size);
}
// Function to delete (dclang_free) all nodes in a linked list
void listdeletefunc() {
if (data_stack_ptr < 1) {
printf("ldel -- stack underflow; need <list> on the stack! ");
return;
}
// Pop the list pointer from the stack
DCLANG_PTR list_ptr = (DCLANG_PTR)dclang_pop();
// Convert pointer to the actual node structure
struct Node *list = (struct Node *)list_ptr;
// Traverse the linked list and free each node in the 'next' direction
struct Node *current_next = list->next;
while (current_next != list) {
struct Node *next_node = current_next->next;
dclang_free(current_next);
current_next = next_node;
}
// Free the head node
// Reset the list to a blank head node
list->next = list;
list->prev = list;
}