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