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, ulong 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 for(i = 0; i < sizeof(buf)-2; i += 2) {
284 ret = get1(m, addr, (uchar*)&buf[i], 2);
285 if (ret < 0)
286 error("indir: %r");
287 addr += 2;
288 if(buf[i] == 0 && buf[i+1] == 0)
289 break;
291 buf[i++] = 0;
292 buf[i] = 0;
293 r->store.u.string = runenode((Rune*)buf);
294 break;
295 case 'i':
296 case 'I':
297 if ((*mach->das)(m, addr, fmt, buf, sizeof(buf)) < 0)
298 error("indir: %r");
299 r->type = TSTRING;
300 r->store.fmt = 's';
301 r->store.u.string = strnode(buf);
302 break;
303 case 'f':
304 ret = get1(m, addr, (uchar*)buf, mach->szfloat);
305 if (ret < 0)
306 error("indir: %r");
307 mach->ftoa32(buf, sizeof(buf), (void*) buf);
308 convflt(r, buf);
309 break;
310 case 'g':
311 ret = get1(m, addr, (uchar*)buf, mach->szfloat);
312 if (ret < 0)
313 error("indir: %r");
314 mach->ftoa32(buf, sizeof(buf), (void*) buf);
315 r->type = TSTRING;
316 r->store.u.string = strnode(buf);
317 break;
318 case 'F':
319 ret = get1(m, addr, (uchar*)buf, mach->szdouble);
320 if (ret < 0)
321 error("indir: %r");
322 mach->ftoa64(buf, sizeof(buf), (void*) buf);
323 convflt(r, buf);
324 break;
325 case '3': /* little endian ieee 80 with hole in bytes 8&9 */
326 ret = get1(m, addr, (uchar*)reg, 10);
327 if (ret < 0)
328 error("indir: %r");
329 memmove(reg+10, reg+8, 2); /* open hole */
330 memset(reg+8, 0, 2); /* fill it */
331 leieeeftoa80(buf, sizeof(buf), reg);
332 convflt(r, buf);
333 break;
334 case '8': /* big-endian ieee 80 */
335 ret = get1(m, addr, (uchar*)reg, 10);
336 if (ret < 0)
337 error("indir: %r");
338 beieeeftoa80(buf, sizeof(buf), reg);
339 convflt(r, buf);
340 break;
341 case 'G':
342 ret = get1(m, addr, (uchar*)buf, mach->szdouble);
343 if (ret < 0)
344 error("indir: %r");
345 mach->ftoa64(buf, sizeof(buf), (void*) buf);
346 r->type = TSTRING;
347 r->store.u.string = strnode(buf);
348 break;
352 void
353 indirreg(Regs *regs, char *name, char fmt, Node *r)
355 ulong val;
357 if(regs == 0)
358 error("no register set for *%s=", name);
360 r->op = OCONST;
361 r->store.fmt = fmt;
362 switch(fmt){
363 default:
364 error("bad pointer format '%c' for *%s", fmt, name);
365 case 'c':
366 case 'C':
367 case 'b':
368 case 'x':
369 case 'd':
370 case 'u':
371 case 'o':
372 case 'q':
373 case 'r':
374 case 'a':
375 case 'A':
376 case 'B':
377 case 'X':
378 case 'D':
379 case 'U':
380 case 'O':
381 case 'Q':
382 case 'V':
383 case 'W':
384 case 'Y':
385 case 'Z':
386 if(rget(regs, name, &val) < 0)
387 error("reading %s: %r", name);
388 r->type = TINT;
389 r->store.u.ival = val;
390 break;
391 case 'f':
392 case 'g':
393 case 'F':
394 case '3':
395 case '8':
396 case 'G':
397 error("floating point registers not supported");
398 break;
402 void
403 windir(Map *m, Node aes, Node *rval, Node *r)
405 uchar cval;
406 ushort sval;
407 Node res;
408 int ret;
410 if(m == 0)
411 error("no map for */@=");
413 if(aes.type != TINT)
414 error("bad type lhs of */@=");
416 expr(rval, &res);
418 if(m != cormap && wtflag == 0)
419 error("not in write mode");
421 r->type = res.type;
422 r->store.fmt = res.store.fmt;
423 r->store = res.store;
425 switch(res.store.fmt) {
426 default:
427 error("bad pointer format '%c' for */@=", res.store.fmt);
428 case 'c':
429 case 'C':
430 case 'b':
431 cval = res.store.u.ival;
432 ret = put1(m, aes.store.u.ival, &cval, 1);
433 break;
434 case 'r':
435 case 'x':
436 case 'd':
437 case 'u':
438 case 'o':
439 sval = res.store.u.ival;
440 ret = put2(m, aes.store.u.ival, sval);
441 r->store.u.ival = sval;
442 break;
443 case 'a':
444 case 'A':
445 case 'B':
446 case 'X':
447 case 'D':
448 case 'U':
449 case 'O':
450 ret = put4(m, aes.store.u.ival, res.store.u.ival);
451 break;
452 case 'V':
453 case 'W':
454 case 'Y':
455 case 'Z':
456 ret = put8(m, aes.store.u.ival, res.store.u.ival);
457 break;
458 case 's':
459 case 'R':
460 ret = put1(m, aes.store.u.ival, (uchar*)res.store.u.string->string, res.store.u.string->len);
461 break;
463 if (ret < 0)
464 error("windir: %r");
467 void
468 windirreg(Regs *regs, char *name, Node *rval, Node *r)
470 Node res;
472 if(regs == 0)
473 error("no register set for *%s=", name);
475 expr(rval, &res);
477 r->type = res.type;
478 r->store.fmt = res.store.fmt;
479 r->store = res.store;
481 switch(res.store.fmt){
482 default:
483 error("bad format '%c' for *%s=", res.store.fmt, name);
484 case 'c':
485 case 'C':
486 case 'b':
487 case 'x':
488 case 'd':
489 case 'u':
490 case 'o':
491 case 'q':
492 case 'r':
493 case 'a':
494 case 'A':
495 case 'B':
496 case 'X':
497 case 'D':
498 case 'U':
499 case 'O':
500 case 'Q':
501 case 'V':
502 case 'W':
503 case 'Y':
504 case 'Z':
505 if(rput(regs, name, res.store.u.ival) < 0)
506 error("writing %s: %r", name);
507 break;
508 case 'f':
509 case 'g':
510 case 'F':
511 case '3':
512 case '8':
513 case 'G':
514 error("floating point registers not supported");
515 break;
519 void
520 call(char *fn, Node *parameters, Node *local, Node *body, Node *retexp)
522 int np, i;
523 Rplace rlab;
524 Node *n, res;
525 Value *v, *f;
526 Lsym *s, *next;
527 Node *avp[Maxarg], *ava[Maxarg];
529 rlab.local = 0;
531 na = 0;
532 flatten(avp, parameters);
533 np = na;
534 na = 0;
535 flatten(ava, local);
536 if(np != na) {
537 if(np < na)
538 error("%s: too few arguments", fn);
539 error("%s: too many arguments", fn);
542 rlab.tail = &rlab.local;
544 ret = &rlab;
545 for(i = 0; i < np; i++) {
546 n = ava[i];
547 switch(n->op) {
548 default:
549 error("%s: %d formal not a name", fn, i);
550 case ONAME:
551 expr(avp[i], &res);
552 s = n->sym;
553 break;
554 case OINDM:
555 res.store.u.cc = avp[i];
556 res.type = TCODE;
557 res.store.comt = 0;
558 if(n->left->op != ONAME)
559 error("%s: %d formal not a name", fn, i);
560 s = n->left->sym;
561 break;
563 if(s->v->ret == ret)
564 error("%s already declared at this scope", s->name);
566 v = gmalloc(sizeof(Value));
567 v->ret = ret;
568 v->pop = s->v;
569 s->v = v;
570 v->scope = 0;
571 *(rlab.tail) = s;
572 rlab.tail = &v->scope;
574 v->store = res.store;
575 v->type = res.type;
576 v->set = 1;
579 ret->val = retexp;
580 if(setjmp(rlab.rlab) == 0)
581 execute(body);
583 for(s = rlab.local; s; s = next) {
584 f = s->v;
585 next = f->scope;
586 s->v = f->pop;
587 free(f);