scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

   1#include <assert.h>
   2#include <stdlib.h>
   3#include <string.h>
   4
   5#include <scc/cstd.h>
   6#include <scc/scc.h>
   7#include "cc1.h"
   8
   9#define XCHG(lp, rp, np) (np = lp, lp = rp, rp = np)
  10
  11int
  12power2node(Node *np, int *log)
  13{
  14	int n;
  15	unsigned long long u;
  16	Symbol *sym;
  17
  18	if (!np || !(np->flags & NCONST) || !np->sym)
  19		return 0;
  20
  21	sym = np->sym;
  22	if (sym->type->op != INT || (u = sym->u.u) == 0)
  23		return 0;
  24
  25	for (n = 0; (u & 1) == 0; n++)
  26		u >>= 1;
  27
  28	if (log)
  29		*log = n;
  30
  31	return u == 1;
  32}
  33
  34int
  35cmpnode(Node *np, unsigned long long val)
  36{
  37	Symbol *sym;
  38	Type *tp;
  39	unsigned long long mask, nodeval;
  40
  41	if (!np || !(np->flags & NCONST) || !np->sym)
  42		return 0;
  43	sym = np->sym;
  44	tp = sym->type;
  45
  46	switch (tp->op) {
  47	case ENUM:
  48	case PTR:
  49	case INT:
  50		mask = (val > 1) ? ones(np->type->size) : -1;
  51		nodeval = (tp->prop & TSIGNED) ? sym->u.i : sym->u.u;
  52		return (nodeval & mask) == (val & mask);
  53	case FLOAT:
  54		if (tp == floattype)
  55			return sym->u.f == val;
  56		else if (tp == doubletype)
  57			return sym->u.d == val;
  58		else
  59			return sym->u.d == val;
  60		break;
  61	default:
  62		abort();
  63	}
  64	return 0;
  65}
  66
  67static Node *
  68promote(Node *np)
  69{
  70	Type *tp;
  71	Node *new;
  72	struct limits *lim, *ilim;
  73
  74	tp = np->type;
  75
  76	switch (tp->op) {
  77	case ENUM:
  78	case INT:
  79		if (tp->n.rank >= inttype->n.rank)
  80			return np;
  81		lim = getlimits(tp);
  82		ilim = getlimits(inttype);
  83		tp = (lim->max.i <= ilim->max.i) ? inttype : uinttype;
  84		break;
  85	case FLOAT:
  86		return np;
  87	default:
  88		abort();
  89	}
  90	if ((new = convert(np, tp, 1)) != NULL)
  91		return new;
  92	return np;
  93}
  94
  95static void
  96arithconv(Node **p1, Node **p2)
  97{
  98	int to = 0, s1, s2;
  99	unsigned r1, r2;
 100	Type *tp1, *tp2;
 101	Node *np1, *np2;
 102	struct limits *lp1, *lp2;
 103
 104	np1 = promote(*p1);
 105	np2 = promote(*p2);
 106
 107	tp1 = np1->type;
 108	tp2 = np2->type;
 109
 110	if (tp1 == tp2)
 111		goto set_p1_p2;
 112
 113	s1 = (tp1->prop & TSIGNED) != 0;
 114	r1 = tp1->n.rank;
 115	lp1 = getlimits(tp1);
 116
 117	s2 = (tp2->prop & TSIGNED) != 0;
 118	r2 = tp2->n.rank;
 119	lp2 = getlimits(tp2);
 120
 121	if (s1 == s2 || tp1->op == FLOAT || tp2->op == FLOAT) {
 122		to = r1 - r2;
 123	} else if (!s1) {
 124		if (r1 >= r2 || lp1->max.i >= lp2->max.i)
 125			to = 1;
 126		else
 127			to = -1;
 128	} else {
 129		if (r2 >= r1 || lp2->max.i >= lp1->max.i)
 130			to = -1;
 131		else
 132			to = 1;
 133	}
 134
 135	if (to > 0)
 136		np2 = convert(np2, tp1, 1);
 137	else if (to < 0)
 138		np1 = convert(np1, tp2, 1);
 139		
 140set_p1_p2:
 141	*p1 = np1;
 142	*p2 = np2;
 143}
 144
 145static int
 146null(Node *np)
 147{
 148	if (np->type != pvoidtype)
 149		return 0;
 150
 151	switch (np->op) {
 152	case OCAST:
 153		np = np->left;
 154		if (np->type != inttype)
 155			return 0;
 156	case OSYM:
 157		return cmpnode(np, 0);
 158	default:
 159		return 0;
 160	}
 161}
 162
 163static Node *
 164chkternary(Node *yes, Node *no)
 165{
 166	/*
 167	 * FIXME:
 168	 * We are ignoring type qualifiers here,
 169	 * but the standard has strong rules about this.
 170	 * take a look to 6.5.15
 171	 */
 172
 173	if (!eqtype(yes->type, no->type, EQUIV)) {
 174		if ((yes->type->prop & TARITH) && (no->type->prop & TARITH)) {
 175			arithconv(&yes, &no);
 176		} else if (yes->type->op != PTR && no->type->op != PTR) {
 177			goto wrong_type;
 178		} else {
 179			/* convert integer 0 to NULL */
 180			if ((yes->type->prop & TINTEGER) && cmpnode(yes, 0))
 181				yes = convert(yes, pvoidtype, 0);
 182			if ((no->type->prop & TINTEGER) && cmpnode(no, 0))
 183				no = convert(no, pvoidtype, 0);
 184			/*
 185			 * At this point the type of both should be
 186			 * a pointer to something, or we have don't
 187			 * compatible types
 188			 */
 189			if (yes->type->op != PTR || no->type->op != PTR)
 190				goto wrong_type;
 191			/*
 192			 * If we have a null pointer constant then
 193			 * convert to the another type
 194			 */
 195			if (null(yes))
 196				yes = convert(yes, no->type, 0);
 197			if (null(no))
 198				no = convert(no, yes->type, 0);
 199
 200			if (!eqtype(yes->type, no->type, EQUIV))
 201				goto wrong_type;
 202		}
 203	}
 204	return node(OCOLON, yes->type, yes, no);
 205
 206wrong_type:
 207	errorp("type mismatch in conditional expression");
 208	freetree(yes);
 209	freetree(no);
 210	return constnode(zero);
 211}
 212
 213static void
 214chklvalue(Node *np)
 215{
 216	if (!(np->flags & NLVAL))
 217		errorp("lvalue required in operation");
 218	if (np->type == voidtype)
 219		errorp("invalid use of void expression");
 220}
 221
 222static Node *
 223chkconstaddr(Node *var, Node *addr)
 224{
 225	unsigned mask = SGLOBAL|SLOCAL|SPRIVATE|SEXTERN;
 226
 227	if (var->sym && var->sym->flags & mask
 228	|| var->op == OFIELD && var->left->op == OSYM
 229	|| var->op == OFIELD && (var->left->flags & NCONST)) {
 230		addr->flags |= NCONST;
 231	}
 232
 233	return addr;
 234}
 235
 236Node *
 237decay(Node *np)
 238{
 239	Node *new;
 240	Type *tp = np->type;
 241
 242	switch (tp->op) {
 243	case ARY:
 244		DBG("EXPR decay ary");
 245		tp = tp->type;
 246		if (np->op != OPTR)
 247			goto new_node;
 248		new = np->left;
 249		free(np);
 250		new->type = mktype(tp, PTR, 0, NULL);
 251		return chkconstaddr(new, new);
 252	case FTN:
 253		DBG("EXPR decay function");
 254	new_node:
 255		new = node(OADDR, mktype(tp, PTR, 0, NULL), np, NULL);
 256		new->flags |= NDECAY;
 257		return chkconstaddr(np, new);
 258	default:
 259		return np;
 260	}
 261}
 262
 263static Node *
 264integerop(int op, Node *lp, Node *rp)
 265{
 266	if (!(lp->type->prop & TINTEGER) || !(rp->type->prop & TINTEGER))
 267		error("operator requires integer operands");
 268
 269
 270	switch (op) {
 271	case OA_MOD:
 272	case OA_SHL:
 273	case OA_SHR:
 274	case OA_AND:
 275	case OA_XOR:
 276	case OA_OR:
 277		rp = convert(rp, lp->type, 0);
 278		break;
 279	default:
 280		arithconv(&lp, &rp);
 281		break;
 282	}
 283
 284	return node(op, lp->type, lp, rp);
 285}
 286
 287static Node *
 288integeruop(int op, Node *np)
 289{
 290	if (!(np->type->prop & TINTEGER))
 291		error("unary operator requires integer operand");
 292	np = promote(np);
 293	return node(op, np->type, np, NULL);
 294}
 295
 296static Node *
 297numericaluop(int op, Node *np)
 298{
 299	if (!(np->type->prop & TARITH))
 300		error("unary operator requires numerical operand");
 301	np = promote(np);
 302	return node(op, np->type, np, NULL);
 303}
 304
 305Node *
 306convert(Node *np, Type *newtp, int iscast)
 307{
 308	Type *oldtp = np->type;
 309	int op = newtp->op;
 310
 311	if (eqtype(newtp, oldtp, EQUAL))
 312		return np;
 313	if (iscast && op == VOID)
 314		goto good_conv;
 315
 316	switch (oldtp->op) {
 317	case ENUM:
 318	case INT:
 319		if (op == PTR && (iscast || cmpnode(np, 0)))
 320			goto good_conv;
 321	case FLOAT:
 322		if (op == INT || op == FLOAT || op == ENUM)
 323			goto good_conv;
 324		return NULL;
 325	case PTR:
 326		if (op == ENUM || op == INT) {
 327			if (iscast)
 328				goto good_conv;
 329		} else if (op == PTR) {
 330			if (eqtype(newtp, oldtp, EQUIV))
 331				goto good_ptr_conv;
 332			if (iscast)
 333				goto good_ptr_conv;
 334			if (newtp == pvoidtype || oldtp == pvoidtype)
 335				goto good_ptr_conv;
 336		}
 337	default:
 338		return NULL;
 339	}
 340
 341good_ptr_conv:
 342	np->type = newtp;
 343	return np;
 344
 345good_conv:
 346	return node(OCAST, newtp, np, NULL);
 347}
 348
 349static Node *
 350parithmetic(int op, Node *lp, Node *rp)
 351{
 352	Type *tp;
 353	Node *size, *np;
 354
 355	if (lp->type->op != PTR)
 356		XCHG(lp, rp, np);
 357
 358	tp = rp->type;
 359	if (tp->op == PTR && !(tp->type->prop & TDEFINED))
 360		goto incomplete;
 361	tp = lp->type;
 362	if (!(tp->type->prop & TDEFINED))
 363		goto incomplete;
 364	size = sizeofnode(tp->type);
 365
 366	if (op == OSUB && rp->type->op == PTR) {
 367		if ((rp = convert(rp, lp->type, 0)) == NULL)
 368			goto incorrect;
 369		lp = node(OSUB, pdifftype, lp, rp);
 370		return node(ODIV, pdifftype, lp, size);
 371	}
 372	if (!(rp->type->prop & TINTEGER))
 373		goto incorrect;
 374
 375	rp = convert(promote(rp), sizettype, 0);
 376	rp = node(OMUL, sizettype, rp, size);
 377	rp = convert(rp, tp, 1);
 378
 379	return node(op, tp, lp, rp);
 380
 381incomplete:
 382	errorp("invalid use of undefined type");
 383	return lp;
 384incorrect:
 385	errorp("incorrect arithmetic operands");
 386	return lp;
 387
 388}
 389
 390static Node *
 391arithmetic(int op, Node *lp, Node *rp)
 392{
 393	Node *np;
 394	Type *ltp = lp->type, *rtp = rp->type;
 395
 396	if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {
 397		switch (op) {
 398		case OA_ADD:
 399		case OA_SUB:
 400		case OA_MUL:
 401		case OA_DIV:
 402			rp = convert(rp, lp->type, 0);
 403			break;
 404		default:
 405			arithconv(&lp, &rp);
 406			break;
 407		}
 408		return node(op, lp->type, lp, rp);
 409	} else if ((ltp->op == PTR || rtp->op == PTR)) {
 410		switch (op) {
 411		case OADD:
 412		case OSUB:
 413		case OA_ADD:
 414		case OA_SUB:
 415		case OINC:
 416		case ODEC:
 417			np = parithmetic(op, lp, rp);
 418			if ((lp->flags&NCONST) && (rp->flags&NCONST))
 419				np->flags |= NCONST;
 420			return np;
 421		}
 422	}
 423	errorp("incorrect arithmetic operands");
 424	return lp;
 425}
 426
 427static Node *
 428pcompare(int op, Node *lp, Node *rp)
 429{
 430	Node *np;
 431
 432	if (lp->type->prop&TINTEGER) {
 433		if ((np = convert(lp, rp->type, 0)) == NULL)
 434			errorp("incompatible types in comparison");
 435		else
 436			lp = np;
 437	}
 438	if (rp->type->prop&TINTEGER) {
 439		if ((np = convert(rp, lp->type, 0)) == NULL)
 440			errorp("incompatible types in comparison");
 441		else
 442			rp = np;
 443	}
 444
 445	return convert(node(op, pvoidtype, lp, rp), inttype, 1);
 446}
 447
 448static Node *
 449compare(int op, Node *lp, Node *rp)
 450{
 451	Type *ltp, *rtp;
 452
 453	ltp = lp->type;
 454	rtp = rp->type;
 455
 456	if (ltp->op == PTR || rtp->op == PTR) {
 457		return pcompare(op, lp, rp);
 458	} else if ((ltp->prop & TARITH) && (rtp->prop & TARITH)) {
 459		arithconv(&lp, &rp);
 460		return convert(node(op, lp->type, lp, rp), inttype, 1);
 461	} else {
 462		errorp("incompatible types in comparison");
 463		freetree(lp);
 464		freetree(rp);
 465		return constnode(zero);
 466	}
 467}
 468
 469int
 470negop(int op)
 471{
 472	switch (op) {
 473	case OEQ:  return ONE;
 474	case ONE:  return OEQ;
 475	case OLT:  return OGE;
 476	case OGE:  return OLT;
 477	case OLE:  return OGT;
 478	case OGT:  return OLE;
 479	default:   abort();
 480	}
 481	return op;
 482}
 483
 484static Node *
 485exp2cond(Node *np, int neg)
 486{
 487	int op;
 488
 489	if (np->type->prop & TAGGREG) {
 490		errorp("used struct/union type value where scalar is required");
 491		return constnode(zero);
 492	}
 493	switch (np->op) {
 494	case ONEG:
 495	case OOR:
 496	case OAND:
 497		return (neg) ? node(ONEG, inttype, np, NULL) : np;
 498	case OEQ:
 499	case ONE:
 500	case OLT:
 501	case OGE:
 502	case OLE:
 503	case OGT:
 504		if (neg)
 505			np->op = negop(np->op);
 506		return np;
 507	default:
 508		op = (neg) ?  OEQ : ONE;
 509		return compare(op, np, constnode(zero));
 510	}
 511}
 512
 513static Node *
 514logic(int op, Node *lp, Node *rp)
 515{
 516	lp = exp2cond(lp, 0);
 517	rp = exp2cond(rp, 0);
 518	return node(op, inttype, lp, rp);
 519}
 520
 521static Node *
 522field(Node *np)
 523{
 524	Symbol *sym;
 525
 526	namespace = np->type->ns;
 527	next();
 528	namespace = NS_IDEN;
 529
 530	sym = yylval.sym;
 531	if (yytoken != IDEN)
 532		unexpected();
 533	next();
 534
 535	if (!(np->type->prop & TAGGREG)) {
 536		errorp("request for member '%s' in something not a structure or union",
 537		      yylval.sym->name);
 538		goto free_np;
 539	}
 540	if ((sym->flags & SDECLARED) == 0) {
 541		errorp("incorrect field in struct/union");
 542		goto free_np;
 543	}
 544	np = node(OFIELD, sym->type, np, varnode(sym));
 545	np->flags |= NLVAL;
 546	return np;
 547
 548free_np:
 549	freetree(np);
 550	return constnode(zero);
 551}
 552
 553static Node *
 554content(int op, Node *np)
 555{
 556	if (np->type->op != PTR) {
 557		errorp("invalid argument of memory indirection");
 558	} else {
 559		np = node(op, np->type->type, np, NULL);
 560		np->flags |= NLVAL;
 561	}
 562	return np;
 563}
 564
 565static Node *
 566array(Node *lp, Node *rp)
 567{
 568	Type *tp;
 569	Node *np;
 570
 571	if (!(lp->type->prop & TINTEGER) && !(rp->type->prop & TINTEGER))
 572		error("array subscript is not an integer");
 573	np = arithmetic(OADD, lp, rp);
 574	tp = np->type;
 575	if (tp->op != PTR)
 576		errorp("subscripted value is neither array nor pointer");
 577	return content(OPTR, np);
 578}
 579
 580static Node *
 581assignop(int op, Node *lp, Node *rp)
 582{
 583	if ((rp = convert(rp, lp->type, 0)) == NULL) {
 584		errorp("incompatible types when assigning");
 585		return lp;
 586	}
 587
 588	return node(op, lp->type, lp, rp);
 589}
 590
 591static Node *
 592incdec(Node *np, int op)
 593{
 594	Type *tp = np->type;
 595	Node *inc;
 596
 597	chklvalue(np);
 598	np->flags |= NEFFECT;
 599
 600	if (!(tp->prop & TDEFINED)) {
 601		errorp("invalid use of undefined type");
 602		return np;
 603	} else if (tp->op == PTR && !(tp->type->prop & TDEFINED)) {
 604		errorp("%s of pointer to an incomplete type",
 605		       (op == OINC || op == OA_ADD) ? "increment" : "decrement");
 606		return np;
 607	} else if (tp->op == PTR || (tp->prop & TARITH)) {
 608		inc = constnode(one);
 609	} else {
 610		errorp("wrong type argument to increment or decrement");
 611		return np;
 612	}
 613	return arithmetic(op, np, inc);
 614}
 615
 616static Node *
 617address(int op, Node *np)
 618{
 619	Node *new;
 620	Type *tp;
 621	Symbol *sym = np->sym;
 622
 623	if ((np->flags & NDECAY) != 0) {
 624		new = np->left;
 625		free(np);
 626		np = new;
 627	}
 628	tp = np->type;
 629
 630	/*
 631	 * ansi c accepts & applied to a function name, and it generates
 632	 * a function pointer
 633	 */
 634	if (np->op == OSYM) {
 635		if (tp->op == FTN)
 636			return decay(np);
 637		if (tp->op == ARY)
 638			goto dont_check_lvalue;
 639	}
 640	chklvalue(np);
 641
 642dont_check_lvalue:
 643	if (sym && (sym->flags & SREGISTER))
 644		errorp("address of register variable '%s' requested", yytext);
 645	new = node(op, mktype(tp, PTR, 0, NULL), np, NULL);
 646
 647	return chkconstaddr(np, new);
 648}
 649
 650static Node *
 651negation(int op, Node *np)
 652{
 653	if (!(np->type->prop & TARITH) && np->type->op != PTR) {
 654		errorp("invalid argument of unary '!'");
 655		return constnode(zero);
 656	}
 657	return exp2cond(np, 1);
 658}
 659
 660static Symbol *
 661adjstrings(Symbol *sym)
 662{
 663	char *d, *s;
 664	Type *tp, *base;
 665	size_t len, n, osiz, nsiz;
 666
 667	tp = sym->type;
 668	base = tp->type;
 669	for (len = tp->n.elem; next() == STRING; len += n - 1) {
 670		if (yylval.sym->type->type != base)
 671			break;
 672
 673		d = sym->u.s;
 674		s = yylval.sym->u.s;
 675		n = yylval.sym->type->n.elem;
 676		osiz = (len-1) * base->size;
 677		nsiz = n * base->size;
 678
 679		sym->u.s = d = xrealloc(d, osiz + nsiz);
 680		memcpy(d + osiz, s, nsiz);
 681	}
 682
 683	if (tp->n.elem != len)
 684		sym->type = mktype(base, ARY, len, NULL);
 685
 686	return sym;
 687}
 688
 689static Node *
 690funcsym(Symbol *sym)
 691{
 692	char *s;
 693	Node *np;
 694
 695	sym = install(sym->ns, sym);
 696	s = curfun->name;
 697	np = constnode(newstring(s, strlen(s)+1));
 698	sym->type = np->type;
 699	sym->flags |= SHASINIT | SLOCAL | SUSED;
 700	emit(ODECL, sym);
 701	emit(OINIT, np);
 702
 703	return varnode(sym);
 704}
 705
 706/*************************************************************
 707 * grammar functions                                         *
 708 *************************************************************/
 709static Node *
 710primary(void)
 711{
 712	Node *np;
 713	Symbol *sym;
 714	Node *(*fun)(Symbol *);
 715
 716	sym = yylval.sym;
 717	switch (yytoken) {
 718	case STRING:
 719		adjstrings(sym);
 720		sym->flags |= SHASINIT;
 721		if (!disstring) {
 722			emit(ODECL, sym);
 723			emit(OINIT, constnode(sym));
 724		}
 725		return varnode(sym);
 726	case BUILTIN:
 727		fun = sym->u.fun;
 728		next();
 729		expect('(');
 730		np = (*fun)(sym);
 731		expect(')');
 732
 733		/* do not call to next */
 734		return np;
 735	case CONSTANT:
 736		np = constnode(sym);
 737		break;
 738	case DEFINED:
 739		np = defined();
 740		break;
 741	case '(':
 742		next();
 743		np = expr();
 744		expect(')');
 745
 746		/* do not call to next */
 747		return np;
 748	case IDEN:
 749		assert((sym->flags & SCONSTANT) == 0);
 750		if ((sym->flags & SDECLARED) != 0) {
 751			sym->flags |= SUSED;
 752			np = varnode(sym);
 753		} else if (namespace == NS_CPP) {
 754			np = constnode(zero);
 755		} else if (!strcmp(yytext, "__func__") && curctx > PARAMCTX) {
 756			np = funcsym(sym);
 757		} else {
 758			errorp("'%s' undeclared", yytext);
 759			sym->type = inttype;
 760			sym = install(sym->ns, sym);
 761			sym->flags |= SUSED;
 762			np = varnode(sym);
 763		}
 764		break;
 765	default:
 766		unexpected();
 767	}
 768	next();
 769
 770	return np;
 771}
 772
 773static Node *
 774arguments(Node *np)
 775{
 776	int toomany, n, op;
 777	Node *par = NULL, *arg;
 778	Type *argtype, *tp = np->type, *rettype;
 779	Type **targs = (Type *[]) {ellipsistype};
 780
 781	if (tp->op == PTR && tp->type->op == FTN) {
 782		np = content(OPTR, np);
 783		tp = np->type;
 784	}
 785	if (tp->op != FTN) {
 786		n = 1;
 787		rettype = inttype;
 788		errorp("function or function pointer expected");
 789	} else {
 790		targs = tp->p.pars;
 791		n = tp->n.elem;
 792		rettype = tp->type;
 793	}
 794
 795	expect('(');
 796	if (yytoken == ')')
 797		goto no_pars;
 798	toomany = 0;
 799
 800	do {
 801		arg = assign();
 802		argtype = *targs;
 803		if (argtype == ellipsistype) {
 804			n = 0;
 805			switch (arg->type->op) {
 806			case INT:
 807				arg = promote(arg);
 808				break;
 809			case FLOAT:
 810				if (arg->type == floattype)
 811					arg = convert(arg, doubletype, 1);
 812				break;
 813			}
 814			par = node(OPAR, arg->type, par, arg);
 815			continue;
 816		}
 817		if (--n < 0) {
 818			if (!toomany)
 819				errorp("too many arguments in function call");
 820			toomany = 1;
 821			continue;
 822		}
 823		++targs;
 824		if ((arg = convert(arg, argtype, 0)) != NULL) {
 825			par = node(OPAR, arg->type, par, arg);
 826			continue;
 827		}
 828		errorp("incompatible type for argument %d in function call",
 829		       tp->n.elem - n);
 830	} while (accept(','));
 831
 832no_pars:
 833	expect(')');
 834	if (n > 0 && *targs != ellipsistype)
 835		errorp("too few arguments in function call");
 836
 837	op = (tp->prop&TELLIPSIS) ? OCALLE : OCALL;
 838	return node(op, rettype, np, par);
 839}
 840
 841static Type *
 842gettype(Node *np)
 843{
 844	Node *new;
 845	Type *tp;
 846
 847	if (np == NULL)
 848		unexpected();
 849	if ((np->flags & NDECAY) != 0) {
 850		new = np->left;
 851		free(np);
 852		np = new;
 853	}
 854	tp = np->type;
 855	freetree(np);
 856	return tp;
 857}
 858
 859static Node *unary(void);
 860
 861static Node *
 862postfix(Node *lp)
 863{
 864	int op;
 865	Node *rp;
 866
 867	for (;;) {
 868		switch (yytoken) {
 869		case '[':
 870			next();
 871			rp = expr();
 872			expect(']');
 873			lp = array(decay(lp), rp);
 874			break;
 875		case DEC:
 876		case INC:
 877			op = (yytoken == INC) ? OINC : ODEC;
 878			lp = incdec(decay(lp), op);
 879			next();
 880			break;
 881
 882		case INDIR:
 883			lp = content(OPTR, decay(lp));
 884		case '.':
 885			lp = field(decay(lp));
 886			break;
 887		case '(':
 888			lp = arguments(decay(lp));
 889			lp->flags |= NEFFECT;
 890			break;
 891		default:
 892			return lp;
 893		}
 894	}
 895}
 896
 897static Type *
 898sizeexp(void)
 899{
 900	Node *np;
 901	Type *tp;
 902
 903	if (!accept('('))
 904		return gettype(unary());
 905
 906	switch (yytoken) {
 907	case TYPE:
 908	case TYPEIDEN:
 909		tp = typename();
 910		expect(')');
 911		break;
 912	default:
 913		np = expr();
 914		expect(')');
 915		tp = gettype(postfix(np));
 916		break;
 917	}
 918
 919	return tp;
 920}
 921
 922static Node *cast(void);
 923
 924static Node *
 925unary(void)
 926{
 927	Node *(*fun)(int, Node *), *np;
 928	int op;
 929	Type *tp;
 930
 931	switch (yytoken) {
 932	case '!': op = 0;     fun = negation;     break;
 933	case '+': op = OADD;  fun = numericaluop; break;
 934	case '-': op = OSNEG; fun = numericaluop; break;
 935	case '~': op = OCPL;  fun = integeruop;   break;
 936	case '&': op = OADDR; fun = address;      break;
 937	case '*': op = OPTR;  fun = content;      break;
 938	case SIZEOF:
 939		disstring = 1;
 940		next();
 941		tp = sizeexp();
 942		disstring = 0;
 943		if (!(tp->prop & TDEFINED))
 944			errorp("sizeof applied to an incomplete type");
 945		return sizeofnode(tp);
 946	case INC:
 947	case DEC:
 948		op = (yytoken == INC) ? OA_ADD : OA_SUB;
 949		next();
 950		np = incdec(unary(), op);
 951		goto decay;
 952	case DEFINED:
 953		return defined();
 954	default:
 955		np = postfix(primary());
 956		goto decay;
 957	}
 958
 959	next();
 960	np = (*fun)(op, cast());
 961
 962decay:
 963	return decay(np);
 964}
 965
 966static Node *
 967cast(void)
 968{
 969	Node *tmp, *np;
 970	Type *tp;
 971	static int nested;
 972
 973	if (!accept('('))
 974		return unary();
 975
 976	switch (yytoken) {
 977	case TQUALIFIER:
 978	case TYPE:
 979	case TYPEIDEN:
 980		tp = typename();
 981		expect(')');
 982
 983		if (yytoken == '{') {
 984			Symbol *sym = newsym(NS_IDEN, NULL);
 985			sym->id = newid();
 986			sym->type = tp;
 987			sym->flags |= (curctx == GLOBALCTX) ? SPRIVATE : SAUTO;
 988			initializer(sym);
 989
 990			return decay(varnode(sym));
 991		}
 992
 993		switch (tp->op) {
 994		case ARY:
 995			error("cast specifies an array type");
 996		default:
 997			tmp = cast();
 998			if ((np = convert(tmp,  tp, 1)) == NULL)
 999				error("bad type conversion requested");
1000			np->flags &= ~NLVAL;
1001		}
1002		break;
1003	default:
1004		if (nested == NR_SUBEXPR)
1005			error("too many expressions nested by parentheses");
1006		++nested;
1007		np = expr();
1008		--nested;
1009		expect(')');
1010		np = postfix(np);
1011		break;
1012	}
1013
1014	return np;
1015}
1016
1017static Node *
1018mul(void)
1019{
1020	Node *np, *(*fun)(int, Node *, Node *);
1021	int op;
1022
1023	np = cast();
1024	for (;;) {
1025		switch (yytoken) {
1026		case '*': op = OMUL; fun = arithmetic; break;
1027		case '/': op = ODIV; fun = arithmetic; break;
1028		case '%': op = OMOD; fun = integerop;  break;
1029		default: return np;
1030		}
1031		next();
1032		np = (*fun)(op, np, cast());
1033	}
1034}
1035
1036static Node *
1037add(void)
1038{
1039	int op;
1040	Node *np;
1041
1042	np = mul();
1043	for (;;) {
1044		switch (yytoken) {
1045		case '+': op = OADD; break;
1046		case '-': op = OSUB; break;
1047		default:  return np;
1048		}
1049		next();
1050		np = arithmetic(op, np, mul());
1051	}
1052}
1053
1054static Node *
1055shift(void)
1056{
1057	int op;
1058	Node *np;
1059
1060	np = add();
1061	for (;;) {
1062		switch (yytoken) {
1063		case SHL: op = OSHL; break;
1064		case SHR: op = OSHR; break;
1065		default:  return np;
1066		}
1067		next();
1068		np = integerop(op, np, add());
1069	}
1070}
1071
1072static Node *
1073relational(void)
1074{
1075	int op;
1076	Node *np;
1077
1078	np = shift();
1079	for (;;) {
1080		switch (yytoken) {
1081		case '<': op = OLT; break;
1082		case '>': op = OGT; break;
1083		case GE:  op = OGE; break;
1084		case LE:  op = OLE; break;
1085		default:  return np;
1086		}
1087		next();
1088		np = compare(op, np, shift());
1089	}
1090}
1091
1092static Node *
1093eq(void)
1094{
1095	int op;
1096	Node *np;
1097
1098	np = relational();
1099	for (;;) {
1100		switch (yytoken) {
1101		case EQ: op = OEQ; break;
1102		case NE: op = ONE; break;
1103		default: return np;
1104		}
1105		next();
1106		np = compare(op, np, relational());
1107	}
1108}
1109
1110static Node *
1111bit_and(void)
1112{
1113	Node *np;
1114
1115	np = eq();
1116	while (accept('&'))
1117		np = integerop(OBAND, np, eq());
1118	return np;
1119}
1120
1121static Node *
1122bit_xor(void)
1123{
1124	Node *np;
1125
1126	np = bit_and();
1127	while (accept('^'))
1128		np = integerop(OBXOR,  np, bit_and());
1129	return np;
1130}
1131
1132static Node *
1133bit_or(void)
1134{
1135	Node *np;
1136
1137	np = bit_xor();
1138	while (accept('|'))
1139		np = integerop(OBOR, np, bit_xor());
1140	return np;
1141}
1142
1143static Node *
1144and(void)
1145{
1146	Node *np;
1147
1148	np = bit_or();
1149	while (accept(AND))
1150		np = logic(OAND, np, bit_or());
1151	return np;
1152}
1153
1154static Node *
1155or(void)
1156{
1157	Node *np;
1158
1159	np = and();
1160	while (accept(OR))
1161		np = logic(OOR, np, and());
1162	return np;
1163}
1164
1165static Node *
1166ternary(void)
1167{
1168	Node *cond;
1169
1170	cond = or();
1171	while (accept('?')) {
1172		Node *ifyes, *ifno, *np;
1173
1174		cond = exp2cond(cond, 0);
1175		ifyes = expr();
1176		expect(':');
1177		ifno = ternary();
1178		np = chkternary(ifyes, ifno);
1179		cond = node(OASK, np->type, cond, np);
1180	}
1181	return cond;
1182}
1183
1184Node *
1185assign(void)
1186{
1187	Node *np, *(*fun)(int , Node *, Node *);
1188	int op;
1189
1190	np = ternary();
1191	for (;;) {
1192		switch (yytoken) {
1193		case '=':    op = OASSIGN; fun = assignop;   break;
1194		case MUL_EQ: op = OA_MUL;  fun = arithmetic; break;
1195		case DIV_EQ: op = OA_DIV;  fun = arithmetic; break;
1196		case MOD_EQ: op = OA_MOD;  fun = integerop;  break;
1197		case ADD_EQ: op = OA_ADD;  fun = arithmetic; break;
1198		case SUB_EQ: op = OA_SUB;  fun = arithmetic; break;
1199		case SHL_EQ: op = OA_SHL;  fun = integerop;  break;
1200		case SHR_EQ: op = OA_SHR;  fun = integerop;  break;
1201		case AND_EQ: op = OA_AND;  fun = integerop;  break;
1202		case XOR_EQ: op = OA_XOR;  fun = integerop;  break;
1203		case OR_EQ:  op = OA_OR;   fun = integerop;  break;
1204		default: return np;
1205		}
1206		chklvalue(np);
1207		np->flags |= NEFFECT;
1208		next();
1209		np = (fun)(op, np, assign());
1210	}
1211}
1212
1213Node *
1214expr(void)
1215{
1216	Node *lp, *rp;
1217
1218	lp = assign();
1219	while (accept(',')) {
1220		rp = assign();
1221		lp = node(OCOMMA, rp->type, lp, rp);
1222	}
1223
1224	return lp;
1225}
1226
1227Node *
1228iconstexpr(void)
1229{
1230	Node *np;
1231
1232	np = ternary();
1233	if (np && np->type->op == INT) {
1234		np = simplify(convert(np, inttype, 0));
1235		if (np->flags & NCONST)
1236			return np;
1237	}
1238	freetree(np);
1239	return NULL;
1240}
1241
1242Node *
1243condexpr(int neg)
1244{
1245	Node *np;
1246
1247	np = exp2cond(expr(), neg);
1248	if (np->flags & NCONST)
1249		warn("conditional expression is constant");
1250	return simplify(np);
1251}