texpr.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
texpr.c (19296B) | |
--- | |
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 int fsize[256]; | |
10 | |
11 static void | |
12 initfsize(void) | |
13 { | |
14 fsize['A'] = 4; | |
15 fsize['B'] = 4; | |
16 fsize['C'] = 1; | |
17 fsize['D'] = 4; | |
18 fsize['F'] = 8; | |
19 fsize['G'] = 8; | |
20 fsize['O'] = 4; | |
21 fsize['Q'] = 4; | |
22 fsize['R'] = 4; | |
23 fsize['S'] = 4; | |
24 fsize['U'] = 4; | |
25 fsize['V'] = 8; | |
26 fsize['X'] = 4; | |
27 fsize['Y'] = 8; | |
28 fsize['W'] = 8; | |
29 fsize['Z'] = 8; | |
30 fsize['a'] = 4; | |
31 fsize['b'] = 1; | |
32 fsize['c'] = 1; | |
33 fsize['d'] = 2; | |
34 fsize['f'] = 4; | |
35 fsize['g'] = 4; | |
36 fsize['o'] = 2; | |
37 fsize['q'] = 2; | |
38 fsize['r'] = 2; | |
39 fsize['s'] = 4; | |
40 fsize['u'] = 2; | |
41 fsize['x'] = 2; | |
42 } | |
43 | |
44 int | |
45 fmtsize(Value *v) | |
46 { | |
47 int ret; | |
48 | |
49 switch(v->store.fmt) { | |
50 default: | |
51 return fsize[(unsigned char)v->store.fmt]; | |
52 case 'i': | |
53 case 'I': | |
54 if(v->type != TINT || mach == 0) | |
55 error("no size for i fmt pointer ++/--"); | |
56 ret = (*mach->instsize)(symmap, v->store.u.ival); | |
57 if(ret < 0) { | |
58 ret = (*mach->instsize)(symmap, v->store.u.ival); | |
59 if(ret < 0) | |
60 error("%r"); | |
61 } | |
62 return ret; | |
63 } | |
64 } | |
65 | |
66 Lsym* | |
67 chklval(Node *lp) | |
68 { | |
69 Node res; | |
70 Lsym *s; | |
71 | |
72 if(lp->op == ONAME) | |
73 return lp->sym; | |
74 | |
75 if(lp->op == OCALL){ | |
76 s = chklval(lp->left); | |
77 if(strcmp(s->name, "var") == 0 | |
78 && (lp->builtin || s->proc == 0)){ | |
79 if(lp->right == 0) | |
80 error("var(string): arg count"); | |
81 expr(lp->right, &res); | |
82 if(res.type != TSTRING) | |
83 error("var(string): arg type"); | |
84 return mkvar(res.store.u.string->string); | |
85 } | |
86 } | |
87 error("need l-value"); | |
88 return nil; | |
89 } | |
90 | |
91 void | |
92 olist(Node *n, Node *res) | |
93 { | |
94 expr(n->left, res); | |
95 expr(n->right, res); | |
96 } | |
97 | |
98 void | |
99 oeval(Node *n, Node *res) | |
100 { | |
101 expr(n->left, res); | |
102 if(res->type != TCODE) | |
103 error("bad type for eval"); | |
104 expr(res->store.u.cc, res); | |
105 } | |
106 | |
107 void | |
108 ocast(Node *n, Node *res) | |
109 { | |
110 if(n->sym->lt == 0) | |
111 error("%s is not a complex type", n->sym->name); | |
112 | |
113 expr(n->left, res); | |
114 res->store.comt = n->sym->lt; | |
115 res->store.fmt = 'a'; | |
116 } | |
117 | |
118 void | |
119 oindm(Node *n, Node *res) | |
120 { | |
121 Map *m; | |
122 Node l; | |
123 | |
124 m = cormap; | |
125 if(m == 0) | |
126 m = symmap; | |
127 expr(n->left, &l); | |
128 switch(l.type){ | |
129 default: | |
130 error("bad type for *"); | |
131 case TINT: | |
132 if(m == 0) | |
133 error("no map for *"); | |
134 indir(m, l.store.u.ival, l.store.fmt, res); | |
135 res->store.comt = l.store.comt; | |
136 break; | |
137 case TREG: | |
138 indirreg(correg, l.store.u.reg.name, l.store.fmt, res); | |
139 res->store.comt = l.store.comt; | |
140 break; | |
141 case TCON: | |
142 *res = *l.store.u.con; | |
143 res->store.comt = l.store.comt; | |
144 break; | |
145 } | |
146 } | |
147 | |
148 void | |
149 oindc(Node *n, Node *res) | |
150 { | |
151 Map *m; | |
152 Node l; | |
153 | |
154 m = symmap; | |
155 if(m == 0) | |
156 m = cormap; | |
157 expr(n->left, &l); | |
158 if(l.type != TINT) | |
159 error("bad type for @"); | |
160 if(m == 0) | |
161 error("no map for @"); | |
162 indir(m, l.store.u.ival, l.store.fmt, res); | |
163 res->store.comt = l.store.comt; | |
164 } | |
165 | |
166 void | |
167 oframe(Node *n, Node *res) | |
168 { | |
169 char *p; | |
170 Node *lp; | |
171 u64int ival; | |
172 Frtype *f; | |
173 | |
174 p = n->sym->name; | |
175 while(*p && *p == '$') | |
176 p++; | |
177 lp = n->left; | |
178 if(localaddr(cormap, acidregs, p, lp->sym->name, &ival) < 0) | |
179 error("colon: %r"); | |
180 | |
181 res->store.u.ival = ival; | |
182 res->op = OCONST; | |
183 res->store.fmt = 'X'; | |
184 res->type = TINT; | |
185 | |
186 /* Try and set comt */ | |
187 for(f = n->sym->local; f; f = f->next) { | |
188 if(f->var == lp->sym) { | |
189 res->store.comt = f->type; | |
190 res->store.fmt = 'a'; | |
191 break; | |
192 } | |
193 } | |
194 } | |
195 | |
196 void | |
197 oindex(Node *n, Node *res) | |
198 { | |
199 Node l, r; | |
200 | |
201 expr(n->left, &l); | |
202 expr(n->right, &r); | |
203 | |
204 if(r.type != TINT) | |
205 error("bad type for []"); | |
206 | |
207 switch(l.type) { | |
208 default: | |
209 error("lhs[] has bad type"); | |
210 case TINT: | |
211 indir(cormap, l.store.u.ival+(r.store.u.ival*fsize[(unsi… | |
212 res->store.comt = l.store.comt; | |
213 res->store.fmt = l.store.fmt; | |
214 break; | |
215 case TLIST: | |
216 nthelem(l.store.u.l, r.store.u.ival, res); | |
217 break; | |
218 case TSTRING: | |
219 res->store.u.ival = 0; | |
220 if(r.store.u.ival >= 0 && r.store.u.ival < l.store.u.str… | |
221 int xx8; /* to get around bug in vc */ | |
222 xx8 = r.store.u.ival; | |
223 res->store.u.ival = l.store.u.string->string[xx8… | |
224 } | |
225 res->op = OCONST; | |
226 res->type = TINT; | |
227 res->store.fmt = 'c'; | |
228 break; | |
229 } | |
230 } | |
231 | |
232 void | |
233 oappend(Node *n, Node *res) | |
234 { | |
235 Node r, l; | |
236 | |
237 expr(n->left, &l); | |
238 expr(n->right, &r); | |
239 if(l.type != TLIST) | |
240 error("must append to list"); | |
241 append(res, &l, &r); | |
242 } | |
243 | |
244 void | |
245 odelete(Node *n, Node *res) | |
246 { | |
247 Node l, r; | |
248 | |
249 expr(n->left, &l); | |
250 expr(n->right, &r); | |
251 if(l.type != TLIST) | |
252 error("must delete from list"); | |
253 if(r.type != TINT) | |
254 error("delete index must be integer"); | |
255 | |
256 delete(l.store.u.l, r.store.u.ival, res); | |
257 } | |
258 | |
259 void | |
260 ohead(Node *n, Node *res) | |
261 { | |
262 Node l; | |
263 | |
264 expr(n->left, &l); | |
265 if(l.type != TLIST) | |
266 error("head needs list"); | |
267 res->op = OCONST; | |
268 if(l.store.u.l) { | |
269 res->type = l.store.u.l->type; | |
270 res->store = l.store.u.l->store; | |
271 } | |
272 else { | |
273 res->type = TLIST; | |
274 res->store.u.l = 0; | |
275 } | |
276 } | |
277 | |
278 void | |
279 otail(Node *n, Node *res) | |
280 { | |
281 Node l; | |
282 | |
283 expr(n->left, &l); | |
284 if(l.type != TLIST) | |
285 error("tail needs list"); | |
286 res->op = OCONST; | |
287 res->type = TLIST; | |
288 if(l.store.u.l) | |
289 res->store.u.l = l.store.u.l->next; | |
290 else | |
291 res->store.u.l = 0; | |
292 } | |
293 | |
294 void | |
295 oconst(Node *n, Node *res) | |
296 { | |
297 res->op = OCONST; | |
298 res->type = n->type; | |
299 res->store = n->store; | |
300 res->store.comt = n->store.comt; | |
301 } | |
302 | |
303 void | |
304 oname(Node *n, Node *res) | |
305 { | |
306 Value *v; | |
307 | |
308 v = n->sym->v; | |
309 if(v->set == 0) | |
310 error("%s used but not set", n->sym->name); | |
311 res->op = OCONST; | |
312 res->type = v->type; | |
313 res->store = v->store; | |
314 res->store.comt = v->store.comt; | |
315 } | |
316 | |
317 void | |
318 octruct(Node *n, Node *res) | |
319 { | |
320 res->op = OCONST; | |
321 res->type = TLIST; | |
322 res->store.u.l = construct(n->left); | |
323 } | |
324 | |
325 void | |
326 oasgn(Node *n, Node *res) | |
327 { | |
328 Node *lp, r; | |
329 Node aes; | |
330 Value *v; | |
331 | |
332 lp = n->left; | |
333 switch(lp->op) { | |
334 case OINDM: | |
335 expr(lp->left, &aes); | |
336 if(aes.type == TREG) | |
337 windirreg(correg, aes.store.u.reg.name, n->right… | |
338 else | |
339 windir(cormap, aes, n->right, res); | |
340 break; | |
341 case OINDC: | |
342 expr(lp->left, &aes); | |
343 windir(symmap, aes, n->right, res); | |
344 break; | |
345 default: | |
346 v = chklval(lp)->v; | |
347 expr(n->right, &r); | |
348 v->set = 1; | |
349 v->type = r.type; | |
350 v->store = r.store; | |
351 res->op = OCONST; | |
352 res->type = v->type; | |
353 res->store = v->store; | |
354 res->store.comt = v->store.comt; | |
355 } | |
356 } | |
357 | |
358 void | |
359 oadd(Node *n, Node *res) | |
360 { | |
361 Node l, r; | |
362 | |
363 expr(n->left, &l); | |
364 expr(n->right, &r); | |
365 res->store.fmt = l.store.fmt; | |
366 res->op = OCONST; | |
367 res->type = TFLOAT; | |
368 switch(l.type) { | |
369 default: | |
370 error("bad lhs type +"); | |
371 case TINT: | |
372 switch(r.type) { | |
373 case TINT: | |
374 res->type = TINT; | |
375 res->store.u.ival = l.store.u.ival+r.store.u.iva… | |
376 break; | |
377 case TFLOAT: | |
378 res->store.u.fval = l.store.u.ival+r.store.u.fva… | |
379 break; | |
380 default: | |
381 error("bad rhs type +"); | |
382 } | |
383 break; | |
384 case TFLOAT: | |
385 switch(r.type) { | |
386 case TINT: | |
387 res->store.u.fval = l.store.u.fval+r.store.u.iva… | |
388 break; | |
389 case TFLOAT: | |
390 res->store.u.fval = l.store.u.fval+r.store.u.fva… | |
391 break; | |
392 default: | |
393 error("bad rhs type +"); | |
394 } | |
395 break; | |
396 case TSTRING: | |
397 if(r.type == TSTRING) { | |
398 res->type = TSTRING; | |
399 res->store.fmt = 's'; | |
400 res->store.u.string = stradd(l.store.u.string, r… | |
401 break; | |
402 } | |
403 error("bad rhs for +"); | |
404 case TLIST: | |
405 res->type = TLIST; | |
406 switch(r.type) { | |
407 case TLIST: | |
408 res->store.u.l = addlist(l.store.u.l, r.store.u.… | |
409 break; | |
410 default: | |
411 r.left = 0; | |
412 r.right = 0; | |
413 res->store.u.l = addlist(l.store.u.l, construct(… | |
414 break; | |
415 } | |
416 } | |
417 } | |
418 | |
419 void | |
420 osub(Node *n, Node *res) | |
421 { | |
422 Node l, r; | |
423 | |
424 expr(n->left, &l); | |
425 expr(n->right, &r); | |
426 res->store.fmt = l.store.fmt; | |
427 res->op = OCONST; | |
428 res->type = TFLOAT; | |
429 switch(l.type) { | |
430 default: | |
431 error("bad lhs type -"); | |
432 case TINT: | |
433 switch(r.type) { | |
434 case TINT: | |
435 res->type = TINT; | |
436 res->store.u.ival = l.store.u.ival-r.store.u.iva… | |
437 break; | |
438 case TFLOAT: | |
439 res->store.u.fval = l.store.u.ival-r.store.u.fva… | |
440 break; | |
441 default: | |
442 error("bad rhs type -"); | |
443 } | |
444 break; | |
445 case TFLOAT: | |
446 switch(r.type) { | |
447 case TINT: | |
448 res->store.u.fval = l.store.u.fval-r.store.u.iva… | |
449 break; | |
450 case TFLOAT: | |
451 res->store.u.fval = l.store.u.fval-r.store.u.fva… | |
452 break; | |
453 default: | |
454 error("bad rhs type -"); | |
455 } | |
456 break; | |
457 } | |
458 } | |
459 | |
460 void | |
461 omul(Node *n, Node *res) | |
462 { | |
463 Node l, r; | |
464 | |
465 expr(n->left, &l); | |
466 expr(n->right, &r); | |
467 res->store.fmt = l.store.fmt; | |
468 res->op = OCONST; | |
469 res->type = TFLOAT; | |
470 switch(l.type) { | |
471 default: | |
472 error("bad lhs type *"); | |
473 case TINT: | |
474 switch(r.type) { | |
475 case TINT: | |
476 res->type = TINT; | |
477 res->store.u.ival = l.store.u.ival*r.store.u.iva… | |
478 break; | |
479 case TFLOAT: | |
480 res->store.u.fval = l.store.u.ival*r.store.u.fva… | |
481 break; | |
482 default: | |
483 error("bad rhs type *"); | |
484 } | |
485 break; | |
486 case TFLOAT: | |
487 switch(r.type) { | |
488 case TINT: | |
489 res->store.u.fval = l.store.u.fval*r.store.u.iva… | |
490 break; | |
491 case TFLOAT: | |
492 res->store.u.fval = l.store.u.fval*r.store.u.fva… | |
493 break; | |
494 default: | |
495 error("bad rhs type *"); | |
496 } | |
497 break; | |
498 } | |
499 } | |
500 | |
501 void | |
502 odiv(Node *n, Node *res) | |
503 { | |
504 Node l, r; | |
505 | |
506 expr(n->left, &l); | |
507 expr(n->right, &r); | |
508 res->store.fmt = l.store.fmt; | |
509 res->op = OCONST; | |
510 res->type = TFLOAT; | |
511 switch(l.type) { | |
512 default: | |
513 error("bad lhs type /"); | |
514 case TINT: | |
515 switch(r.type) { | |
516 case TINT: | |
517 res->type = TINT; | |
518 if(r.store.u.ival == 0) | |
519 error("zero divide"); | |
520 res->store.u.ival = l.store.u.ival/r.store.u.iva… | |
521 break; | |
522 case TFLOAT: | |
523 if(r.store.u.fval == 0) | |
524 error("zero divide"); | |
525 res->store.u.fval = l.store.u.ival/r.store.u.fva… | |
526 break; | |
527 default: | |
528 error("bad rhs type /"); | |
529 } | |
530 break; | |
531 case TFLOAT: | |
532 switch(r.type) { | |
533 case TINT: | |
534 res->store.u.fval = l.store.u.fval/r.store.u.iva… | |
535 break; | |
536 case TFLOAT: | |
537 res->store.u.fval = l.store.u.fval/r.store.u.fva… | |
538 break; | |
539 default: | |
540 error("bad rhs type /"); | |
541 } | |
542 break; | |
543 } | |
544 } | |
545 | |
546 void | |
547 omod(Node *n, Node *res) | |
548 { | |
549 Node l, r; | |
550 | |
551 expr(n->left, &l); | |
552 expr(n->right, &r); | |
553 res->store.fmt = l.store.fmt; | |
554 res->op = OCONST; | |
555 res->type = TINT; | |
556 if(l.type != TINT || r.type != TINT) | |
557 error("bad expr type %"); | |
558 res->store.u.ival = l.store.u.ival%r.store.u.ival; | |
559 } | |
560 | |
561 void | |
562 olsh(Node *n, Node *res) | |
563 { | |
564 Node l, r; | |
565 | |
566 expr(n->left, &l); | |
567 expr(n->right, &r); | |
568 res->store.fmt = l.store.fmt; | |
569 res->op = OCONST; | |
570 res->type = TINT; | |
571 if(l.type != TINT || r.type != TINT) | |
572 error("bad expr type <<"); | |
573 res->store.u.ival = l.store.u.ival<<r.store.u.ival; | |
574 } | |
575 | |
576 void | |
577 orsh(Node *n, Node *res) | |
578 { | |
579 Node l, r; | |
580 | |
581 expr(n->left, &l); | |
582 expr(n->right, &r); | |
583 res->store.fmt = l.store.fmt; | |
584 res->op = OCONST; | |
585 res->type = TINT; | |
586 if(l.type != TINT || r.type != TINT) | |
587 error("bad expr type >>"); | |
588 res->store.u.ival = (unsigned)l.store.u.ival>>r.store.u.ival; | |
589 } | |
590 | |
591 void | |
592 olt(Node *n, Node *res) | |
593 { | |
594 Node l, r; | |
595 | |
596 expr(n->left, &l); | |
597 expr(n->right, &r); | |
598 | |
599 res->store.fmt = l.store.fmt; | |
600 res->op = OCONST; | |
601 res->type = TINT; | |
602 switch(l.type) { | |
603 default: | |
604 error("bad lhs type <"); | |
605 case TINT: | |
606 switch(r.type) { | |
607 case TINT: | |
608 res->store.u.ival = l.store.u.ival < r.store.u.i… | |
609 break; | |
610 case TFLOAT: | |
611 res->store.u.ival = l.store.u.ival < r.store.u.f… | |
612 break; | |
613 default: | |
614 error("bad rhs type <"); | |
615 } | |
616 break; | |
617 case TFLOAT: | |
618 switch(r.type) { | |
619 case TINT: | |
620 res->store.u.ival = l.store.u.fval < r.store.u.i… | |
621 break; | |
622 case TFLOAT: | |
623 res->store.u.ival = l.store.u.fval < r.store.u.f… | |
624 break; | |
625 default: | |
626 error("bad rhs type <"); | |
627 } | |
628 break; | |
629 } | |
630 } | |
631 | |
632 void | |
633 ogt(Node *n, Node *res) | |
634 { | |
635 Node l, r; | |
636 | |
637 expr(n->left, &l); | |
638 expr(n->right, &r); | |
639 res->store.fmt = 'D'; | |
640 res->op = OCONST; | |
641 res->type = TINT; | |
642 switch(l.type) { | |
643 default: | |
644 error("bad lhs type >"); | |
645 case TINT: | |
646 switch(r.type) { | |
647 case TINT: | |
648 res->store.u.ival = l.store.u.ival > r.store.u.i… | |
649 break; | |
650 case TFLOAT: | |
651 res->store.u.ival = l.store.u.ival > r.store.u.f… | |
652 break; | |
653 default: | |
654 error("bad rhs type >"); | |
655 } | |
656 break; | |
657 case TFLOAT: | |
658 switch(r.type) { | |
659 case TINT: | |
660 res->store.u.ival = l.store.u.fval > r.store.u.i… | |
661 break; | |
662 case TFLOAT: | |
663 res->store.u.ival = l.store.u.fval > r.store.u.f… | |
664 break; | |
665 default: | |
666 error("bad rhs type >"); | |
667 } | |
668 break; | |
669 } | |
670 } | |
671 | |
672 void | |
673 oleq(Node *n, Node *res) | |
674 { | |
675 Node l, r; | |
676 | |
677 expr(n->left, &l); | |
678 expr(n->right, &r); | |
679 res->store.fmt = 'D'; | |
680 res->op = OCONST; | |
681 res->type = TINT; | |
682 switch(l.type) { | |
683 default: | |
684 error("bad expr type <="); | |
685 case TINT: | |
686 switch(r.type) { | |
687 case TINT: | |
688 res->store.u.ival = l.store.u.ival <= r.store.u.… | |
689 break; | |
690 case TFLOAT: | |
691 res->store.u.ival = l.store.u.ival <= r.store.u.… | |
692 break; | |
693 default: | |
694 error("bad expr type <="); | |
695 } | |
696 break; | |
697 case TFLOAT: | |
698 switch(r.type) { | |
699 case TINT: | |
700 res->store.u.ival = l.store.u.fval <= r.store.u.… | |
701 break; | |
702 case TFLOAT: | |
703 res->store.u.ival = l.store.u.fval <= r.store.u.… | |
704 break; | |
705 default: | |
706 error("bad expr type <="); | |
707 } | |
708 break; | |
709 } | |
710 } | |
711 | |
712 void | |
713 ogeq(Node *n, Node *res) | |
714 { | |
715 Node l, r; | |
716 | |
717 expr(n->left, &l); | |
718 expr(n->right, &r); | |
719 res->store.fmt = 'D'; | |
720 res->op = OCONST; | |
721 res->type = TINT; | |
722 switch(l.type) { | |
723 default: | |
724 error("bad lhs type >="); | |
725 case TINT: | |
726 switch(r.type) { | |
727 case TINT: | |
728 res->store.u.ival = l.store.u.ival >= r.store.u.… | |
729 break; | |
730 case TFLOAT: | |
731 res->store.u.ival = l.store.u.ival >= r.store.u.… | |
732 break; | |
733 default: | |
734 error("bad rhs type >="); | |
735 } | |
736 break; | |
737 case TFLOAT: | |
738 switch(r.type) { | |
739 case TINT: | |
740 res->store.u.ival = l.store.u.fval >= r.store.u.… | |
741 break; | |
742 case TFLOAT: | |
743 res->store.u.ival = l.store.u.fval >= r.store.u.… | |
744 break; | |
745 default: | |
746 error("bad rhs type >="); | |
747 } | |
748 break; | |
749 } | |
750 } | |
751 | |
752 void | |
753 oeq(Node *n, Node *res) | |
754 { | |
755 Node l, r; | |
756 | |
757 expr(n->left, &l); | |
758 expr(n->right, &r); | |
759 res->store.fmt = 'D'; | |
760 res->op = OCONST; | |
761 res->type = TINT; | |
762 res->store.u.ival = 0; | |
763 switch(l.type) { | |
764 default: | |
765 break; | |
766 case TINT: | |
767 switch(r.type) { | |
768 case TINT: | |
769 res->store.u.ival = l.store.u.ival == r.store.u.… | |
770 break; | |
771 case TFLOAT: | |
772 res->store.u.ival = l.store.u.ival == r.store.u.… | |
773 break; | |
774 default: | |
775 break; | |
776 } | |
777 break; | |
778 case TFLOAT: | |
779 switch(r.type) { | |
780 case TINT: | |
781 res->store.u.ival = l.store.u.fval == r.store.u.… | |
782 break; | |
783 case TFLOAT: | |
784 res->store.u.ival = l.store.u.fval == r.store.u.… | |
785 break; | |
786 default: | |
787 break; | |
788 } | |
789 break; | |
790 case TSTRING: | |
791 if(r.type == TSTRING) { | |
792 res->store.u.ival = scmp(r.store.u.string, l.sto… | |
793 break; | |
794 } | |
795 break; | |
796 case TLIST: | |
797 if(r.type == TLIST) { | |
798 res->store.u.ival = listcmp(l.store.u.l, r.store… | |
799 break; | |
800 } | |
801 break; | |
802 } | |
803 if(n->op == ONEQ) | |
804 res->store.u.ival = !res->store.u.ival; | |
805 } | |
806 | |
807 | |
808 void | |
809 oland(Node *n, Node *res) | |
810 { | |
811 Node l, r; | |
812 | |
813 expr(n->left, &l); | |
814 expr(n->right, &r); | |
815 res->store.fmt = l.store.fmt; | |
816 res->op = OCONST; | |
817 res->type = TINT; | |
818 if(l.type != TINT || r.type != TINT) | |
819 error("bad expr type &"); | |
820 res->store.u.ival = l.store.u.ival&r.store.u.ival; | |
821 } | |
822 | |
823 void | |
824 oxor(Node *n, Node *res) | |
825 { | |
826 Node l, r; | |
827 | |
828 expr(n->left, &l); | |
829 expr(n->right, &r); | |
830 res->store.fmt = l.store.fmt; | |
831 res->op = OCONST; | |
832 res->type = TINT; | |
833 if(l.type != TINT || r.type != TINT) | |
834 error("bad expr type ^"); | |
835 res->store.u.ival = l.store.u.ival^r.store.u.ival; | |
836 } | |
837 | |
838 void | |
839 olor(Node *n, Node *res) | |
840 { | |
841 Node l, r; | |
842 | |
843 expr(n->left, &l); | |
844 expr(n->right, &r); | |
845 res->store.fmt = l.store.fmt; | |
846 res->op = OCONST; | |
847 res->type = TINT; | |
848 if(l.type != TINT || r.type != TINT) | |
849 error("bad expr type |"); | |
850 res->store.u.ival = l.store.u.ival|r.store.u.ival; | |
851 } | |
852 | |
853 void | |
854 ocand(Node *n, Node *res) | |
855 { | |
856 Node l, r; | |
857 | |
858 res->store.fmt = 'D'; | |
859 res->op = OCONST; | |
860 res->type = TINT; | |
861 res->store.u.ival = 0; | |
862 expr(n->left, &l); | |
863 res->store.fmt = l.store.fmt; | |
864 if(bool(&l) == 0) | |
865 return; | |
866 expr(n->right, &r); | |
867 if(bool(&r) == 0) | |
868 return; | |
869 res->store.u.ival = 1; | |
870 } | |
871 | |
872 void | |
873 onot(Node *n, Node *res) | |
874 { | |
875 Node l; | |
876 | |
877 res->op = OCONST; | |
878 res->type = TINT; | |
879 res->store.u.ival = 0; | |
880 expr(n->left, &l); | |
881 if(bool(&l) == 0) | |
882 res->store.u.ival = 1; | |
883 } | |
884 | |
885 void | |
886 ocor(Node *n, Node *res) | |
887 { | |
888 Node l, r; | |
889 | |
890 res->op = OCONST; | |
891 res->type = TINT; | |
892 res->store.u.ival = 0; | |
893 expr(n->left, &l); | |
894 if(bool(&l)) { | |
895 res->store.u.ival = 1; | |
896 return; | |
897 } | |
898 expr(n->right, &r); | |
899 if(bool(&r)) { | |
900 res->store.u.ival = 1; | |
901 return; | |
902 } | |
903 } | |
904 | |
905 void | |
906 oeinc(Node *n, Node *res) | |
907 { | |
908 Value *v; | |
909 | |
910 v = chklval(n->left)->v; | |
911 res->op = OCONST; | |
912 res->type = v->type; | |
913 switch(v->type) { | |
914 case TINT: | |
915 if(n->op == OEDEC) | |
916 v->store.u.ival -= fmtsize(v); | |
917 else | |
918 v->store.u.ival += fmtsize(v); | |
919 break; | |
920 case TFLOAT: | |
921 if(n->op == OEDEC) | |
922 v->store.u.fval--; | |
923 else | |
924 v->store.u.fval++; | |
925 break; | |
926 default: | |
927 error("bad type for pre --/++"); | |
928 } | |
929 res->store = v->store; | |
930 } | |
931 | |
932 void | |
933 opinc(Node *n, Node *res) | |
934 { | |
935 Value *v; | |
936 | |
937 v = chklval(n->left)->v; | |
938 res->op = OCONST; | |
939 res->type = v->type; | |
940 res->store = v->store; | |
941 switch(v->type) { | |
942 case TINT: | |
943 if(n->op == OPDEC) | |
944 v->store.u.ival -= fmtsize(v); | |
945 else | |
946 v->store.u.ival += fmtsize(v); | |
947 break; | |
948 case TFLOAT: | |
949 if(n->op == OPDEC) | |
950 v->store.u.fval--; | |
951 else | |
952 v->store.u.fval++; | |
953 break; | |
954 default: | |
955 error("bad type for post --/++"); | |
956 } | |
957 } | |
958 | |
959 void | |
960 ocall(Node *n, Node *res) | |
961 { | |
962 Lsym *s; | |
963 Rplace *rsav; | |
964 | |
965 res->op = OCONST; /* Default return value */ | |
966 res->type = TLIST; | |
967 res->store.u.l = 0; | |
968 | |
969 s = chklval(n->left); | |
970 if(n->builtin && !s->builtin){ | |
971 error("no builtin %s", s->name); | |
972 return; | |
973 } | |
974 if(s->builtin && (n->builtin || s->proc == 0)) { | |
975 (*s->builtin)(res, n->right); | |
976 return; | |
977 } | |
978 if(s->proc == 0) | |
979 error("no function %s", s->name); | |
980 | |
981 rsav = ret; | |
982 call(s->name, n->right, s->proc->left, s->proc->right, res); | |
983 ret = rsav; | |
984 } | |
985 | |
986 void | |
987 ofmt(Node *n, Node *res) | |
988 { | |
989 expr(n->left, res); | |
990 res->store.fmt = n->right->store.u.ival; | |
991 } | |
992 | |
993 void | |
994 ouplus(Node *n, Node *res) | |
995 { | |
996 expr(n->left, res); | |
997 } | |
998 | |
999 void | |
1000 owhat(Node *n, Node *res) | |
1001 { | |
1002 res->op = OCONST; /* Default return value */ | |
1003 res->type = TLIST; | |
1004 res->store.u.l = 0; | |
1005 whatis(n->sym); | |
1006 } | |
1007 | |
1008 void (*expop[NUMO])(Node*, Node*); | |
1009 | |
1010 static void | |
1011 initexpop(void) | |
1012 { | |
1013 expop[ONAME] = oname; | |
1014 expop[OCONST] = oconst; | |
1015 expop[OMUL] = omul; | |
1016 expop[ODIV] = odiv; | |
1017 expop[OMOD] = omod; | |
1018 expop[OADD] = oadd; | |
1019 expop[OSUB] = osub; | |
1020 expop[ORSH] = orsh; | |
1021 expop[OLSH] = olsh; | |
1022 expop[OLT] = olt; | |
1023 expop[OGT] = ogt; | |
1024 expop[OLEQ] = oleq; | |
1025 expop[OGEQ] = ogeq; | |
1026 expop[OEQ] = oeq; | |
1027 expop[ONEQ] = oeq; | |
1028 expop[OLAND] = oland; | |
1029 expop[OXOR] = oxor; | |
1030 expop[OLOR] = olor; | |
1031 expop[OCAND] = ocand; | |
1032 expop[OCOR] = ocor; | |
1033 expop[OASGN] = oasgn; | |
1034 expop[OINDM] = oindm; | |
1035 expop[OEDEC] = oeinc; | |
1036 expop[OEINC] = oeinc; | |
1037 expop[OPINC] = opinc; | |
1038 expop[OPDEC] = opinc; | |
1039 expop[ONOT] = onot; | |
1040 expop[OIF] = 0; | |
1041 expop[ODO] = 0; | |
1042 expop[OLIST] = olist; | |
1043 expop[OCALL] = ocall; | |
1044 expop[OCTRUCT] = octruct; | |
1045 expop[OWHILE] =0; | |
1046 expop[OELSE] = 0; | |
1047 expop[OHEAD] = ohead; | |
1048 expop[OTAIL] = otail; | |
1049 expop[OAPPEND] = oappend; | |
1050 expop[ORET] = 0; | |
1051 expop[OINDEX] =oindex; | |
1052 expop[OINDC] = oindc; | |
1053 expop[ODOT] = odot; | |
1054 expop[OLOCAL] =0; | |
1055 expop[OFRAME] = oframe; | |
1056 expop[OCOMPLEX] =0; | |
1057 expop[ODELETE] = odelete; | |
1058 expop[OCAST] = ocast; | |
1059 expop[OFMT] = ofmt; | |
1060 expop[OEVAL] = oeval; | |
1061 expop[OWHAT] = owhat; | |
1062 expop[OUPLUS] = ouplus; | |
1063 } | |
1064 | |
1065 void | |
1066 initexpr(void) | |
1067 { | |
1068 initfsize(); | |
1069 initexpop(); | |
1070 } | |
1071 | |
1072 int | |
1073 acidregsrw(Regs *r, char *name, u64int *u, int isr) | |
1074 { | |
1075 Lsym *l; | |
1076 Value *v; | |
1077 Node *n; | |
1078 u64int addr; | |
1079 | |
1080 if(!isr){ | |
1081 werrstr("cannot write registers"); | |
1082 return -1; | |
1083 } | |
1084 USED(r); | |
1085 l = look(name); | |
1086 if(l == nil){ | |
1087 werrstr("register %s not found", name); | |
1088 return -1; | |
1089 } | |
1090 v = l->v; | |
1091 switch(v->type){ | |
1092 default: | |
1093 werrstr("*%s: bad type", name); | |
1094 return -1; | |
1095 case TREG: | |
1096 if(correg == nil){ | |
1097 werrstr("*%s: register %s not mapped", name, v->… | |
1098 return -1; | |
1099 } | |
1100 return rget(correg, v->store.u.reg.name, u); | |
1101 case TCON: | |
1102 n = v->store.u.con; | |
1103 if(n->op != OCONST || n->type != TINT){ | |
1104 werrstr("*%s: bad register constant", name); | |
1105 return -1; | |
1106 } | |
1107 *u = n->store.u.ival; | |
1108 return 0; | |
1109 case TINT: | |
1110 if(cormap == nil){ | |
1111 werrstr("*%s: core not mapped", name); | |
1112 return -1; | |
1113 } | |
1114 addr = v->store.u.ival; | |
1115 /* XXX should use format to determine size */ | |
1116 if(geta(cormap, addr, u) < 0) | |
1117 return -1; | |
1118 return 0; | |
1119 } | |
1120 } |