EarlyC/prestructc/c00.c

Find at most related files.
including files from this version of Unix.

/* C compiler

Copyright 1972 Bell Telephone Laboratories, Inc. 

*/

init(s, t)
char s[]; {
	extern symbuf, namsiz;
	char symbuf[], sp[];
	int np[], i;

	i = namsiz;
	sp = symbuf;
	while(i--)
		if ((*sp++ = *s++)=='\0') --s;
	np = lookup();
	*np++ = 1;
	*np = t;
}

main(argc, argv)
int argv[]; {
	extern extdef, eof;
	extern fout, fin, nerror, tmpfil, xdflg;

	if(argc<4) {
		error("Arg count");
		exit(1);
	}
	if((fin=open(argv[1],0))<0) {
		error("Can't find %s", argv[1]);
		exit(1);
	}
	if((fout=creat(argv[2], 017))<0) {
		error("Can't create %s", argv[2]);
		exit(1);
	}
	tmpfil = argv[3];
	xdflg++;
	init("int", 0);
	init("char", 1);
	init("float", 2);
	init("double", 3);
	init("struct", 4);
	init("auto", 5);
	init("extern", 6);
	init("static", 7);
	init("goto", 10);
	init("return", 11);
	init("if", 12);
	init("while", 13);
	init("else", 14);
	init("switch", 15);
	init("case", 16);
	init("break", 17);
	init("continue", 18);
	init("do", 19);
	init("default", 20);
	xdflg = 0;
	while(!eof) {
		extdef();
		blkend();
	}
	flush();
	flshw();
	exit(nerror!=0);
}

lookup() {
	extern hshtab, hshsiz, pssiz, symbuf, xdflg;
	int hshtab[], symbuf[];
	extern hshlen, hshused, nwps;
	auto i, j, np[], sp[], rp[];

	i = 0;
	sp = symbuf;
	j = nwps;
	while(j--)
		i =+ *sp++ & 077577;
	if (i<0) i = -i;
	i =% hshsiz;
	i =* pssiz;
	while(*(np = &hshtab[i+4])) {
		sp = symbuf;
		j = nwps;
		while(j--)
			if ((*np++&077577) != *sp++) goto no;
		return(&hshtab[i]);
no:		if ((i =+ pssiz) >= hshlen) i = 0;
	}
	if(++hshused > hshsiz) {
		error("Symbol table overflow");
		exit(1);
	}
	rp = np = &hshtab[i];
	sp = symbuf;
	j = 4;
	while(j--)
		*np++ = 0;
	j = nwps;
	while(j--)
		*np++ = *sp++;
	*np = 0;
	if (xdflg)
		rp[4] =| 0200;		/* mark non-deletable */
	return(rp);
}

symbol() {
	extern peeksym, peekc, eof, line;
	extern csym, symbuf, namsiz, lookup, ctab, cval;
	int csym[];
	extern isn, mosflg, xdflg;
	auto b, c;
	char symbuf[], sp[], ctab[];

	if (peeksym>=0) {
		c = peeksym;
		peeksym = -1;
		if (c==20)
			mosflg = 0;
		return(c);
	}
	if (peekc) {
		c = peekc;
		peekc = 0;
	} else
		if (eof)
			return(0); else
			c = getchar();
loop:
	switch(ctab[c]) {

	case 125:	/* newline */
		line++;

	case 126:	/* white space */
		c = getchar();
		goto loop;

	case 0:		/* EOF */
		eof++;
		return(0);

	case 40:	/* + */
		return(subseq(c,40,30));

	case 41:	/* - */
		return(subseq(c,subseq('>',41,50),31));

	case 80:	/* = */
		if (subseq(' ',0,1)) return(80);
		c = symbol();
		if (c>=40 & c<=49)
			return(c+30);
		if (c==80)
			return(60);
		peeksym = c;
		return(80);

	case 63:	/* < */
		if (subseq(c,0,1)) return(46);
		return(subseq('=',63,62));

	case 65:	/* > */
		if (subseq(c,0,1)) return(45);
		return(subseq('=',65,64));

	case 34:	/* ! */
		return(subseq('=',34,61));

	case 43:	/* / */
		if (subseq('*',1,0))
			return(43);
com:
		c = getchar();
com1:
		if (c=='\0') {
			eof++;
			error("Nonterminated comment");
			return(0);
		}
		if (c=='\n')
			line++;
		if (c!='*')
			goto com;
		c = getchar();
		if (c!='/')
			goto com1;
		c = getchar();
		goto loop;

	case 120:	/* . */
	case 124:	/* number */
		peekc = c;
		switch(c=getnum(c=='0'? 8:10)) {
			case 25:		/* float 0 */
				c = 23;
				break;

			case 23:		/* float non 0 */
				cval = isn++;
		}
		return(c);

	case 122:	/* " */
		return(getstr());

	case 121:	/* ' */
		return(getcc());

	case 123:	/* letter */
		sp = symbuf;
		if (mosflg) {
			*sp++ = '.';
			mosflg = 0;
		}
		while(ctab[c]==123 | ctab[c]==124) {
			if (sp<symbuf+namsiz) *sp++ = c;
			c = getchar();
		}
		while(sp<symbuf+namsiz)
			*sp++ = '\0';
		peekc = c;
		csym = lookup();
		if (csym[0]==1) {	/* keyword */
			cval = csym[1];
			return(19);
		}
		return(20);

	case 127:	/* unknown */
		error("Unknown character");
		c = getchar();
		goto loop;

	}
	return(ctab[c]);
}

