V3/c/c01.c

Compare this file to the similar file:
Show the results in this format:

build(op) {
	extern cp[], cvtab, opdope[], maprel[];
	auto p1[], t1, d1, p2[], t2, d2, p3[], t3, d3, t;
	auto d, dope, leftc, cvn, pcvn;
	char cvtab[];

	if (op==4)  {		/* [] */
		build(40);	/* + */
		op = 36;	/* * */
	}
	dope = opdope[op];
	if ((dope&01)!=0) {	/* binary */
		p2 = disarray(*--cp);
		t2 = p2[1];
		chkfun(p2);
		d2 = p2[2];
		if (*p2==20)
			d2 = 0;
	}
	p1 = disarray(*--cp);
	if (op!=100 & op!=35)		/* call, * */
		chkfun(p1);
	t1 = p1[1];
	d1 = p1[2];
	if (*p1==20)
		d1 = 0;
	pcvn = 0;
	switch (op) {

	/* : */
	case 8:
		if (t1!=t2)
			error("Type clash in conditional");
		t = t1;
		goto nocv;

	/* , */
	case 9:
		*cp++ = block(2, 9, 0, 0, p1, p2);
		return;

	/* ? */
	case 90:
		if (*p2!=8)
			error("Illegal conditional");
		t = t2;
		goto nocv;

	/* call */
	case 100:
		if ((t1&030) != 020)
			error("Call of non-function");
		*cp++ = block(2,100,decref(t1),24,p1,p2);
		return;

	/* * */
	case 36:
		if (*p1==35 | *p1==29) {	/* & unary */
			*cp++ = p1[3];
			return;
		}
		if (*p1!=20 & d1==0)
			d1 = 1;
		if ((t1&030) == 020)		/* function */
			error("Illegal indirection");
		*cp++ = block(1,36,decref(t1),d1,p1);
		return;

	/* & unary */
	case 35:
		if (*p1==36) {			/* * */
			*cp++ = p1[3];
			return;
		}
		if (*p1==20) {
			*cp++ = block(1,p1[3]==5?29:35,incref(t1),1,p1);
			return;
		}
		error("Illegal lvalue");
		break;

	case 43:	/* / */
	case 44:	/* % */
	case 73:	/* =/ */
	case 74:	/* =% */
		d1++;
		d2++;

	case 42:	/* * */
	case 72:	/* =* */
		d1++;
		d2++;
		break;

	case 30:	/* ++ -- pre and post */
	case 31:
	case 32:
	case 33:
		chklval(p1);
		*cp++ = block(2,op,t1,max(d1,1),p1,plength(p1));
		return;

	case 39:	/* . (structure ref) */
	case 50:	/* -> (indirect structure ref) */
		if (p2[0]!=20 | p2[3]!=4)		/* not mos */
			error("Illegal structure ref");
		*cp++ = p1;
		t = t2;
		if ((t&030) == 030)	/* array */
			t = decref(t);
		setype(p1, t);
		if (op==39)		/* is "." */
			build(35);	/* unary & */
		*cp++ = block(1,21,7,0,p2[5]);
		build(40);		/* + */
		if ((t2&030) != 030)	/* not array */
			build(36);	/* unary * */
		return;
	}
	if ((dope&02)!=0)		/* lvalue needed on left? */
		chklval(p1);
	if ((dope&020)!=0)		/* word operand on left? */
		chkw(p1);
	if ((dope&040)!=0)		/* word operand on right? */
		chkw(p2);
	if ((dope&01)==0) {		/* unary op? */
		*cp++ = block(1,op,t1,max(d1,1),p1);
		return;
	}
	if (t2==7) {
		t = t1;
		p2[1] = 0;	/* no int cv for struct */
		t2 = 0;
		goto nocv;
	}
	cvn = cvtab[11*lintyp(t1)+lintyp(t2)];
	leftc = cvn&0100;
	t = leftc? t2:t1;
	if (op==80 & t1!=4 & t2!=4) {	/* = */
		t = t1;
		if (leftc | cvn!=1)
			goto nocv;
	}
	if (cvn =& 077) {
		if (cvn==077) {
	illcv:
			error("Illegal conversion");
			goto nocv;
		}
		if (cvn>4 & cvn<10) {		/* ptr conv */
			t = 0;			/* integer result */
			cvn = 0;
			if ((dope&04)!=0)	/* relational? */
				goto nocv;
			if (op!=41)	/* - */
				goto illcv;
			pcvn = cvn;
			goto nocv;
		}
		if (leftc) {
			if ((dope&010) != 0) {	/* =op */
				if (cvn == 1) {
					leftc = 0;
					cvn = 8;
					t = t1;
					goto rcvt;
				} else
					goto illcv;
			}
			d1 = (p1=convert(p1, t, d1, cvn, plength(p2)))[2];
		} else {
		rcvt:
			d2 = (p2=convert(p2, t, d2, cvn, plength(p1)))[2];
		}
nocv:;		}
	if (d1==d2)
		d = d1+1; else
		d = max(d1,d2);
	if ((dope&04)!=0) {		/* relational? */
		if (op>61 & t>=010)
			op =+ 4;	  /* ptr relation */
		t = 0;		/* relational is integer */
	}
	*cp++ = optim(block(2,op,t,d,p1,p2));
	if (pcvn) {
		p1 = *--cp;
		*cp++ = block(1,50+pcvn,0,d,p1);
	}
	return;
	*cp++ = block(1,op,t1,d1==0?1:d1,p1);
}

