]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/acid/list.c
etheriwl: don't break controller on command flush timeout
[plan9front.git] / sys / src / cmd / acid / list.c
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*
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
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
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*
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
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
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
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
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*
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 = 'A';
189         l->ival = v;
190
191         return tl;
192 }
193
194 static List*
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*
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
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 = 'A';
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 }