xref: /plan9/sys/src/cmd/acid/list.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ctype.h>
5 #include <mach.h>
6 #define Extern extern
7 #include "acid.h"
8 
9 static List **tail;
10 
11 List*
construct(Node * l)12 construct(Node *l)
13 {
14 	List *lh, **save;
15 
16 	save = tail;
17 	lh = 0;
18 	tail = &lh;
19 	build(l);
20 	tail = save;
21 
22 	return lh;
23 }
24 
25 int
listlen(List * l)26 listlen(List *l)
27 {
28 	int len;
29 
30 	len = 0;
31 	while(l) {
32 		len++;
33 		l = l->next;
34 	}
35 	return len;
36 }
37 
38 void
build(Node * n)39 build(Node *n)
40 {
41 	List *l;
42 	Node res;
43 
44 	if(n == 0)
45 		return;
46 
47 	switch(n->op) {
48 	case OLIST:
49 		build(n->left);
50 		build(n->right);
51 		return;
52 	default:
53 		expr(n, &res);
54 		l = al(res.type);
55 		l->Store = res.Store;
56 		*tail = l;
57 		tail = &l->next;
58 	}
59 }
60 
61 List*
addlist(List * l,List * r)62 addlist(List *l, List *r)
63 {
64 	List *f;
65 
66 	if(l == 0)
67 		return r;
68 
69 	for(f = l; f->next; f = f->next)
70 		;
71 	f->next = r;
72 
73 	return l;
74 }
75 
76 void
append(Node * r,Node * list,Node * val)77 append(Node *r, Node *list, Node *val)
78 {
79 	List *l, *f;
80 
81 	l = al(val->type);
82 	l->Store = val->Store;
83 	l->next = 0;
84 
85 	r->op = OCONST;
86 	r->type = TLIST;
87 
88 	if(list->l == 0) {
89 		list->l = l;
90 		r->l = l;
91 		return;
92 	}
93 	for(f = list->l; f->next; f = f->next)
94 		;
95 	f->next = l;
96 	r->l = list->l;
97 }
98 
99 int
listcmp(List * l,List * r)100 listcmp(List *l, List *r)
101 {
102 	if(l == r)
103 		return 1;
104 
105 	while(l) {
106 		if(r == 0)
107 			return 0;
108 		if(l->type != r->type)
109 			return 0;
110 		switch(l->type) {
111 		case TINT:
112 			if(l->ival != r->ival)
113 				return 0;
114 			break;
115 		case TFLOAT:
116 			if(l->fval != r->fval)
117 				return 0;
118 			break;
119 		case TSTRING:
120 			if(scmp(l->string, r->string) == 0)
121 				return 0;
122 			break;
123 		case TLIST:
124 			if(listcmp(l->l, r->l) == 0)
125 				return 0;
126 			break;
127 		}
128 		l = l->next;
129 		r = r->next;
130 	}
131 	if(l != r)
132 		return 0;
133 	return 1;
134 }
135 
136 void
nthelem(List * l,int n,Node * res)137 nthelem(List *l, int n, Node *res)
138 {
139 	if(n < 0)
140 		error("negative index in []");
141 
142 	while(l && n--)
143 		l = l->next;
144 
145 	res->op = OCONST;
146 	if(l == 0) {
147 		res->type = TLIST;
148 		res->l = 0;
149 		return;
150 	}
151 	res->type = l->type;
152 	res->Store = l->Store;
153 }
154 
155 void
delete(List * l,int n,Node * res)156 delete(List *l, int n, Node *res)
157 {
158 	List **tl;
159 
160 	if(n < 0)
161 		error("negative index in delete");
162 
163 	res->op = OCONST;
164 	res->type = TLIST;
165 	res->l = l;
166 
167 	for(tl = &res->l; l && n--; l = l->next)
168 		tl = &l->next;
169 
170 	if(l == 0)
171 		error("element beyond end of list");
172 	*tl = l->next;
173 }
174 
175 List*
listvar(char * s,vlong v)176 listvar(char *s, vlong v)
177 {
178 	List *l, *tl;
179 
180 	tl = al(TLIST);
181 
182 	l = al(TSTRING);
183 	tl->l = l;
184 	l->fmt = 's';
185 	l->string = strnode(s);
186 	l->next = al(TINT);
187 	l = l->next;
188 	l->fmt = 'X';
189 	l->ival = v;
190 
191 	return tl;
192 }
193 
194 static List*
listlocals(Map * map,Symbol * fn,uvlong fp)195 listlocals(Map *map, Symbol *fn, uvlong fp)
196 {
197 	int i;
198 	uvlong val;
199 	Symbol s;
200 	List **tail, *l2;
201 
202 	l2 = 0;
203 	tail = &l2;
204 	s = *fn;
205 
206 	for(i = 0; localsym(&s, i); i++) {
207 		if(s.class != CAUTO)
208 			continue;
209 		if(s.name[0] == '.')
210 			continue;
211 
212 		if(geta(map, fp-s.value, &val) > 0) {
213 			*tail = listvar(s.name, val);
214 			tail = &(*tail)->next;
215 		}
216 	}
217 	return l2;
218 }
219 
220 static List*
listparams(Map * map,Symbol * fn,uvlong fp)221 listparams(Map *map, Symbol *fn, uvlong fp)
222 {
223 	int i;
224 	Symbol s;
225 	uvlong v;
226 	List **tail, *l2;
227 
228 	l2 = 0;
229 	tail = &l2;
230 	fp += mach->szaddr;			/* skip saved pc */
231 	s = *fn;
232 	for(i = 0; localsym(&s, i); i++) {
233 		if (s.class != CPARAM)
234 			continue;
235 
236 		if(geta(map, fp+s.value, &v) > 0) {
237 			*tail = listvar(s.name, v);
238 			tail = &(*tail)->next;
239 		}
240 	}
241 	return l2;
242 }
243 
244 void
trlist(Map * map,uvlong pc,uvlong sp,Symbol * sym)245 trlist(Map *map, uvlong pc, uvlong sp, Symbol *sym)
246 {
247 	List *q, *l;
248 
249 	static List **tail;
250 
251 	if (tracelist == 0) {		/* first time */
252 		tracelist = al(TLIST);
253 		tail = &tracelist;
254 	}
255 
256 	q = al(TLIST);
257 	*tail = q;
258 	tail = &q->next;
259 
260 	l = al(TINT);			/* Function address */
261 	q->l = l;
262 	l->ival = sym->value;
263 	l->fmt = 'X';
264 
265 	l->next = al(TINT);		/* called from address */
266 	l = l->next;
267 	l->ival = pc;
268 	l->fmt = 'Y';
269 
270 	l->next = al(TLIST);		/* make list of params */
271 	l = l->next;
272 	l->l = listparams(map, sym, sp);
273 
274 	l->next = al(TLIST);		/* make list of locals */
275 	l = l->next;
276 	l->l = listlocals(map, sym, sp);
277 }
278