setype(p, t)
int p[];
{
	int p1[];

	if ((p[1]&07) != 4)		/* not structure */
		return;
	p[1] = t;
	switch(*p) {

	case 29:		/* & */
	case 35:
		setype(p[3], decref(t));
		return;

	case 36:		/* * */
		setype(p[3], incref(t));
		return;

	case 40:		/* + */
		setype(p[4], t);
	}
}

chkfun(p)
int p[];
{
	if ((p[1]&030)==020)	/* func */
		error("Illegal use of function");
}

optim(p)
int p[];
{
	int p1[], p2[], t;

	if (*p != 40)				/* + */
		return(p);
	p1 = p[3];
	p2 = p[4];
	if (*p1==21) {				/* const */
		t = p1;
		p1 = p2;
		p2 = t;
	}
	if (*p2 != 21)				/* const */
		return(p);
	if ((t=p2[3]) == 0)			/* const 0 */
		return(p1);
	if (*p1!=35 & *p1!=29)			/* not & */
		return(p);
	p2 = p1[3];
	if (*p2!=20) {				/* name? */
		error("C error (optim)");
		return(p);
	}
	p2[4] =+ t;
	return(p1);
}

disarray(p)
int p[];
{
	extern cp;
	int t, cp[];

	if (((t = p[1]) & 030)!=030 | p[0]==20&p[3]==4)	/* array & not MOS */
		return(p);
	p[1] = decref(t);
	*cp++ = p;
	build(35);				/* add & */
	return(*--cp);
}

convert(p, t, d, cvn, len)
int p[];
{
	int c, p1[];

	if (*p==21) {		/* constant */
		c = p[3];
		switch(cvn) {

		case 4:		/* int -> double[] */
			c =<< 1;

		case 3:		/* int -> float[] */
			c =<< 1;

		case 2:		/* int -> int[] */
			c =<< 1;
			p[3] = c;
			return(p);

		case 10:	/* i -> s[] */
			p[3] = c*len;
			return(p);
		}
	}
	if (cvn==10)			/* i -> s[]; retrun i*len */
		return(block(2,42,t,d+2,p,block(1,21,0,0,len)));
	return(block(1, 50+cvn, t, max(1,d), p));
}

chkw(p)
int p[]; {
	extern error;
	auto t;

	if ((t=p[1])>1 & t<=07)
		error("Integer operand required");
	return;
}

lintyp(t)
{
	if (t<=07)
		return(t);
	if ((t&037)==t)
		return((t&07)+5);
	return(10);
}

error(s, p1, p2, p3, p4, p5, p6) {
	extern line, fout, nerror;
	int f;

	nerror++;
	flush();
	f = fout;
	fout = 1;
	printf("%d: ", line);
	printf(s, p1, p2, p3, p4, p5, p6);
	putchar('\n');
	fout = f;
}

block(n, op, t, d, p1,p2,p3)
int p1[],p2[],p3[]; {
	int p[], ap[], space[];
	extern space;

	ap = &op;
	n =+ 3;
	p = space;
	while(n--)
		pblock(*ap++);
	return(p);
}

pblock(p)
{
	extern space, osleft;
	int space[];

	*space++ = p;
	if (--osleft<=0) {
		error("Expression overflow");
		exit(1);
	}
}

chklval(p)
int p[]; {
	extern error;

	if (*p!=20 & *p !=36)
		error("Lvalue required");
}

max(a, b)
{
	if (a>b)
		return(a);
	return(b);
}