subseq(c,a,b) {
	extern peekc;

	if (!peekc)
		peekc = getchar();
	if (peekc != c)
		return(a);
	peekc = 0;
	return(b);
}
getstr() {
	extern isn, cval, strflg;
	auto c;
	char t[], d[];

	t = ".text";
	d = ".data";
	printf("%s;L%d:.byte ", (strflg?t:d), cval=isn++);
	while((c=mapch('"')) >= 0)
		printf("%o,", c);
	printf("0;.even;%s\n", (strflg?d:t));
	return(22);
}

getcc()
{
	extern cval, ncpw;
	auto c, cc;
	char cp[];

	cval = 0;
	cp = &cval;
	cc = 0;
	while((c=mapch('\'')) >= 0)
		if(cc++ < ncpw)
			*cp++ = c;
	if(cc>ncpw)
		error("Long character constant");
	return(21);
}

mapch(c)
{
	extern peekc, line;
	auto a;

	if((a=getchar())==c)
		return(-1);
	switch(a) {

	case '\n':
	case 0:
		error("Nonterminated string");
		peekc = a;
		return(-1);

	case '\\':
		switch (a=getchar()) {

		case 't':
			return('\t');

		case 'n':
			return('\n');

		case '0':
			return('\0');

		case 'r':
			return('\r');

		case '\n':
			line++;
			return('\n');
		}

	}
	return(a);
}

