xref: /plan9/sys/src/cmd/acid/list.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1bd389b36SDavid du Colombier #include <u.h>
2bd389b36SDavid du Colombier #include <libc.h>
3bd389b36SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <ctype.h>
5bd389b36SDavid du Colombier #include <mach.h>
6bd389b36SDavid du Colombier #define Extern extern
7bd389b36SDavid du Colombier #include "acid.h"
8bd389b36SDavid du Colombier 
9bd389b36SDavid du Colombier static List **tail;
10bd389b36SDavid du Colombier 
11bd389b36SDavid du Colombier List*
construct(Node * l)12bd389b36SDavid du Colombier construct(Node *l)
13bd389b36SDavid du Colombier {
14bd389b36SDavid du Colombier 	List *lh, **save;
15bd389b36SDavid du Colombier 
16bd389b36SDavid du Colombier 	save = tail;
17bd389b36SDavid du Colombier 	lh = 0;
18bd389b36SDavid du Colombier 	tail = &lh;
19bd389b36SDavid du Colombier 	build(l);
20bd389b36SDavid du Colombier 	tail = save;
21bd389b36SDavid du Colombier 
22bd389b36SDavid du Colombier 	return lh;
23bd389b36SDavid du Colombier }
24bd389b36SDavid du Colombier 
25219b2ee8SDavid du Colombier int
listlen(List * l)26219b2ee8SDavid du Colombier listlen(List *l)
27219b2ee8SDavid du Colombier {
28219b2ee8SDavid du Colombier 	int len;
29219b2ee8SDavid du Colombier 
30219b2ee8SDavid du Colombier 	len = 0;
31219b2ee8SDavid du Colombier 	while(l) {
32219b2ee8SDavid du Colombier 		len++;
33219b2ee8SDavid du Colombier 		l = l->next;
34219b2ee8SDavid du Colombier 	}
35219b2ee8SDavid du Colombier 	return len;
36219b2ee8SDavid du Colombier }
37219b2ee8SDavid du Colombier 
38bd389b36SDavid du Colombier void
build(Node * n)39bd389b36SDavid du Colombier build(Node *n)
40bd389b36SDavid du Colombier {
41bd389b36SDavid du Colombier 	List *l;
42bd389b36SDavid du Colombier 	Node res;
43bd389b36SDavid du Colombier 
44bd389b36SDavid du Colombier 	if(n == 0)
45bd389b36SDavid du Colombier 		return;
46bd389b36SDavid du Colombier 
47bd389b36SDavid du Colombier 	switch(n->op) {
48bd389b36SDavid du Colombier 	case OLIST:
49bd389b36SDavid du Colombier 		build(n->left);
50bd389b36SDavid du Colombier 		build(n->right);
51bd389b36SDavid du Colombier 		return;
52bd389b36SDavid du Colombier 	default:
53bd389b36SDavid du Colombier 		expr(n, &res);
54bd389b36SDavid du Colombier 		l = al(res.type);
55bd389b36SDavid du Colombier 		l->Store = res.Store;
56bd389b36SDavid du Colombier 		*tail = l;
57bd389b36SDavid du Colombier 		tail = &l->next;
58bd389b36SDavid du Colombier 	}
59bd389b36SDavid du Colombier }
60bd389b36SDavid du Colombier 
61bd389b36SDavid du Colombier List*
addlist(List * l,List * r)62bd389b36SDavid du Colombier addlist(List *l, List *r)
63bd389b36SDavid du Colombier {
64bd389b36SDavid du Colombier 	List *f;
65bd389b36SDavid du Colombier 
66219b2ee8SDavid du Colombier 	if(l == 0)
67219b2ee8SDavid du Colombier 		return r;
68219b2ee8SDavid du Colombier 
69bd389b36SDavid du Colombier 	for(f = l; f->next; f = f->next)
70bd389b36SDavid du Colombier 		;
71bd389b36SDavid du Colombier 	f->next = r;
72bd389b36SDavid du Colombier 
73bd389b36SDavid du Colombier 	return l;
74bd389b36SDavid du Colombier }
75bd389b36SDavid du Colombier 
76bd389b36SDavid du Colombier void
append(Node * r,Node * list,Node * val)77bd389b36SDavid du Colombier append(Node *r, Node *list, Node *val)
78bd389b36SDavid du Colombier {
79bd389b36SDavid du Colombier 	List *l, *f;
80bd389b36SDavid du Colombier 
81bd389b36SDavid du Colombier 	l = al(val->type);
82bd389b36SDavid du Colombier 	l->Store = val->Store;
83bd389b36SDavid du Colombier 	l->next = 0;
84bd389b36SDavid du Colombier 
85bd389b36SDavid du Colombier 	r->op = OCONST;
86bd389b36SDavid du Colombier 	r->type = TLIST;
87bd389b36SDavid du Colombier 
88bd389b36SDavid du Colombier 	if(list->l == 0) {
89bd389b36SDavid du Colombier 		list->l = l;
90bd389b36SDavid du Colombier 		r->l = l;
91bd389b36SDavid du Colombier 		return;
92bd389b36SDavid du Colombier 	}
93bd389b36SDavid du Colombier 	for(f = list->l; f->next; f = f->next)
94bd389b36SDavid du Colombier 		;
95bd389b36SDavid du Colombier 	f->next = l;
96bd389b36SDavid du Colombier 	r->l = list->l;
97bd389b36SDavid du Colombier }
98bd389b36SDavid du Colombier 
99bd389b36SDavid du Colombier int
listcmp(List * l,List * r)100bd389b36SDavid du Colombier listcmp(List *l, List *r)
101bd389b36SDavid du Colombier {
102bd389b36SDavid du Colombier 	if(l == r)
103bd389b36SDavid du Colombier 		return 1;
104bd389b36SDavid du Colombier 
105bd389b36SDavid du Colombier 	while(l) {
106bd389b36SDavid du Colombier 		if(r == 0)
107bd389b36SDavid du Colombier 			return 0;
108bd389b36SDavid du Colombier 		if(l->type != r->type)
109bd389b36SDavid du Colombier 			return 0;
110bd389b36SDavid du Colombier 		switch(l->type) {
111bd389b36SDavid du Colombier 		case TINT:
112bd389b36SDavid du Colombier 			if(l->ival != r->ival)
113bd389b36SDavid du Colombier 				return 0;
114bd389b36SDavid du Colombier 			break;
115bd389b36SDavid du Colombier 		case TFLOAT:
116bd389b36SDavid du Colombier 			if(l->fval != r->fval)
117bd389b36SDavid du Colombier 				return 0;
118bd389b36SDavid du Colombier 			break;
119bd389b36SDavid du Colombier 		case TSTRING:
120bd389b36SDavid du Colombier 			if(scmp(l->string, r->string) == 0)
121bd389b36SDavid du Colombier 				return 0;
122bd389b36SDavid du Colombier 			break;
123bd389b36SDavid du Colombier 		case TLIST:
124bd389b36SDavid du Colombier 			if(listcmp(l->l, r->l) == 0)
125bd389b36SDavid du Colombier 				return 0;
126bd389b36SDavid du Colombier 			break;
127bd389b36SDavid du Colombier 		}
128bd389b36SDavid du Colombier 		l = l->next;
129bd389b36SDavid du Colombier 		r = r->next;
130bd389b36SDavid du Colombier 	}
131bd389b36SDavid du Colombier 	if(l != r)
132bd389b36SDavid du Colombier 		return 0;
133bd389b36SDavid du Colombier 	return 1;
134bd389b36SDavid du Colombier }
135bd389b36SDavid du Colombier 
136bd389b36SDavid du Colombier void
nthelem(List * l,int n,Node * res)137bd389b36SDavid du Colombier nthelem(List *l, int n, Node *res)
138bd389b36SDavid du Colombier {
139bd389b36SDavid du Colombier 	if(n < 0)
140bd389b36SDavid du Colombier 		error("negative index in []");
141bd389b36SDavid du Colombier 
142bd389b36SDavid du Colombier 	while(l && n--)
143bd389b36SDavid du Colombier 		l = l->next;
144bd389b36SDavid du Colombier 
145bd389b36SDavid du Colombier 	res->op = OCONST;
146bd389b36SDavid du Colombier 	if(l == 0) {
147bd389b36SDavid du Colombier 		res->type = TLIST;
148bd389b36SDavid du Colombier 		res->l = 0;
149bd389b36SDavid du Colombier 		return;
150bd389b36SDavid du Colombier 	}
151bd389b36SDavid du Colombier 	res->type = l->type;
152bd389b36SDavid du Colombier 	res->Store = l->Store;
153bd389b36SDavid du Colombier }
154bd389b36SDavid du Colombier 
155bd389b36SDavid du Colombier void
delete(List * l,int n,Node * res)156bd389b36SDavid du Colombier delete(List *l, int n, Node *res)
157bd389b36SDavid du Colombier {
158bd389b36SDavid du Colombier 	List **tl;
159bd389b36SDavid du Colombier 
160bd389b36SDavid du Colombier 	if(n < 0)
161bd389b36SDavid du Colombier 		error("negative index in delete");
162bd389b36SDavid du Colombier 
163bd389b36SDavid du Colombier 	res->op = OCONST;
164bd389b36SDavid du Colombier 	res->type = TLIST;
165bd389b36SDavid du Colombier 	res->l = l;
166bd389b36SDavid du Colombier 
167bd389b36SDavid du Colombier 	for(tl = &res->l; l && n--; l = l->next)
168bd389b36SDavid du Colombier 		tl = &l->next;
169bd389b36SDavid du Colombier 
170bd389b36SDavid du Colombier 	if(l == 0)
171bd389b36SDavid du Colombier 		error("element beyond end of list");
172bd389b36SDavid du Colombier 	*tl = l->next;
173bd389b36SDavid du Colombier }
174bd389b36SDavid du Colombier 
175bd389b36SDavid du Colombier List*
listvar(char * s,vlong v)176*4de34a7eSDavid du Colombier listvar(char *s, vlong v)
177bd389b36SDavid du Colombier {
178bd389b36SDavid du Colombier 	List *l, *tl;
179bd389b36SDavid du Colombier 
180bd389b36SDavid du Colombier 	tl = al(TLIST);
181bd389b36SDavid du Colombier 
182bd389b36SDavid du Colombier 	l = al(TSTRING);
183bd389b36SDavid du Colombier 	tl->l = l;
184bd389b36SDavid du Colombier 	l->fmt = 's';
185bd389b36SDavid du Colombier 	l->string = strnode(s);
186bd389b36SDavid du Colombier 	l->next = al(TINT);
187bd389b36SDavid du Colombier 	l = l->next;
188bd389b36SDavid du Colombier 	l->fmt = 'X';
189bd389b36SDavid du Colombier 	l->ival = v;
190bd389b36SDavid du Colombier 
191bd389b36SDavid du Colombier 	return tl;
192bd389b36SDavid du Colombier }
193bd389b36SDavid du Colombier 
194219b2ee8SDavid du Colombier static List*
listlocals(Map * map,Symbol * fn,uvlong fp)195*4de34a7eSDavid du Colombier listlocals(Map *map, Symbol *fn, uvlong fp)
196bd389b36SDavid du Colombier {
197bd389b36SDavid du Colombier 	int i;
198*4de34a7eSDavid du Colombier 	uvlong val;
199bd389b36SDavid du Colombier 	Symbol s;
200bd389b36SDavid du Colombier 	List **tail, *l2;
201bd389b36SDavid du Colombier 
202bd389b36SDavid du Colombier 	l2 = 0;
203bd389b36SDavid du Colombier 	tail = &l2;
204bd389b36SDavid du Colombier 	s = *fn;
205219b2ee8SDavid du Colombier 
206bd389b36SDavid du Colombier 	for(i = 0; localsym(&s, i); i++) {
207bd389b36SDavid du Colombier 		if(s.class != CAUTO)
208bd389b36SDavid du Colombier 			continue;
209bd389b36SDavid du Colombier 		if(s.name[0] == '.')
210bd389b36SDavid du Colombier 			continue;
211219b2ee8SDavid du Colombier 
212*4de34a7eSDavid du Colombier 		if(geta(map, fp-s.value, &val) > 0) {
213bd389b36SDavid du Colombier 			*tail = listvar(s.name, val);
214bd389b36SDavid du Colombier 			tail = &(*tail)->next;
215bd389b36SDavid du Colombier 		}
216bd389b36SDavid du Colombier 	}
217bd389b36SDavid du Colombier 	return l2;
218bd389b36SDavid du Colombier }
219bd389b36SDavid du Colombier 
220219b2ee8SDavid du Colombier static List*
listparams(Map * map,Symbol * fn,uvlong fp)221*4de34a7eSDavid du Colombier listparams(Map *map, Symbol *fn, uvlong fp)
222bd389b36SDavid du Colombier {
223bd389b36SDavid du Colombier 	int i;
224bd389b36SDavid du Colombier 	Symbol s;
225*4de34a7eSDavid du Colombier 	uvlong v;
226bd389b36SDavid du Colombier 	List **tail, *l2;
227bd389b36SDavid du Colombier 
228bd389b36SDavid du Colombier 	l2 = 0;
229bd389b36SDavid du Colombier 	tail = &l2;
230219b2ee8SDavid du Colombier 	fp += mach->szaddr;			/* skip saved pc */
231bd389b36SDavid du Colombier 	s = *fn;
232bd389b36SDavid du Colombier 	for(i = 0; localsym(&s, i); i++) {
233bd389b36SDavid du Colombier 		if (s.class != CPARAM)
234bd389b36SDavid du Colombier 			continue;
235219b2ee8SDavid du Colombier 
236*4de34a7eSDavid du Colombier 		if(geta(map, fp+s.value, &v) > 0) {
237bd389b36SDavid du Colombier 			*tail = listvar(s.name, v);
238bd389b36SDavid du Colombier 			tail = &(*tail)->next;
239bd389b36SDavid du Colombier 		}
240bd389b36SDavid du Colombier 	}
241bd389b36SDavid du Colombier 	return l2;
242bd389b36SDavid du Colombier }
243219b2ee8SDavid du Colombier 
244219b2ee8SDavid du Colombier void
trlist(Map * map,uvlong pc,uvlong sp,Symbol * sym)245*4de34a7eSDavid du Colombier trlist(Map *map, uvlong pc, uvlong sp, Symbol *sym)
246219b2ee8SDavid du Colombier {
247219b2ee8SDavid du Colombier 	List *q, *l;
248219b2ee8SDavid du Colombier 
249219b2ee8SDavid du Colombier 	static List **tail;
250219b2ee8SDavid du Colombier 
251219b2ee8SDavid du Colombier 	if (tracelist == 0) {		/* first time */
252219b2ee8SDavid du Colombier 		tracelist = al(TLIST);
253219b2ee8SDavid du Colombier 		tail = &tracelist;
254219b2ee8SDavid du Colombier 	}
255219b2ee8SDavid du Colombier 
256219b2ee8SDavid du Colombier 	q = al(TLIST);
257219b2ee8SDavid du Colombier 	*tail = q;
258219b2ee8SDavid du Colombier 	tail = &q->next;
259219b2ee8SDavid du Colombier 
260219b2ee8SDavid du Colombier 	l = al(TINT);			/* Function address */
261219b2ee8SDavid du Colombier 	q->l = l;
262219b2ee8SDavid du Colombier 	l->ival = sym->value;
263219b2ee8SDavid du Colombier 	l->fmt = 'X';
264219b2ee8SDavid du Colombier 
265219b2ee8SDavid du Colombier 	l->next = al(TINT);		/* called from address */
266219b2ee8SDavid du Colombier 	l = l->next;
267219b2ee8SDavid du Colombier 	l->ival = pc;
268*4de34a7eSDavid du Colombier 	l->fmt = 'Y';
269219b2ee8SDavid du Colombier 
270219b2ee8SDavid du Colombier 	l->next = al(TLIST);		/* make list of params */
271219b2ee8SDavid du Colombier 	l = l->next;
272219b2ee8SDavid du Colombier 	l->l = listparams(map, sym, sp);
273219b2ee8SDavid du Colombier 
274219b2ee8SDavid du Colombier 	l->next = al(TLIST);		/* make list of locals */
275219b2ee8SDavid du Colombier 	l = l->next;
276219b2ee8SDavid du Colombier 	l->l = listlocals(map, sym, sp);
277219b2ee8SDavid du Colombier }
278