-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib_list.c
123 lines (95 loc) · 2.95 KB
/
lib_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
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
#include "lib.h"
/* find length of list */
void lib_len(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *len = ref(val_int(a->data.list->length));
stack_push(stack, len);
delete_ref(a);
}
/* put a value onto front a list */
void lib_cons(AStack* stack, AVarBuffer *buffer) {
AValue *vlist = stack_get(stack, 0);
AValue *a = stack_get(stack, 1);
stack_pop(stack, 2);
AValue *result = cons_list_val(a, vlist);
stack_push(stack, result);
delete_ref(a);
delete_ref(vlist);
}
/* put a value onto the end of a list
* (need better name) */
void lib_append(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
AValue *vlist = stack_get(stack, 1);
stack_pop(stack, 2);
AValue *result = append_list_val(vlist, a);
stack_push(stack, result);
delete_ref(a);
delete_ref(vlist);
}
/* get head of list */
void lib_head(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *head = head_list_val(a);
stack_push(stack, head);
delete_ref(a);
}
/* get tail of list */
void lib_tail(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *tail = tail_list_val(a);
stack_push(stack, tail);
delete_ref(a);
}
/* get init of list */
void lib_listinit(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *init = init_list_val(a);
stack_push(stack, init);
delete_ref(a);
}
/* get last elem of list */
void lib_last(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *last = last_list_val(a);
stack_push(stack, last);
delete_ref(a);
}
/* split list on top of stack into head and tail */
void lib_uncons(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *head = head_list_val(a);
AValue *tail = tail_list_val(a);
stack_push(stack, head);
stack_push(stack, tail);
delete_ref(a);
}
/* split list on top of stack into init and last
* (note: come up with a better name???) */
void lib_unappend(AStack* stack, AVarBuffer *buffer) {
AValue *a = stack_get(stack, 0);
stack_pop(stack, 1);
AValue *last = last_list_val(a);
AValue *init = init_list_val(a);
stack_push(stack, init);
stack_push(stack, last);
delete_ref(a);
}
/* Initialize built-in list operators. */
void listlib_init(ASymbolTable *st, AScope *sc) {
addlibfunc(sc, st, "len", &lib_len);
addlibfunc(sc, st, "cons", &lib_cons);
addlibfunc(sc, st, "append", &lib_append);
addlibfunc(sc, st, "head", &lib_head);
addlibfunc(sc, st, "tail", &lib_tail);
addlibfunc(sc, st, "init", &lib_listinit);
addlibfunc(sc, st, "last", &lib_last);
addlibfunc(sc, st, "uncons", &lib_uncons);
addlibfunc(sc, st, "unappend", &lib_unappend);
}