tree() {
	extern csym, ctyp, isn, fcval, peeksym, opdope, cp, cmst;
	int csym[], opdope[], cp[], cmst[];
	extern space, cval, ossiz, cmsiz, mosflg, osleft;
	double fcval;
	int space[];

	int op[], opst[20], pp[], prst[20], andflg, o,
		p, ps, os;

	osleft = ossiz;
	space = 0;
	*space++ = 0;
	op = opst;
	pp = prst;
	cp = cmst;
	*op = 200;		/* stack EOF */
	*pp = 06;
	andflg = 0;

advanc:
	switch (o=symbol()) {

	/* name */
	case 20:
		if (*csym==0)
			if((peeksym=symbol())==6) {	/* ( */
				*csym = 6;		/* extern */
				csym[1] = 020;		/* int() */
			} else {
				csym[1] = 030;		/* array */
				if (csym[2]==0)
					csym[2] = isn++;
			}
		*cp++ = block(2,20,csym[1],csym[3],*csym,0);
		if (*csym==6) {			/* external */
			o = 3;
			while(++o<8) {
				pblock(csym[o]);
				if ((csym[o]&077400) == 0)
					break;
			}
		} else
			pblock(csym[2]);
		goto tand;

	/* short constant */
	case 21:
	case21:
		*cp++ = block(1,21,ctyp,0,cval);
		goto tand;

	/* floating constant */
	case 23:
		*cp++ = block(1,23,3,0,cval);
		if (cval)		/* non-0 */
			printf(".data;L%d:%o;%o;%o;%o;.text\n",cval,fcval);
		goto tand;

	/* string constant: fake a static char array */
	case 22:
		*cp++ = block(3, 20, 031, 1, 7, 0, cval);

tand:
		if(cp>=cmst+cmsiz) {
			error("Expression overflow");
			exit(1);
		}
		if (andflg)
			goto syntax;
		andflg = 1;
		goto advanc;

	/* ++, -- */
	case 30:
	case 31:
		if (andflg)
			o =+ 2;
		goto oponst;

	/* ! */
	case 34:
	/* ~ */
	case 38:
		if (andflg)
			goto syntax;
		goto oponst;

	/* - */
	case 41:
		if (!andflg) {
			peeksym = symbol();
			if (peeksym==21) {
				peeksym = -1;
				cval = -cval;
				goto case21;
			}
			o = 37;
		}
		andflg = 0;
		goto oponst;

	/* & */
	/* * */
	case 47:
	case 42:
		if (andflg)
			andflg = 0; else
			if(o==47)
				o = 35;
			else
				o = 36;
		goto oponst;

	/* ( */
	case 6:
		if (andflg) {
			o = symbol();
			if (o==7)
				o = 101; else {
				peeksym = o;
				o = 100;
				andflg = 0;
			}
		}
	goto oponst;

	/* ) */
	/* ] */
	case 5:
	case 7:
		if (!andflg)
			goto syntax;
		goto oponst;

	case 39:	/* . */
		mosflg++;
		break;

	}
	/* binaries */
	if (!andflg)
		goto syntax;
	andflg = 0;

oponst:
	p = (opdope[o]>>9) & 077;
opon1:
	ps = *pp;
	if (p>ps | p==ps & (opdope[o]&0200)!=0) { /* right-assoc */
putin:
		switch (o) {

		case 6: /* ( */
		case 4: /* [ */
		case 100: /* call */
			p = 04;
		}
		if(op>=opst+20) {		/* opstack size */
			error("expression overflow");
			exit(1);
		}
		*++op = o;
		*++pp = p;
		goto advanc;
	}
	--pp;
	switch (os = *op--) {

	/* EOF */
	case 200:
		peeksym = o;
		return(*--cp);

	/* call */
	case 100:
		if (o!=7)
			goto syntax;
		build(os);
		goto advanc;

	/* mcall */
	case 101:
		*cp++ = block(0,0,0,0);	/* 0 arg call */
		os = 100;
		goto fbuild;

	/* ( */
	case 6:
		if (o!=7)
			goto syntax;
		goto advanc;

	/* [ */
	case 4:
		if (o!=5)
			goto syntax;
		build(4);
		goto advanc;
	}
fbuild:
	build(os);
	goto opon1;

syntax:
	error("Expression syntax");
	errflush(o);
	return(0);
}

scdeclare(kw)
{
	extern csym, paraml, parame, peeksym;
	int csym[], paraml[], parame[];
	int o;

	while((o=symbol())==20) {		/* name */
		if(*csym>0 & *csym!=kw)
			redec();
		*csym = kw;
		if(kw==8)  {		/* parameter */
			*csym = -1;
			if (paraml==0)
				paraml = csym;
			else
				*parame = csym;
			parame = csym;
		}
		if ((o=symbol())!=9)	/* , */
			break;
	}
	if(o==1 & kw!=8 | o==7 & kw==8)
		return;
syntax:
	decsyn(o);
}

