* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / expr.c
blobb8cb08b614eb8c9ad5a9dbb6aadf71f26dc6cc1c
1 #include "c.h"
4 static char prec[] = {
5 #define xx(a,b,c,d,e,f,g) c,
6 #define yy(a,b,c,d,e,f,g) c,
7 #include "token.h"
8 };
9 static int oper[] = {
10 #define xx(a,b,c,d,e,f,g) d,
11 #define yy(a,b,c,d,e,f,g) d,
12 #include "token.h"
14 float refinc = 1.0;
15 static Tree expr2(void);
16 static Tree expr3(int);
17 static Tree nullcheck(Tree);
18 static Tree postfix(Tree);
19 static Tree unary(void);
20 static Tree primary(void);
21 static Type super(Type ty);
23 static Type super(Type ty) {
24 switch (ty->op) {
25 case INT:
26 if (ty->size < inttype->size)
27 return inttype;
28 break;
29 case UNSIGNED:
30 if (ty->size < unsignedtype->size)
31 return unsignedtype;
32 break;
33 case POINTER:
34 return unsignedptr;
36 return ty;
38 Tree expr(int tok) {
39 static char stop[] = { IF, ID, '}', 0 };
40 Tree p = expr1(0);
42 while (t == ',') {
43 Tree q;
44 t = gettok();
45 q = pointer(expr1(0));
46 p = tree(RIGHT, q->type, root(value(p)), q);
48 if (tok)
49 test(tok, stop);
50 return p;
52 Tree expr0(int tok) {
53 return root(expr(tok));
55 Tree expr1(int tok) {
56 static char stop[] = { IF, ID, 0 };
57 Tree p = expr2();
59 if (t == '='
60 || (prec[t] >= 6 && prec[t] <= 8)
61 || (prec[t] >= 11 && prec[t] <= 13)) {
62 int op = t;
63 t = gettok();
64 if (oper[op] == ASGN)
65 p = asgntree(ASGN, p, value(expr1(0)));
66 else
68 expect('=');
69 p = incr(op, p, expr1(0));
72 if (tok)
73 test(tok, stop);
74 return p;
76 Tree incr(int op, Tree v, Tree e) {
77 return asgntree(ASGN, v, (*optree[op])(oper[op], v, e));
79 static Tree expr2(void) {
80 Tree p = expr3(4);
82 if (t == '?') {
83 Tree l, r;
84 Coordinate pts[2];
85 if (Aflag > 1 && isfunc(p->type))
86 warning("%s used in a conditional expression\n",
87 funcname(p));
88 p = pointer(p);
89 t = gettok();
90 pts[0] = src;
91 l = pointer(expr(':'));
92 pts[1] = src;
93 r = pointer(expr2());
94 if (events.points)
96 apply(events.points, &pts[0], &l);
97 apply(events.points, &pts[1], &r);
99 p = condtree(p, l, r);
101 return p;
103 Tree value(Tree p) {
104 int op = generic(rightkid(p)->op);
106 if (p->type != voidtype
107 && (op==AND || op==OR || op==NOT || op==EQ || op==NE
108 || op== LE || op==LT || op== GE || op==GT))
109 p = condtree(p, consttree(1, inttype),
110 consttree(0, inttype));
111 return p;
113 static Tree expr3(int k) {
114 int k1;
115 Tree p = unary();
117 for (k1 = prec[t]; k1 >= k; k1--)
118 while (prec[t] == k1 && *cp != '=') {
119 Tree r;
120 Coordinate pt;
121 int op = t;
122 t = gettok();
123 pt = src;
124 p = pointer(p);
125 if (op == ANDAND || op == OROR) {
126 r = pointer(expr3(k1));
127 if (events.points)
128 apply(events.points, &pt, &r);
129 } else
130 r = pointer(expr3(k1 + 1));
131 p = (*optree[op])(oper[op], p, r);
133 return p;
135 static Tree unary(void) {
136 Tree p;
138 switch (t) {
139 case '*': t = gettok(); p = unary(); p = pointer(p);
140 if (isptr(p->type)
141 && (isfunc(p->type->type) || isarray(p->type->type)))
142 p = retype(p, p->type->type);
143 else {
144 if (YYnull)
145 p = nullcheck(p);
146 p = rvalue(p);
147 } break;
148 case '&': t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type))
149 p = retype(p, ptr(p->type));
150 else
151 p = lvalue(p);
152 if (isaddrop(p->op) && p->u.sym->sclass == REGISTER)
153 error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name);
155 else if (isaddrop(p->op))
156 p->u.sym->addressed = 1;
157 break;
158 case '+': t = gettok(); p = unary(); p = pointer(p);
159 if (isarith(p->type))
160 p = cast(p, promote(p->type));
161 else
162 typeerror(ADD, p, NULL); break;
163 case '-': t = gettok(); p = unary(); p = pointer(p);
164 if (isarith(p->type)) {
165 Type ty = promote(p->type);
166 p = cast(p, ty);
167 if (isunsigned(ty)) {
168 warning("unsigned operand of unary -\n");
169 p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL));
170 } else
171 p = simplify(NEG, ty, p, NULL);
172 } else
173 typeerror(SUB, p, NULL); break;
174 case '~': t = gettok(); p = unary(); p = pointer(p);
175 if (isint(p->type)) {
176 Type ty = promote(p->type);
177 p = simplify(BCOM, ty, cast(p, ty), NULL);
178 } else
179 typeerror(BCOM, p, NULL); break;
180 case '!': t = gettok(); p = unary(); p = pointer(p);
181 if (isscalar(p->type))
182 p = simplify(NOT, inttype, cond(p), NULL);
183 else
184 typeerror(NOT, p, NULL); break;
185 case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break;
186 case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break;
187 case TYPECODE: case SIZEOF: { int op = t;
188 Type ty;
189 p = NULL;
190 t = gettok();
191 if (t == '(') {
192 t = gettok();
193 if (istypename(t, tsym)) {
194 ty = typename();
195 expect(')');
196 } else {
197 p = postfix(expr(')'));
198 ty = p->type;
200 } else {
201 p = unary();
202 ty = p->type;
204 assert(ty);
205 if (op == TYPECODE)
206 p = cnsttree(inttype, (long)ty->op);
207 else {
208 if (isfunc(ty) || ty->size == 0)
209 error("invalid type argument `%t' to `sizeof'\n", ty);
210 else if (p && rightkid(p)->op == FIELD)
211 error("`sizeof' applied to a bit field\n");
212 p = cnsttree(unsignedlong, (unsigned long)ty->size);
213 } } break;
214 case '(':
215 t = gettok();
216 if (istypename(t, tsym)) {
217 Type ty, ty1 = typename(), pty;
218 expect(')');
219 ty = unqual(ty1);
220 if (isenum(ty)) {
221 Type ty2 = ty->type;
222 if (isconst(ty1))
223 ty2 = qual(CONST, ty2);
224 if (isvolatile(ty1))
225 ty2 = qual(VOLATILE, ty2);
226 ty1 = ty2;
227 ty = ty->type;
229 p = pointer(unary());
230 pty = p->type;
231 if (isenum(pty))
232 pty = pty->type;
233 if ((isarith(pty) && isarith(ty))
234 || (isptr(pty) && isptr(ty))) {
235 explicitCast++;
236 p = cast(p, ty);
237 explicitCast--;
238 } else if ((isptr(pty) && isint(ty))
239 || (isint(pty) && isptr(ty))) {
240 if (Aflag >= 1 && ty->size < pty->size)
241 warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, ty);
243 p = cast(p, ty);
244 } else if (ty != voidtype) {
245 error("cast from `%t' to `%t' is illegal\n",
246 p->type, ty1);
247 ty1 = inttype;
249 if (generic(p->op) == INDIR || ty->size == 0)
250 p = tree(RIGHT, ty1, NULL, p);
251 else
252 p = retype(p, ty1);
253 } else
254 p = postfix(expr(')'));
255 break;
256 default:
257 p = postfix(primary());
259 return p;
262 static Tree postfix(Tree p) {
263 for (;;)
264 switch (t) {
265 case INCR: p = tree(RIGHT, p->type,
266 tree(RIGHT, p->type,
268 incr(t, p, consttree(1, inttype))),
270 t = gettok(); break;
271 case DECR: p = tree(RIGHT, p->type,
272 tree(RIGHT, p->type,
274 incr(t, p, consttree(1, inttype))),
276 t = gettok(); break;
277 case '[': {
278 Tree q;
279 t = gettok();
280 q = expr(']');
281 if (YYnull) {
282 if (isptr(p->type))
283 p = nullcheck(p);
284 else if (isptr(q->type))
285 q = nullcheck(q);
287 p = (*optree['+'])(ADD, pointer(p), pointer(q));
288 if (isptr(p->type) && isarray(p->type->type))
289 p = retype(p, p->type->type);
290 else
291 p = rvalue(p);
292 } break;
293 case '(': {
294 Type ty;
295 Coordinate pt;
296 p = pointer(p);
297 if (isptr(p->type) && isfunc(p->type->type))
298 ty = p->type->type;
299 else {
300 error("found `%t' expected a function\n", p->type);
301 ty = func(voidtype, NULL, 1);
302 p = retype(p, ptr(ty));
304 pt = src;
305 t = gettok();
306 p = call(p, ty, pt);
307 } break;
308 case '.': t = gettok();
309 if (t == ID) {
310 if (isstruct(p->type)) {
311 Tree q = addrof(p);
312 p = field(q, token);
313 q = rightkid(q);
314 if (isaddrop(q->op) && q->u.sym->temporary)
315 p = tree(RIGHT, p->type, p, NULL);
316 } else
317 error("left operand of . has incompatible type `%t'\n",
318 p->type);
319 t = gettok();
320 } else
321 error("field name expected\n"); break;
322 case DEREF: t = gettok();
323 p = pointer(p);
324 if (t == ID) {
325 if (isptr(p->type) && isstruct(p->type->type)) {
326 if (YYnull)
327 p = nullcheck(p);
328 p = field(p, token);
329 } else
330 error("left operand of -> has incompatible type `%t'\n", p->type);
332 t = gettok();
333 } else
334 error("field name expected\n"); break;
335 default:
336 return p;
339 static Tree primary(void) {
340 Tree p;
342 assert(t != '(');
343 switch (t) {
344 case ICON:
345 case FCON: p = tree(mkop(CNST,tsym->type), tsym->type, NULL, NULL);
346 p->u.v = tsym->u.c.v;
347 break;
348 case SCON: if (ischar(tsym->type->type))
349 tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size);
350 else
351 tsym->u.c.v.p = memcpy(allocate(tsym->type->size, PERM), tsym->u.c.v.p, tsym->type->size);
352 tsym = constant(tsym->type, tsym->u.c.v);
353 if (tsym->u.c.loc == NULL)
354 tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL);
355 p = idtree(tsym->u.c.loc); break;
356 case ID: if (tsym == NULL)
358 Symbol p = install(token, &identifiers, level, FUNC);
359 p->src = src;
360 if (getchr() == '(') {
361 Symbol q = lookup(token, externals);
362 p->type = func(inttype, NULL, 1);
363 p->sclass = EXTERN;
364 if (Aflag >= 1)
365 warning("missing prototype\n");
366 if (q && !eqtype(q->type, p->type, 1))
367 warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);
369 if (q == NULL) {
370 q = install(p->name, &externals, GLOBAL, PERM);
371 q->type = p->type;
372 q->sclass = EXTERN;
373 q->src = src;
374 (*IR->defsymbol)(q);
376 p->u.alias = q;
377 } else {
378 error("undeclared identifier `%s'\n", p->name);
379 p->sclass = AUTO;
380 p->type = inttype;
381 if (p->scope == GLOBAL)
382 (*IR->defsymbol)(p);
383 else
384 addlocal(p);
386 t = gettok();
387 if (xref)
388 use(p, src);
389 return idtree(p);
391 if (xref)
392 use(tsym, src);
393 if (tsym->sclass == ENUM)
394 p = consttree(tsym->u.value, inttype);
395 else {
396 if (tsym->sclass == TYPEDEF)
397 error("illegal use of type name `%s'\n", tsym->name);
398 p = idtree(tsym);
399 } break;
400 case FIRSTARG:
401 if (level > PARAM && cfunc && cfunc->u.f.callee[0])
402 p = idtree(cfunc->u.f.callee[0]);
403 else {
404 error("illegal use of `%k'\n", FIRSTARG);
405 p = cnsttree(inttype, 0L);
407 break;
408 default:
409 error("illegal expression\n");
410 p = cnsttree(inttype, 0L);
412 t = gettok();
413 return p;
415 Tree idtree(Symbol p) {
416 int op;
417 Tree e;
418 Type ty = p->type ? unqual(p->type) : voidptype;
420 if (p->scope == GLOBAL || p->sclass == STATIC)
421 op = ADDRG;
422 else if (p->scope == PARAM) {
423 op = ADDRF;
424 if (isstruct(p->type) && !IR->wants_argb)
426 e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL);
427 e->u.sym = p;
428 return rvalue(rvalue(e));
430 } else if (p->sclass == EXTERN) {
431 assert(p->u.alias);
432 p = p->u.alias;
433 op = ADDRG;
434 } else
435 op = ADDRL;
436 p->ref += refinc;
437 if (isarray(ty))
438 e = tree(mkop(op,voidptype), p->type, NULL, NULL);
439 else if (isfunc(ty))
440 e = tree(mkop(op,funcptype), p->type, NULL, NULL);
441 else
442 e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL);
443 e->u.sym = p;
444 if (isptr(e->type))
445 e = rvalue(e);
446 return e;
449 Tree rvalue(Tree p) {
450 Type ty = deref(p->type);
452 ty = unqual(ty);
453 return tree(mkop(INDIR,ty), ty, p, NULL);
455 Tree lvalue(Tree p) {
456 if (generic(p->op) != INDIR) {
457 error("lvalue required\n");
458 return value(p);
459 } else if (unqual(p->type) == voidtype)
460 warning("`%t' used as an lvalue\n", p->type);
461 return p->kids[0];
463 Tree retype(Tree p, Type ty) {
464 Tree q;
466 if (p->type == ty)
467 return p;
468 q = tree(p->op, ty, p->kids[0], p->kids[1]);
469 q->node = p->node;
470 q->u = p->u;
471 return q;
473 Tree rightkid(Tree p) {
474 while (p && p->op == RIGHT)
475 if (p->kids[1])
476 p = p->kids[1];
477 else if (p->kids[0])
478 p = p->kids[0];
479 else
480 assert(0);
481 assert(p);
482 return p;
484 int hascall(Tree p) {
485 if (p == 0)
486 return 0;
487 if (generic(p->op) == CALL || (IR->mulops_calls &&
488 (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I
489 || p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))
490 return 1;
491 return hascall(p->kids[0]) || hascall(p->kids[1]);
493 Type binary(Type xty, Type yty) {
494 #define xx(t) if (xty == t || yty == t) return t
495 xx(longdouble);
496 xx(doubletype);
497 xx(floattype);
498 xx(unsignedlonglong);
499 xx(longlong);
500 xx(unsignedlong);
501 if ((xty == longtype && yty == unsignedtype)
502 || (xty == unsignedtype && yty == longtype)) {
503 if (longtype->size > unsignedtype->size)
504 return longtype;
505 else
506 return unsignedlong;
508 xx(longtype);
509 xx(unsignedtype);
510 return inttype;
511 #undef xx
513 Tree pointer(Tree p) {
514 if (isarray(p->type))
515 /* assert(p->op != RIGHT || p->u.sym == NULL), */
516 p = retype(p, atop(p->type));
517 else if (isfunc(p->type))
518 p = retype(p, ptr(p->type));
519 return p;
521 Tree cond(Tree p) {
522 int op = generic(rightkid(p)->op);
524 if (op == AND || op == OR || op == NOT
525 || op == EQ || op == NE
526 || op == LE || op == LT || op == GE || op == GT)
527 return p;
528 p = pointer(p);
529 return (*optree[NEQ])(NE, p, consttree(0, inttype));
531 Tree cast(Tree p, Type type) {
532 Type src, dst;
534 p = value(p);
535 if (p->type == type)
536 return p;
537 dst = unqual(type);
538 src = unqual(p->type);
539 if (src->op != dst->op || src->size != dst->size) {
540 switch (src->op) {
541 case INT:
542 if (src->size < inttype->size)
543 p = simplify(CVI, inttype, p, NULL);
544 break;
545 case UNSIGNED:
546 if (src->size < inttype->size)
547 p = simplify(CVU, inttype, p, NULL);
548 else if (src->size < unsignedtype->size)
549 p = simplify(CVU, unsignedtype, p, NULL);
550 break;
551 case ENUM:
552 p = retype(p, inttype);
553 break;
554 case POINTER:
555 if (isint(dst) && src->size > dst->size)
556 warning("conversion from `%t' to `%t' is undefined\n", p->type, type);
557 p = simplify(CVP, super(src), p, NULL);
558 break;
559 case FLOAT:
560 break;
561 default: assert(0);
564 src = unqual(p->type);
565 dst = super(dst);
566 if (src->op != dst->op)
567 switch (src->op) {
568 case INT:
569 p = simplify(CVI, dst, p, NULL);
570 break;
571 case UNSIGNED:
572 if (isfloat(dst)) {
573 Type ssrc = signedint(src);
574 Tree two = cnsttree(longdouble, (double)2.0);
575 p = (*optree['+'])(ADD,
576 (*optree['*'])(MUL,
577 two,
578 simplify(CVU, ssrc,
579 simplify(RSH, src,
580 p, consttree(1, inttype)), NULL)),
581 simplify(CVU, ssrc,
582 simplify(BAND, src,
583 p, consttree(1, unsignedtype)), NULL));
584 } else
585 p = simplify(CVU, dst, p, NULL);
586 break;
587 case FLOAT:
588 if (isunsigned(dst)) {
589 Type sdst = signedint(dst);
590 Tree c = cast(cnsttree(longdouble, (double)sdst->u.sym->u.limits.max.i + 1), src);
591 p = condtree(
592 simplify(GE, src, p, c),
593 (*optree['+'])(ADD,
594 cast(cast(simplify(SUB, src, p, c), sdst), dst),
595 cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)),
596 simplify(CVF, sdst, p, NULL));
597 } else
598 p = simplify(CVF, dst, p, NULL);
599 break;
600 default: assert(0);
602 dst = unqual(type);
605 src = unqual(p->type);
606 switch (src->op) {
607 case INT:
608 if (src->op != dst->op || src->size != dst->size)
609 p = simplify(CVI, dst, p, NULL);
610 break;
611 case UNSIGNED:
612 if (src->op != dst->op || src->size != dst->size)
613 p = simplify(CVU, dst, p, NULL);
614 break;
615 case FLOAT:
616 if (src->op != dst->op || src->size != dst->size)
617 p = simplify(CVF, dst, p, NULL);
618 break;
619 case POINTER:
620 if (src->op != dst->op)
621 p = simplify(CVP, dst, p, NULL);
622 else {
623 if ((isfunc(src->type) && !isfunc(dst->type))
624 || (!isfunc(src->type) && isfunc(dst->type)))
625 warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);
627 if (src->size != dst->size)
628 p = simplify(CVP, dst, p, NULL);
630 break;
631 default: assert(0);
633 return retype(p, type);
635 Tree field(Tree p, const char *name) {
636 Field q;
637 Type ty1, ty = p->type;
639 if (isptr(ty))
640 ty = deref(ty);
641 ty1 = ty;
642 ty = unqual(ty);
643 if ((q = fieldref(name, ty)) != NULL) {
644 if (isarray(q->type)) {
645 ty = q->type->type;
646 if (isconst(ty1) && !isconst(ty))
647 ty = qual(CONST, ty);
648 if (isvolatile(ty1) && !isvolatile(ty))
649 ty = qual(VOLATILE, ty);
650 ty = array(ty, q->type->size/ty->size, q->type->align);
651 } else {
652 ty = q->type;
653 if (isconst(ty1) && !isconst(ty))
654 ty = qual(CONST, ty);
655 if (isvolatile(ty1) && !isvolatile(ty))
656 ty = qual(VOLATILE, ty);
657 ty = ptr(ty);
659 if (YYcheck && !isaddrop(p->op) && q->offset > 0) /* omit */
660 p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype)); /* omit */
661 else /* omit */
662 p = simplify(ADD+P, ty, p, consttree(q->offset, inttype));
664 if (q->lsb) {
665 p = tree(FIELD, ty->type, rvalue(p), NULL);
666 p->u.field = q;
667 } else if (!isarray(q->type))
668 p = rvalue(p);
670 } else {
671 error("unknown field `%s' of `%t'\n", name, ty);
672 p = rvalue(retype(p, ptr(inttype)));
674 return p;
676 /* funcname - return name of function f or a function' */
677 char *funcname(Tree f) {
678 if (isaddrop(f->op))
679 return stringf("`%s'", f->u.sym->name);
680 return "a function";
682 static Tree nullcheck(Tree p) {
683 if (!needconst && YYnull && isptr(p->type)) {
684 p = value(p);
685 if (strcmp(YYnull->name, "_YYnull") == 0) {
686 Symbol t1 = temporary(REGISTER, voidptype);
687 p = tree(RIGHT, p->type,
688 tree(OR, voidtype,
689 cond(asgn(t1, cast(p, voidptype))),
690 vcall(YYnull, voidtype, (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL)),
691 idtree(t1));
694 else
695 p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L));
698 return p;
700 Tree nullcall(Type pty, Symbol f, Tree p, Tree e) {
701 Type ty;
703 if (isarray(pty))
704 return retype(nullcall(atop(pty), f, p, e), pty);
705 ty = unqual(unqual(p->type)->type);
706 return vcall(f, pty,
707 p, e,
708 cnsttree(inttype, (long)ty->size),
709 cnsttree(inttype, (long)ty->align),
710 (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL);