Blob


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"
9 void
10 error(char *fmt, ...)
11 {
12 int i;
13 char buf[2048];
14 va_list arg;
16 /* Unstack io channels */
17 if(iop != 0) {
18 for(i = 1; i < iop; i++)
19 Bterm(io[i]);
20 bout = io[0];
21 iop = 0;
22 }
24 ret = 0;
25 gotint = 0;
26 Bflush(bout);
27 if(silent)
28 silent = 0;
29 else {
30 va_start(arg, fmt);
31 vseprint(buf, buf+sizeof(buf), fmt, arg);
32 va_end(arg);
33 fprint(2, "%Z: (error) %s\n", buf);
34 }
35 while(popio())
36 ;
37 interactive = 1;
38 longjmp(err, 1);
39 }
41 void
42 unwind(void)
43 {
44 int i;
45 Lsym *s;
46 Value *v;
48 for(i = 0; i < Hashsize; i++) {
49 for(s = hash[i]; s; s = s->hash) {
50 while(s->v->pop) {
51 v = s->v->pop;
52 free(s->v);
53 s->v = v;
54 }
55 }
56 }
57 }
59 void
60 execute(Node *n)
61 {
62 Value *v;
63 Lsym *sl;
64 Node *l, *r;
65 int i, s, e;
66 Node res, xx;
67 static int stmnt;
69 gc();
70 if(gotint)
71 error("interrupted");
73 if(n == 0)
74 return;
76 if(stmnt++ > 5000) {
77 Bflush(bout);
78 stmnt = 0;
79 }
81 l = n->left;
82 r = n->right;
84 switch(n->op) {
85 default:
86 expr(n, &res);
87 if(ret || (res.type == TLIST && res.store.u.l == 0))
88 break;
89 prnt->right = &res;
90 expr(prnt, &xx);
91 break;
92 case OASGN:
93 case OCALL:
94 expr(n, &res);
95 break;
96 case OCOMPLEX:
97 decl(n);
98 break;
99 case OLOCAL:
100 for(n = n->left; n; n = n->left) {
101 if(ret == 0)
102 error("local not in function");
103 sl = n->sym;
104 if(sl->v->ret == ret)
105 error("%s declared twice", sl->name);
106 v = gmalloc(sizeof(Value));
107 v->ret = ret;
108 v->pop = sl->v;
109 sl->v = v;
110 v->scope = 0;
111 *(ret->tail) = sl;
112 ret->tail = &v->scope;
113 v->set = 0;
115 break;
116 case ORET:
117 if(ret == 0)
118 error("return not in function");
119 expr(n->left, ret->val);
120 longjmp(ret->rlab, 1);
121 case OLIST:
122 execute(n->left);
123 execute(n->right);
124 break;
125 case OIF:
126 expr(l, &res);
127 if(r && r->op == OELSE) {
128 if(bool(&res))
129 execute(r->left);
130 else
131 execute(r->right);
133 else if(bool(&res))
134 execute(r);
135 break;
136 case OWHILE:
137 for(;;) {
138 expr(l, &res);
139 if(!bool(&res))
140 break;
141 execute(r);
143 break;
144 case ODO:
145 expr(l->left, &res);
146 if(res.type != TINT)
147 error("loop must have integer start");
148 s = res.store.u.ival;
149 expr(l->right, &res);
150 if(res.type != TINT)
151 error("loop must have integer end");
152 e = res.store.u.ival;
153 for(i = s; i <= e; i++)
154 execute(r);
155 break;
159 int
160 bool(Node *n)
162 int true = 0;
164 if(n->op != OCONST)
165 fatal("bool: not const");
167 switch(n->type) {
168 case TINT:
169 if(n->store.u.ival != 0)
170 true = 1;
171 break;
172 case TFLOAT:
173 if(n->store.u.fval != 0.0)
174 true = 1;
175 break;
176 case TSTRING:
177 if(n->store.u.string->len)
178 true = 1;
179 break;
180 case TLIST:
181 if(n->store.u.l)
182 true = 1;
183 break;
185 return true;
188 void
189 convflt(Node *r, char *flt)
191 char c;
193 c = flt[0];
194 if(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
195 r->type = TSTRING;
196 r->store.fmt = 's';
197 r->store.u.string = strnode(flt);
199 else {
200 r->type = TFLOAT;
201 r->store.u.fval = atof(flt);
205 void
206 indir(Map *m, u64int addr, char fmt, Node *r)
208 int i;
209 u32int ival;
210 u64int vval;
211 int ret;
212 u8int cval;
213 u16int sval;
214 char buf[512], reg[12];
216 r->op = OCONST;
217 r->store.fmt = fmt;
218 switch(fmt) {
219 default:
220 error("bad pointer format '%c' for *", fmt);
221 case 'c':
222 case 'C':
223 case 'b':
224 r->type = TINT;
225 ret = get1(m, addr, &cval, 1);
226 if (ret < 0)
227 error("indir: %r");
228 r->store.u.ival = cval;
229 break;
230 case 'x':
231 case 'd':
232 case 'u':
233 case 'o':
234 case 'q':
235 case 'r':
236 r->type = TINT;
237 ret = get2(m, addr, &sval);
238 if (ret < 0)
239 error("indir: %r");
240 r->store.u.ival = sval;
241 break;
242 case 'a':
243 case 'A':
244 case 'B':
245 case 'X':
246 case 'D':
247 case 'U':
248 case 'O':
249 case 'Q':
250 r->type = TINT;
251 ret = get4(m, addr, &ival);
252 if (ret < 0)
253 error("indir: %r");
254 r->store.u.ival = ival;
255 break;
256 case 'V':
257 case 'W':
258 case 'Y':
259 case 'Z':
260 r->type = TINT;
261 ret = get8(m, addr, &vval);
262 if (ret < 0)
263 error("indir: %r");
264 r->store.u.ival = vval;
265 break;
266 case 's':
267 r->type = TSTRING;
268 for(i = 0; i < sizeof(buf)-1; i++) {
269 ret = get1(m, addr, (uchar*)&buf[i], 1);
270 if (ret < 0)
271 error("indir: %r");
272 addr++;
273 if(buf[i] == '\0')
274 break;
276 buf[i] = 0;
277 if(i == 0)
278 strcpy(buf, "(null)");
279 r->store.u.string = strnode(buf);
280 break;
281 case 'R':
282 r->type = TSTRING;
283 assert(sizeof(Rune) == 4);
284 for(i = 0; i < sizeof(buf)-4; i += 4) {
285 ret = get4(m, addr, &ival);
286 if (ret < 0)
287 error("indir: %r");
288 memmove(buf+i, &ival, 4);
289 addr += 4;
290 if(ival == 0)
291 break;
293 ival = 0;
294 memmove(buf+i, &ival, 4);
295 r->store.u.string = runenode((Rune*)buf);
296 break;
297 case 'i':
298 case 'I':
299 if ((*mach->das)(m, addr, fmt, buf, sizeof(buf)) < 0)
300 error("indir: %r");
301 r->type = TSTRING;
302 r->store.fmt = 's';
303 r->store.u.string = strnode(buf);
304 break;
305 case 'f':
306 ret = get1(m, addr, (uchar*)buf, mach->szfloat);
307 if (ret < 0)
308 error("indir: %r");
309 mach->ftoa32(buf, sizeof(buf), (void*) buf);
310 convflt(r, buf);
311 break;
312 case 'g':
313 ret = get1(m, addr, (uchar*)buf, mach->szfloat);
314 if (ret < 0)
315 error("indir: %r");
316 mach->ftoa32(buf, sizeof(buf), (void*) buf);
317 r->type = TSTRING;
318 r->store.u.string = strnode(buf);
319 break;
320 case 'F':
321 ret = get1(m, addr, (uchar*)buf, mach->szdouble);
322 if (ret < 0)
323 error("indir: %r");
324 mach->ftoa64(buf, sizeof(buf), (void*) buf);
325 convflt(r, buf);
326 break;
327 case '3': /* little endian ieee 80 with hole in bytes 8&9 */
328 ret = get1(m, addr, (uchar*)reg, 10);
329 if (ret < 0)
330 error("indir: %r");
331 memmove(reg+10, reg+8, 2); /* open hole */
332 memset(reg+8, 0, 2); /* fill it */
333 leieeeftoa80(buf, sizeof(buf), reg);
334 convflt(r, buf);
335 break;
336 case '8': /* big-endian ieee 80 */
337 ret = get1(m, addr, (uchar*)reg, 10);
338 if (ret < 0)
339 error("indir: %r");
340 beieeeftoa80(buf, sizeof(buf), reg);
341 convflt(r, buf);
342 break;
343 case 'G':
344 ret = get1(m, addr, (uchar*)buf, mach->szdouble);
345 if (ret < 0)
346 error("indir: %r");
347 mach->ftoa64(buf, sizeof(buf), (void*) buf);
348 r->type = TSTRING;
349 r->store.u.string = strnode(buf);
350 break;
354 void
355 indirreg(Regs *regs, char *name, char fmt, Node *r)
357 u64int val;
359 if(regs == 0)
360 error("no register set for *%s=", name);
362 r->op = OCONST;
363 r->store.fmt = fmt;
364 switch(fmt){
365 default:
366 error("bad pointer format '%c' for *%s", fmt, name);
367 case 'c':
368 case 'C':
369 case 'b':
370 case 'x':
371 case 'd':
372 case 'u':
373 case 'o':
374 case 'q':
375 case 'r':
376 case 'a':
377 case 'A':
378 case 'B':
379 case 'X':
380 case 'D':
381 case 'U':
382 case 'O':
383 case 'Q':
384 case 'V':
385 case 'W':
386 case 'Y':
387 case 'Z':
388 if(rget(regs, name, &val) < 0)
389 error("reading %s: %r", name);
390 r->type = TINT;
391 r->store.u.ival = val;
392 break;
393 case 'f':
394 case 'g':
395 case 'F':
396 case '3':
397 case '8':
398 case 'G':
399 error("floating point registers not supported");
400 break;
404 void
405 windir(Map *m, Node aes, Node *rval, Node *r)
407 uchar cval;
408 ushort sval;
409 Node res;
410 int ret;
412 if(m == 0)
413 error("no map for */@=");
415 if(aes.type != TINT)
416 error("bad type lhs of */@=");
418 expr(rval, &res);
420 if(m != cormap && wtflag == 0)
421 error("not in write mode");
423 r->type = res.type;
424 r->store.fmt = res.store.fmt;
425 r->store = res.store;
427 switch(res.store.fmt) {
428 default:
429 error("bad pointer format '%c' for */@=", res.store.fmt);
430 case 'c':
431 case 'C':
432 case 'b':
433 cval = res.store.u.ival;
434 ret = put1(m, aes.store.u.ival, &cval, 1);
435 break;
436 case 'r':
437 case 'x':
438 case 'd':
439 case 'u':
440 case 'o':
441 sval = res.store.u.ival;
442 ret = put2(m, aes.store.u.ival, sval);
443 r->store.u.ival = sval;
444 break;
445 case 'a':
446 case 'A':
447 case 'B':
448 case 'X':
449 case 'D':
450 case 'U':
451 case 'O':
452 ret = put4(m, aes.store.u.ival, res.store.u.ival);
453 break;
454 case 'V':
455 case 'W':
456 case 'Y':
457 case 'Z':
458 ret = put8(m, aes.store.u.ival, res.store.u.ival);
459 break;
460 case 's':
461 case 'R':
462 ret = put1(m, aes.store.u.ival, (uchar*)res.store.u.string->string, res.store.u.string->len);
463 break;
465 if (ret < 0)
466 error("windir: %r");
469 void
470 windirreg(Regs *regs, char *name, Node *rval, Node *r)
472 Node res;
474 if(regs == 0)
475 error("no register set for *%s=", name);
477 expr(rval, &res);
479 r->type = res.type;
480 r->store.fmt = res.store.fmt;
481 r->store = res.store;
483 switch(res.store.fmt){
484 default:
485 error("bad format '%c' for *%s=", res.store.fmt, name);
486 case 'c':
487 case 'C':
488 case 'b':
489 case 'x':
490 case 'd':
491 case 'u':
492 case 'o':
493 case 'q':
494 case 'r':
495 case 'a':
496 case 'A':
497 case 'B':
498 case 'X':
499 case 'D':
500 case 'U':
501 case 'O':
502 case 'Q':
503 case 'V':
504 case 'W':
505 case 'Y':
506 case 'Z':
507 if(rput(regs, name, res.store.u.ival) < 0)
508 error("writing %s: %r", name);
509 break;
510 case 'f':
511 case 'g':
512 case 'F':
513 case '3':
514 case '8':
515 case 'G':
516 error("floating point registers not supported");
517 break;
521 void
522 call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp)
524 int np, i;
525 Rplace rlab;
526 Node *n, res;
527 Value *v, *f;
528 Lsym *s, *next;
529 Node *avp[Maxarg], *ava[Maxarg];
531 rlab.local = 0;
533 na = 0;
534 flatten(avp, parameters);
535 np = na;
536 na = 0;
537 flatten(ava, local);
538 if(np != na) {
539 if(np < na)
540 error("%s: too few arguments", fn);
541 error("%s: too many arguments", fn);
544 rlab.tail = &rlab.local;
546 ret = &rlab;
547 for(i = 0; i < np; i++) {
548 n = ava[i];
549 switch(n->op) {
550 default:
551 error("%s: %d formal not a name", fn, i);
552 case ONAME:
553 expr(avp[i], &res);
554 s = n->sym;
555 break;
556 case OINDM:
557 res.store.u.cc = avp[i];
558 res.type = TCODE;
559 res.store.comt = 0;
560 if(n->left->op != ONAME)
561 error("%s: %d formal not a name", fn, i);
562 s = n->left->sym;
563 break;
565 if(s->v->ret == ret)
566 error("%s already declared at this scope", s->name);
568 v = gmalloc(sizeof(Value));
569 v->ret = ret;
570 v->pop = s->v;
571 s->v = v;
572 v->scope = 0;
573 *(rlab.tail) = s;
574 rlab.tail = &v->scope;
576 v->store = res.store;
577 v->type = res.type;
578 v->set = 1;
581 ret->val = retexp;
582 if(setjmp(rlab.rlab) == 0)
583 execute(body);
585 for(s = rlab.local; s; s = next) {
586 f = s->v;
587 next = f->scope;
588 s->v = f->pop;
589 free(f);