tdeclare(kw, offset, mos)
{
	int o, elsize, ds[];
	extern xdflg, peeksym, mosflg, defsym, csym;
	int csym[], ssym[];

	if (kw == 4) {				/* struct */
		ssym = 0;
		ds = defsym;
		mosflg = mos;
		if ((o=symbol())==20) {		/* name */
			ssym = csym;
			o = symbol();
		}
		mosflg = mos;
		if (o != 6) {			/* ( */
			if (ssym==0)
				goto syntax;
			if (*ssym!=8)		/* class structname */
				error("Bad structure name");
			if (ssym[3]==0) {	/* no size yet */
				kw = 5;		/* deferred MOS */
				elsize = ssym;
			} else
				elsize = ssym[3];
			peeksym = o;
		} else {
			if (ssym) {
				if (*ssym)
					redec();
				*ssym = 8;
				ssym[3] = 0;
			}
			elsize = declist(4);
			if ((elsize&01) != 0)
				elsize++;
			defsym = ds;
			if ((o = symbol()) != 7)	/* ) */
				goto syntax;
			if (ssym)
				ssym[3] = elsize;
		}
	}
	mosflg = mos;
	if ((peeksym=symbol()) == 1) {		/* ; */
		peeksym = -1;
		mosflg = 0;
		return(offset);
	}
	do {
		offset =+ t1dec(kw, offset, mos, elsize);
		if (xdflg & !mos)
			return;
	} while ((o=symbol()) == 9);		/* , */
	if (o==1)
		return(offset);
syntax:
	decsyn(o);
}

t1dec(kw, offset, mos, elsize)
{
	int type, nel, defsym[], t1;
	extern defsym, mosflg;

	nel = 0;
	mosflg = mos;
	if ((t1=getype(&nel)) < 0)
		goto syntax;
	type = 0;
	do
		type = type<<2 | (t1 & 03);
	while(t1 =>> 2);
	t1 = type<<3 | kw;
	if (defsym[1] & defsym[1]!=t1)
		redec();
	defsym[1] = t1;
	defsym[3] = elsize;
	elsize = length(defsym);
	if (mos) {
		if (*defsym)
			redec();
		else
			*defsym = 4;
		if ((offset&1)!=0 & elsize!=1)
			offset++;
		defsym[2] = offset;
	} else
		if (*defsym == 0)
			*defsym = -2;		/* default auto */
	if (nel==0)
		nel = 1;
	defsym[8] = nel;
syntax:
	return(nel*elsize);
}

getype(pnel)
int pnel[];
{
	int o, type;
	extern cval, peeksym, xdflg, defsym, csym, pssiz;
	int defsym[], csym[];

	switch(o=symbol()) {

	case 42:					/* * */
		return(getype(pnel)<<2 | 01);

	case 6:						/* ( */
		type = getype(pnel);
		if ((o=symbol()) != 7)			/* ) */
			goto syntax;
		goto getf;

	case 20:					/* name */
		defsym = csym;
		type = 0;
	getf:
		switch(o=symbol()) {

		case 6:					/* ( */
			if (xdflg) {
				xdflg = 0;
				o = defsym;
				scdeclare(8);
				defsym = o;
				xdflg++;
			} else
				if ((o=symbol()) != 7)	/* ) */
					goto syntax;
			type = type<<2 | 02;
			goto getf;

		case 4:					/* [ */
			if ((o=symbol()) != 5) {	/* ] */
				if (o!=21)		/* const */
					goto syntax;
				*pnel = cval;
				if ((o=symbol())!=5)
					goto syntax;
			}
			type = type<<2 | 03;
			goto getf;
		}
		peeksym = o;
		return(type);
	}
syntax:
	decsyn(o);
	return(-1);
}

decsyn(o)
{
	error("Declaration syntax");
	errflush(o);
}

redec()
{
	extern csym;
	int csym[];

	error("%p redeclared", &csym[4]);
}

/* storage */

regtab 0;
efftab 1;
cctab 2;
sptab 3;
symbuf[4];
pssiz 9;
namsiz 8;
nwps 4;
hshused;
hshsiz 100;
hshlen 900;	/* 9*hshsiz */
hshtab[900];
space;
cp;
cmsiz 40;
cmst[40];
ctyp;
isn 1;
swsiz 120;
swtab[120];
swp;
contlab;
brklab;
deflab;
nreg 4;
nauto;
stack;
peeksym 0177777;
peekc;
eof;
line 1;
defsym;
xdflg;
csym;
cval;
fcval 0;	/* a double number */
fc1 0;
fc2 0;
fc3 0;
ncpw 2;
nerror;
paraml;
parame;
tmpfil;
strflg;
ossiz 250;
osleft;
mosflg;
debug 0;