-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinkedlist.c
143 lines (131 loc) · 3.55 KB
/
linkedlist.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
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "value.h"
#include "talloc.h"
/* Justin Lim and Elliot Mawby. CS251, Dave Musicant. Modified LinkedList.
* Due April 29, 2015. Modified May 1, 2015.
*
* Changes: makeNull() and cons() now use the talloc function from talloc.c, instead of malloc.
* Reverse() function modified.
*/
// Create a new NULL_TYPE value node.
Value *makeNull() {
Value *v = talloc(sizeof(Value));
(*v).type = NULL_TYPE;
return v;
}
// Create a new CONS_TYPE value node.
Value *cons(Value *car, Value *cdr) {
Value *v = talloc(sizeof(Value));
(*v).type = CONS_TYPE;
(*v).c.car = car;
(*v).c.cdr = cdr;
return v;
}
// Display the contents of the linked list to the screen in some kind of
// readable format
void display(Value *list) {
Value *val = list;
// If null, the end of the list has been reached.
if ((*val).type == NULL_TYPE) {
printf("End of list.\n");
}
// Otherwise, print the item in the list, or if CONS_TYPE,
// display the car go to next item (cdr).
else {
switch ((*val).type) {
case INT_TYPE:
printf("%i\n", (*val).i);
break;
case DOUBLE_TYPE:
printf("%f\n", (*val).d);
break;
case STR_TYPE:
printf("%s\n", (*val).s);
break;
case CONS_TYPE:
display((*val).c.car);
display((*val).c.cdr);
break;
case NULL_TYPE:
printf("\n");
break;
// Part 2
case PTR_TYPE:
printf("\n");
break;
// Part 3
case OPEN_TYPE:
printf("%c\n", '(');
break;
case CLOSE_TYPE:
printf("%c\n", ')');
break;
case BOOL_TYPE:
printf("%i\n", (*val).i);
break;
case SYMBOL_TYPE:
printf("%s\n", (*val).s);
break;
case VOID_TYPE:
break;
case CLOSURE_TYPE:
break;
case PRIMITIVE_TYPE:
break;
}
}
}
// Return a new list that is the reverse of the one that is passed in. No stored
// data within the linked list should be duplicated; rather, a new linked list
// of CONS_TYPE nodes should be created, that point to items in the original
// list.
Value *reverse(Value *list) {
Value *head = makeNull();
Value *val = list;
// Keeps track of the cdr of our list.
Value *cdr_ptr = list;
// Reverses the list.
while ((*val).type == CONS_TYPE) {
val = (*val).c.car;
cdr_ptr = (*cdr_ptr).c.cdr;
head = cons(val,head);
val = cdr_ptr;
}
return head;
}
// Utility to make it less typing to get car value. Use assertions to make sure
// that this is a legitimate operation.
Value *car(Value *list) {
return (*list).c.car;
}
// Utility to make it less typing to get cdr value. Use assertions to make sure
// that this is a legitimate operation.
Value *cdr(Value *list) {
return (*list).c.cdr;
}
// Utility to check if pointing to a NULL_TYPE value. Use assertions to make sure
// that this is a legitimate operation.
bool isNull(Value *value) {
if ((*value).type == NULL_TYPE) {
return 1;
} else {
return 0;
}
}
// Measure length of list. Use assertions to make sure that this is a legitimate
// operation.
int length(Value *value) {
int counter = 0;
if ((*value).type != CONS_TYPE) {
if ((*value).type != NULL_TYPE) {
return 1;
}
}
while ((*value).type == CONS_TYPE) {
counter ++;
value = (*value).c.cdr;
}
return counter;
}