-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlist.c
62 lines (55 loc) · 1.05 KB
/
list.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
#include "list.h"
#include "obj_null.h"
#include "obj_pair.h"
obj_t make_list_(obj_t first, ...)
{
obj_t p = first, list = EMPTY_LIST;
va_list ap;
va_start(ap, first);
while (p != END_OF_ARGS) {
list = CONS(p, list);
p = va_arg(ap, obj_t);
}
va_end(ap);
return reverse_list(list);
}
bool is_list(obj_t obj)
{
while (is_pair(obj))
obj = pair_cdr(obj);
return is_null(obj);
}
size_t list_length(obj_t list)
{
size_t n = 0;
while (!is_null(list)) {
n++;
list = CDR(list);
}
return n;
}
size_t irregular_list_length(obj_t list)
{
size_t n = 0;
while (is_pair(list)) {
n++;
list = CDR(list);
}
return n + !is_null(list);
}
obj_t reverse_list(obj_t list)
{
obj_t rev = EMPTY_LIST;
while (!is_null(list)) {
rev = CONS(CAR(list), rev);
list = CDR(list);
}
return rev;
}
obj_t cons_if_changed(obj_t old_pair, obj_t new_car, obj_t new_cdr)
{
assert(is_pair(old_pair));
if (new_car == CAR(old_pair) && new_cdr == CDR(old_pair))
return old_pair;
return CONS(new_car, new_cdr);
}