⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c03.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#/* * C compiler, phase 1 * * * Handles processing of declarations, * except for top-level processing of * externals. */#include "c0.h"/* * Process a sequence of declaration statements */declist(sclass){	register sc, offset;	struct hshtab typer;	offset = 0;	sc = sclass;	while (getkeywords(&sclass, &typer)) {		offset = declare(sclass, &typer, offset);		sclass = sc;	}	return(offset+align(INT, offset, 0));}/* * Read the keywords introducing a declaration statement * Store back the storage class, and fill in the type * entry, which looks like a hash table entry. */getkeywords(scptr, tptr)int *scptr;struct hshtab *tptr;{	register skw, tkw, longf;	int o, isadecl, ismos, unsignf;	isadecl = 0;	longf = 0;	unsignf = 0;	tptr->htype = INT;	tptr->hstrp = NULL;	tptr->hsubsp = NULL;	tkw = -1;	skw = *scptr;	ismos = skw==MOS||skw==MOU;	for (;;) {		mosflg = ismos && isadecl;		o = symbol();		if (o==NAME && csym->hclass==TYPEDEF && tkw<0) {			tkw = csym->htype;			tptr->hsubsp = csym->hsubsp;			tptr->hstrp = csym->hstrp;			isadecl++;			continue;		}		switch (o==KEYW? cval: -1) {		case AUTO:		case STATIC:		case EXTERN:		case REG:		case TYPEDEF:			if (skw && skw!=cval) {				if (skw==ARG && cval==REG)					cval = AREG;				else					error("Conflict in storage class");			}			skw = cval;			break;			case UNSIGN:			unsignf++;			break;		case LONG:			longf++;			break;		case ENUM:			strdec(ismos, cval);			cval = INT;			goto types;		case UNION:		case STRUCT:			tptr->hstrp = strdec(ismos, cval);			cval = STRUCT;		case INT:		case CHAR:		case FLOAT:		case DOUBLE:		types:			if (tkw>=0)				error("Type clash");			tkw = cval;			break;			default:			peeksym = o;			if (isadecl==0)				return(0);			if (tkw<0)				tkw = INT;			if (skw==0)				skw = blklev==0? DEFXTRN: AUTO;			if (unsignf) {				if (tkw==INT)					tkw = UNSIGN;				else					error("Misplaced 'unsigned'");			}			if (longf) {				if (tkw==FLOAT)					tkw = DOUBLE;				else if (tkw==INT)					tkw = LONG;				else					error("Misplaced 'long'");			}			*scptr = skw;			tptr->htype = tkw;			return(1);		}		isadecl++;	}}/* * Process a structure, union, or enum declaration; a subroutine * of getkeywords. */struct str *strdec(mosf, kind){	register elsize, o;	register struct hshtab *ssym;	int savebits;	struct hshtab **savememlist;	int savenmems;	struct str *strp;	struct hshtab *ds;	struct hshtab *mems[NMEMS];	struct hshtab typer;	int tagkind;	if (kind!=ENUM) {		tagkind = STRTAG;		mosflg = 1;	} else		tagkind = ENUMTAG;	ssym = 0;	if ((o=symbol())==NAME) {		ssym = csym;		mosflg = mosf;		o = symbol();		if (o==LBRACE && ssym->hblklev<blklev)			pushdecl(ssym);		if (ssym->hclass==0) {			ssym->hclass = tagkind;			ssym->strp = gblock(sizeof(*strp));			funcbase = curbase;			ssym->strp->ssize = 0;			ssym->strp->memlist = NULL;		}		if (ssym->hclass != tagkind)			redec();		strp = ssym->strp;	} else {		strp = gblock(sizeof(*strp));		funcbase = curbase;		strp->ssize = 0;		strp->memlist = NULL;	}	mosflg = 0;	if (o != LBRACE) {		if (ssym==0)			goto syntax;		if (ssym->hclass!=tagkind)			error("Bad structure/union/enum name");		peeksym = o;	} else {		ds = defsym;		mosflg = 0;		savebits = bitoffs;		savememlist = memlist;		savenmems = nmems;		memlist = mems;		nmems = 2;		bitoffs = 0;		if (kind==ENUM) {			typer.htype = INT;			typer.hstrp = strp;			declare(ENUM, &typer, 0);		} else			elsize = declist(kind==UNION?MOU:MOS);		bitoffs = savebits;		defsym = ds;		if (strp->ssize)			error("%.8s redeclared", ssym->name);		strp->ssize = elsize;		*memlist++ = NULL;		strp->memlist = gblock((memlist-mems)*sizeof(*memlist));		funcbase = curbase;		for (o=0; &mems[o] != memlist; o++)			strp->memlist[o] = mems[o];		memlist = savememlist;		nmems = savenmems;		if ((o = symbol()) != RBRACE)			goto syntax;	}	return(strp);   syntax:	decsyn(o);	return(0);}/* * Process a comma-separated list of declarators */declare(askw, tptr, offset)struct hshtab *tptr;{	register int o;	register int skw, isunion;	skw = askw;	isunion = 0;	if (skw==MOU) {		skw = MOS;		isunion++;		mosflg = 1;		if ((peeksym=symbol()) == SEMI) {			o = length(tptr);			if (o>offset)				offset = o;		}	}	do {		if (skw==ENUM && (peeksym=symbol())==RBRACE) {			o = peeksym;			peeksym = -1;			break;		}		o = decl1(skw, tptr, isunion?0:offset, NULL);		if (isunion) {			o =+ align(CHAR, o, 0);			if (o>offset)				offset = o;		} else			offset =+ o;	} while ((o=symbol()) == COMMA);	if (o==RBRACE) {		peeksym = o;		o = SEMI;	}	if (o!=SEMI && (o!=RPARN || skw!=ARG1))		decsyn(o);	return(offset);}/* * Process a single declarator */decl1(askw, atptr, offset, absname)struct hshtab *atptr, *absname;{	int t1, chkoff, a, elsize;	register int skw;	int type;	register struct hshtab *dsym;	register struct hshtab *tptr;	struct tdim dim;	struct field *fldp;	int *dp;	int isinit;	skw = askw;	tptr = atptr;	chkoff = 0;	mosflg = skw==MOS;	dim.rank = 0;	if (((peeksym=symbol())==SEMI || peeksym==RPARN) && absname==NULL)		return(0);	/*	 * Filler field	 */	if (peeksym==COLON && skw==MOS) {		peeksym = -1;		t1 = conexp();		elsize = align(tptr->htype, offset, t1);		bitoffs =+ t1;		return(elsize);	}	t1 = getype(&dim, absname);	if (t1 == -1)		return(0);	if (tptr->hsubsp) {		type = tptr->htype;		for (a=0; type&XTYPE;) {			if ((type&XTYPE)==ARRAY)				dim.dimens[dim.rank++] = tptr->hsubsp[a++];			type =>> TYLEN;		}	}	type = tptr->htype & ~TYPE;	while (t1&XTYPE) {		if (type&BIGTYPE) {			typov();			type = t1 = 0;		}		type = type<<TYLEN | (t1 & XTYPE);		t1 =>> TYLEN;	}	type =| tptr->htype&TYPE;	if (absname)		defsym = absname;	dsym = defsym;	if (dsym->hblklev < blklev)		pushdecl(dsym);	if (dim.rank == 0)		dsym->subsp = NULL;	else {		dp = gblock(dim.rank*sizeof(dim.rank));		funcbase = curbase;		if (skw==EXTERN)			maxdecl = curbase;		for (a=0; a<dim.rank; a++) {			if ((t1 = dp[a] = dim.dimens[a])			 && (dsym->htype&XTYPE) == ARRAY			 && dsym->subsp[a] && t1!=dsym->subsp[a])				redec();		}		dsym->subsp = dp;	}	if ((type&XTYPE) == FUNC) {		if (skw==AUTO)			skw = EXTERN;		if ((skw!=EXTERN && skw!=TYPEDEF) && absname==NULL)			error("Bad func. storage class");	}	if (!(dsym->hclass==0	   || ((skw==ARG||skw==AREG) && dsym->hclass==ARG1)	   || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type)))		if (skw==MOS && dsym->hclass==MOS && dsym->htype==type)			chkoff = 1;		else {			redec();			goto syntax;		}	if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && (type&TYPE)==STRUCT)		if (dsym->hstrp != tptr->hstrp) {			error("Warning: structure redeclaration");			nerror--;		}	dsym->htype = type;	if (tptr->hstrp)		dsym->hstrp = tptr->hstrp;	if (skw==TYPEDEF) {		dsym->hclass = TYPEDEF;		return(0);	}	if (absname)		return(0);	if (skw==ARG1) {		if (paraml==0)			paraml = dsym;		else			parame->hoffset = dsym;		parame = dsym;		dsym->hclass = skw;		return(0);	}	elsize = 0;	if (skw==MOS) {		elsize = length(dsym);		if ((peeksym = symbol())==COLON) {			elsize = 0;			peeksym = -1;			t1 = conexp();			a = align(type, offset, t1);			if (dsym->hflag&FFIELD) {				if (dsym->hstrp->bitoffs!=bitoffs			 	 || dsym->hstrp->flen!=t1)					redec();			} else {				dsym->hstrp = gblock(sizeof(*fldp));				funcbase = curbase;			}			dsym->hflag =| FFIELD;			dsym->hstrp->bitoffs = bitoffs;			dsym->hstrp->flen = t1;			bitoffs =+ t1;		} else			a = align(type, offset, 0);		elsize =+ a;		offset =+ a;		if (++nmems >= NMEMS) {			error("Too many structure members");			nmems =- NMEMS/2;			memlist =- NMEMS/2;		}		if (a)			*memlist++ = &structhole;		if (chkoff && dsym->hoffset != offset)			redec();		dsym->hoffset = offset;		*memlist++ = dsym;	}	if (skw==REG)		if ((dsym->hoffset = goodreg(dsym)) < 0)			skw = AUTO;	dsym->hclass = skw;	isinit = 0;	if ((a=symbol())!=COMMA && a!=SEMI && a!=RBRACE)		isinit++;	if (a!=ASSIGN)		peeksym = a;	if (skw==AUTO) {	/*	if (STAUTO < 0) {	*/			autolen =- rlength(dsym);			dsym->hoffset = autolen;			if (autolen < maxauto)				maxauto = autolen;	/*	} else { 			*/	/*		dsym->hoffset = autolen;	*/	/*		autolen =+ rlength(dsym);	*/	/*		if (autolen > maxauto)		*/	/*			maxauto = autolen;	*/	/*	}			*/		if (isinit)			cinit(dsym, 0, AUTO);	} else if (skw==STATIC) {		dsym->hoffset = isn;		if (isinit) {			outcode("BBN", DATA, LABEL, isn++);			if (cinit(dsym, 1, STATIC) & ALIGN)				outcode("B", EVEN);		} else			outcode("BBNBN", BSS, LABEL, isn++, SSPACE, rlength(dsym));		outcode("B", PROG);	} else if (skw==REG && isinit)		cinit(dsym, 0, REG);	else if (skw==ENUM) {		if (type!=INT)			error("Illegal enumeration %.8s", dsym->name);		dsym->hclass = ENUMCON;		dsym->hoffset = offset;		if (isinit)			cinit(dsym, 0, ENUMCON);		elsize = dsym->hoffset-offset+1;	}	prste(dsym);syntax:	return(elsize);}/* * Push down an outer-block declaration * after redeclaration in an inner block. */pushdecl(asp)struct phshtab *asp;{	register struct phshtab *sp, *nsp;	sp = asp;	nsp = gblock(sizeof(*nsp));	maxdecl = funcbase = curbase;	cpysymb(nsp, sp);	sp->hclass = 0;	sp->hflag =& (FKEYW|FMOS);	sp->htype = 0;	sp->hoffset = 0;	sp->hblklev = blklev;	sp->hpdown = nsp;}/* * Copy the non-name part of a symbol */cpysymb(s1, s2)struct phshtab *s1, *s2;{	register struct phshtab *rs1, *rs2;	rs1 = s1;	rs2 = s2;	rs1->hclass = rs2->hclass;	rs1->hflag = rs2->hflag;	rs1->htype = rs2->htype;	rs1->hoffset = rs2->hoffset;	rs1->hsubsp = rs2->hsubsp;	rs1->hstrp = rs2->hstrp;	rs1->hblklev = rs2->hblklev;	rs1->hpdown = rs2->hpdown;}/* * Read a declarator and get the implied type */getype(adimp, absname)struct tdim *adimp;struct hshtab *absname;{	static struct hshtab argtype;	int type;	register int o;	register struct hshtab *ds;	register struct tdim *dimp;	ds = defsym;	dimp = adimp;	type = 0;	switch(o=symbol()) {	case TIMES:		type = getype(dimp, absname);		if (type==-1)			return(type);		if (type&BIGTYPE) {			typov();			type = 0;		}		return(type<<TYLEN | PTR);	case LPARN:		if (absname==NULL || nextchar()!=')') {			type = getype(dimp, absname);			if (type==-1)				return(type);			ds = defsym;			if ((o=symbol()) != RPARN)				goto syntax;			goto getf;		}	default:		peeksym = o;		if (absname) {			defsym = ds = absname;			absname = NULL;			goto getf;		}		break;	case NAME:		defsym = ds = csym;	getf:		switch(o=symbol()) {		case LPARN:			if (blklev==0) {				blklev++;				ds = defsym;				declare(ARG1, &argtype, 0);				defsym = ds;				blklev--;			} else				if ((o=symbol()) != RPARN)					goto syntax;			if (type&BIGTYPE) {				typov();				type = 0;			}			type = type<<TYLEN | FUNC;			goto getf;		case LBRACK:			if (dimp->rank>=5) {				error("Rank too large");				dimp->rank = 4;			}			if ((o=symbol()) != RBRACK) {				peeksym = o;				cval = conexp();				defsym = ds;				if ((o=symbol())!=RBRACK)					goto syntax;			} else {				if (dimp->rank!=0)					error("Null dimension");				cval = 0;			}			dimp->dimens[dimp->rank++] = cval;			if (type&BIGTYPE) {				typov();				type = 0;			}			type = type<<TYLEN | ARRAY;			goto getf;		}		peeksym = o;		return(type);	}syntax:	decsyn(o);	return(-1);}/* * More bits required for type than allowed. */typov(){	error("Type is too complicated");}/* * Enforce alignment restrictions in structures, * including bit-field considerations. */align(type, offset, aflen){	register a, t, flen;	char *ftl;	flen = aflen;	a = offset;	t = type;	ftl = "Field too long";	if (flen==0) {		a =+ (NBPC+bitoffs-1) / NBPC;		bitoffs = 0;	}	while ((t&XTYPE)==ARRAY)		t = decref(t);	if (t!=CHAR) {		a = (a+ALIGN) & ~ALIGN;		if (a>offset)			bitoffs = 0;	}	if (flen) {		if (type==INT || type==UNSIGN) {			if (flen > NBPW)				error(ftl);			if (flen+bitoffs > NBPW) {				bitoffs = 0;				a =+ NCPW;			}		} else if (type==CHAR) {			if (flen > NBPC)				error(ftl);			if (flen+bitoffs > NBPC) {				bitoffs = 0;				a =+ 1;			}		} else			error("Bad type for field");	}	return(a-offset);}/* * Complain about syntax error in declaration */decsyn(o){	error("Declaration syntax");	errflush(o);}/* * Complain about a redeclaration */redec(){	error("%.8s redeclared", defsym->name);}/* * Determine if a variable is suitable for storage in * a register; if so return the register number */goodreg(hp)struct hshtab *hp;{	int type;	type = hp->htype;	/*	 * Special dispensation for unions	 */	if (type==STRUCT && length(hp)<=SZINT)		type = INT;	if ((type!=INT && type!=CHAR && type!=UNSIGN && (type&XTYPE)==0)	 || (type&XTYPE)>PTR || regvar<3)		return(-1);	return(--regvar);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -