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