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

📄 c02.c

📁 unix v6 的c compiler 很老了
💻 C
字号:
#/* C compiler * * */#include "c0h.c"/* * Process a single external definition */extdef(){	register o, elsize;	int type, sclass;	register struct hshtab *ds;	if(((o=symbol())==EOF) || o==SEMI)		return;	peeksym = o;	type = INT;	sclass = EXTERN;	xdflg = FNDEL;	if ((elsize = getkeywords(&sclass, &type)) == -1 && peeksym!=NAME)		goto syntax;	if (type==STRUCT)		blkhed();	do {		defsym = 0;		decl1(EXTERN, type, 0, elsize);		if ((ds=defsym)==0)			return;		funcsym = ds;		ds->hflag =| FNDEL;		outcode("BS", SYMDEF, ds->name);		xdflg = 0;		if ((ds->type&XTYPE)==FUNC) {			if ((peeksym=symbol())==LBRACE || peeksym==KEYW) {				funcblk.type = decref(ds->type);				cfunc(ds->name);				return;			}		} else 			cinit(ds);	} while ((o=symbol())==COMMA);	if (o==SEMI)		return;syntax:	if (o==RBRACE) {		error("Too many }'s");		peeksym = 0;		return;	}	error("External definition syntax");	errflush(o);	statement(0);}/* * Process a function definition. */cfunc(cs)char *cs;{	register savdimp;	savdimp = dimp;	outcode("BBS", PROG, RLABEL, cs);	declist(ARG);	regvar = 5;	retlab = isn++;	if ((peeksym = symbol()) != LBRACE)		error("Compound statement required");	statement(1);	outcode("BNB", LABEL, retlab, RETRN);	dimp = savdimp;}/* * Process the initializers for an external definition. */cinit(ds)struct hshtab *ds;{	register basetype, nel, ninit;	int o, width, realwidth;	nel = 1;	basetype = ds->type;	/*	 * If it's an array, find the number of elements.	 * "basetype" is the type of thing it's an array of.	 */	while ((basetype&XTYPE)==ARRAY) {		if ((nel = dimtab[ds->ssp&0377])==0)			nel = 1;		basetype = decref(basetype);	}	realwidth = width = length(ds) / nel;	/*	 * Pretend a structure is kind of an array of integers.	 * This is a kludge.	 */	if (basetype==STRUCT) {		nel =* realwidth/2;		width = 2;	}	if ((peeksym=symbol())==COMMA || peeksym==SEMI) {		outcode("BSN",CSPACE,ds->name,(nel*width+ALIGN)&~ALIGN);		return;	}	ninit = 0;	outcode("BBS", DATA, NLABEL, ds->name);	if ((o=symbol())==LBRACE) {		do			ninit = cinit1(ds, basetype, width, ninit, nel);		while ((o=symbol())==COMMA);		if (o!=RBRACE)			peeksym = o;	} else {		peeksym = o;		ninit = cinit1(ds, basetype, width, 0, nel);	}	/*	 * Above we pretended that a structure was a bunch of integers.	 * Readjust in accordance with reality.	 * First round up partial initializations.	 */	if (basetype==STRUCT) {		if (o = 2*ninit % realwidth)			outcode("BN", SSPACE, realwidth-o);		ninit = (2*ninit+realwidth-2) / realwidth;		nel =/ realwidth/2;	}	/*	 * If there are too few initializers, allocate	 * more storage.	 * If there are too many initializers, extend	 * the declared size for benefit of "sizeof"	 */	if (ninit<nel)		outcode("BN", SSPACE, (nel-ninit)*realwidth);	else if (ninit>nel) {		if ((ds->type&XTYPE)==ARRAY)			dimtab[ds->ssp&0377] = ninit;		nel = ninit;	}	/*	 * If it's not an array, only one initializer is allowed.	 */	if (ninit>1 && (ds->type&XTYPE)!=ARRAY)		error("Too many initializers");	if (((nel&width)&ALIGN))		outcode("B", EVEN);}/* * Process a single expression in a sequence of initializers * for an external. Mainly, it's for checking * type compatibility. */cinit1(ds, type, awidth, aninit, nel)struct hshtab *ds;{	float sf;	register struct tnode *s;	register width, ninit;	width = awidth;	ninit = aninit;	if ((peeksym=symbol())==STRING && type==CHAR) {		peeksym = -1;		if (ninit)			bxdec();		putstr(0);		if (nel>nchstr) {			strflg++;			outcode("BN", SSPACE, nel-nchstr);			strflg = 0;			nchstr = nel;		}		return(nchstr);	}	if (peeksym==RBRACE)		return(ninit);	initflg++;	s = tree();	initflg = 0;	switch(width) {	case 1:		if (s->op != CON)			goto bad;		outcode("B1N0", BDATA, s->value);		break;	case 2:		if (s->op==CON) {			outcode("B1N0", WDATA, s->value);			break;		}		if (s->op==FCON || s->op==SFCON) {			if (type==STRUCT) {				ninit =+ 3;				goto prflt;			}			goto bad;		}		rcexpr(block(1,INIT,0,0,s));		break;	case 4:		sf = fcval;		outcode("B1N1N0", WDATA, sf);		goto flt;	case 8:	prflt:		outcode("B1N1N1N1N0", WDATA, fcval);	flt:		if (s->op==FCON || s->op==SFCON)			break;	default:	bad:		bxdec();	}	return(++ninit);}bxdec(){	error("Inconsistent external initialization");}/* * Process one statement in a function. */statement(d){	register o, o1, o2;	int o3, o4;	struct tnode *np;stmt:	switch(o=symbol()) {	case EOF:		error("Unexpected EOF");	case SEMI:		return;	case LBRACE:		if (d) {			if (proflg)				outcode("BN", PROFIL, isn++);			outcode("BN", SAVE, blkhed());		}		while (!eof) {			if ((o=symbol())==RBRACE)				return;			peeksym = o;			statement(0);		}		error("Missing '}'");		return;	case KEYW:		switch(cval) {		case GOTO:			if (o1 = simplegoto())				branch(o1);			else 				dogoto();			goto semi;		case RETURN:			doret();			goto semi;		case IF:			np = pexpr();			o2 = 0;			if ((o1=symbol())==KEYW) switch (cval) {			case GOTO:				if (o2=simplegoto())					goto simpif;				cbranch(np, o2=isn++, 0);				dogoto();				label(o2);				goto hardif;			case RETURN:				if (nextchar()==';') {					o2 = retlab;					goto simpif;				}				cbranch(np, o1=isn++, 0);				doret();				label(o1);				o2++;				goto hardif;			case BREAK:				o2 = brklab;				goto simpif;			case CONTIN:				o2 = contlab;			simpif:				chconbrk(o2);				cbranch(np, o2, 1);			hardif:				if ((o=symbol())!=SEMI)					goto syntax;				if ((o1=symbol())==KEYW && cval==ELSE) 					goto stmt;				peeksym = o1;				return;			}			peeksym = o1;			cbranch(np, o1=isn++, 0);			statement(0);			if ((o=symbol())==KEYW && cval==ELSE) {				o2 = isn++;				branch(o2);				label(o1);				statement(0);				label(o2);				return;			}			peeksym = o;			label(o1);			return;		case WHILE:			o1 = contlab;			o2 = brklab;			label(contlab = isn++);			cbranch(pexpr(), brklab=isn++, 0);			statement(0);			branch(contlab);			label(brklab);			contlab = o1;			brklab = o2;			return;		case BREAK:			chconbrk(brklab);			branch(brklab);			goto semi;		case CONTIN:			chconbrk(contlab);			branch(contlab);			goto semi;		case DO:			o1 = contlab;			o2 = brklab;			contlab = isn++;			brklab = isn++;			label(o3 = isn++);			statement(0);			label(contlab);			contlab = o1;			if ((o=symbol())==KEYW && cval==WHILE) {				cbranch(tree(), o3, 1);				label(brklab);				brklab = o2;				goto semi;			}			goto syntax;		case CASE:			o1 = conexp();			if ((o=symbol())!=COLON)				goto syntax;			if (swp==0) {				error("Case not in switch");				goto stmt;			}			if(swp>=swtab+swsiz) {				error("Switch table overflow");			} else {				swp->swlab = isn;				(swp++)->swval = o1;				label(isn++);			}			goto stmt;		case SWITCH:			o1 = brklab;			brklab = isn++;			np = pexpr();			chkw(np, -1);			rcexpr(block(1,RFORCE,0,0,np));			pswitch();			brklab = o1;			return;		case DEFAULT:			if (swp==0)				error("Default not in switch");			if ((o=symbol())!=COLON)				goto syntax;			label(deflab = isn++);			goto stmt;		case FOR:			o1 = contlab;			o2 = brklab;			contlab = isn++;			brklab = isn++;			if (o=forstmt())				goto syntax;			label(brklab);			contlab = o1;			brklab = o2;			return;		}		error("Unknown keyword");		goto syntax;	case NAME:		if (nextchar()==':') {			peekc = 0;			o1 = csym;			if (o1->hclass>0) {				error("Redefinition");				goto stmt;			}			o1->hclass = STATIC;			o1->htype = ARRAY;			if (o1->hoffset==0)				o1->hoffset = isn++;			label(o1->hoffset);			goto stmt;		}	}	peeksym = o;	rcexpr(tree());semi:	if ((o=symbol())==SEMI)		return;syntax:	error("Statement syntax");	errflush(o);}/* * Process a for statement. */forstmt(){	register int l, o, sline;	int sline1, *ss;	struct tnode *st;	if ((o=symbol()) != LPARN)		return(o);	if ((o=symbol()) != SEMI) {		/* init part */		peeksym = o;		rcexpr(tree());		if ((o=symbol()) != SEMI)			return(o);	}	label(contlab);	if ((o=symbol()) != SEMI) {		/* test part */		peeksym = o;		rcexpr(block(1,CBRANCH,tree(),brklab,0));		if ((o=symbol()) != SEMI)			return(o);	}	if ((peeksym=symbol()) == RPARN) {	/* incr part */		peeksym = -1;		statement(0);		branch(contlab);		return(0);	}	l = contlab;	contlab = isn++;	st = tree();	sline = line;	if ((o=symbol()) != RPARN)		return(o);	ss = treespace;	treespace = space;	statement(0);	sline1 = line;	line = sline;	label(contlab);	rcexpr(st);	line = sline1;	treespace = ss;	branch(l);	return(0);}/* * A parenthesized expression, * as after "if". */pexpr(){	register o, t;	if ((o=symbol())!=LPARN)		goto syntax;	t = tree();	if ((o=symbol())!=RPARN)		goto syntax;	return(t);syntax:	error("Statement syntax");	errflush(o);	return(0);}/* * The switch stateent, which involves collecting the * constants and labels for the cases. */pswitch(){	register struct swtab *cswp, *sswp;	int dl, swlab;	cswp = sswp = swp;	if (swp==0)		cswp = swp = swtab;	branch(swlab=isn++);	dl = deflab;	deflab = 0;	statement(0);	branch(brklab);	label(swlab);	if (deflab==0)		deflab = brklab;	outcode("BNN", SWIT, deflab, line);	for (; cswp < swp; cswp++)		outcode("NN", cswp->swlab, cswp->swval);	outcode("0");	label(brklab);	deflab = dl;	swp = sswp;}/* * blkhed is called at the start of each function. * It reads the declarations at the start; * then assigns storage locations for the * parameters (which have been linked into a list, * in order of appearance). * This list is necessary because in * f(a, b) float b; int a; ... * the names are seen before the types. * Also, the routine adjusts structures involved * in some kind of forward-referencing. */blkhed(){	register pl;	register struct hshtab *cs;	autolen = 6;	declist(0);	pl = 4;	while(paraml) {		parame->hoffset = 0;		cs = paraml;		paraml = paraml->hoffset;		if (cs->htype==FLOAT)			cs->htype = DOUBLE;		cs->hoffset = pl;		cs->hclass = AUTO;		if ((cs->htype&XTYPE) == ARRAY) {			cs->htype =- (ARRAY-PTR);	/* set ptr */			cs->ssp++;		/* pop dims */		}		pl =+ rlength(cs);	}	for (cs=hshtab; cs<hshtab+hshsiz; cs++) {		if (cs->name[0] == '\0')			continue;		/* check tagged structure */		if (cs->hclass>KEYWC && (cs->htype&TYPE)==RSTRUCT) {			cs->lenp = dimtab[cs->lenp&0377]->lenp;			cs->htype = cs->htype&~TYPE | STRUCT;		}		if (cs->hclass == STRTAG && dimtab[cs->lenp&0377]==0)			error("Undefined structure: %.8s", cs->name);		if (cs->hclass == ARG)			error("Not an argument: %.8s", cs->name);		if (stflg)			prste(cs);	}	space = treespace;	outcode("BN", SETREG, regvar);	return(autolen);}/* * After a function definition, delete local * symbols. * Also complain about undefineds. */blkend() {	register struct hshtab *cs;	for (cs=hshtab; cs<hshtab+hshsiz; cs++) {		if (cs->name[0]) {			if (cs->hclass==0 && (cs->hflag&FNUND)==0) {				error("%.8s undefined", cs->name);				cs->hflag =| FNUND;			}			if((cs->hflag&FNDEL)==0) {				cs->name[0] = '\0';				hshused--;				cs->hflag =& ~(FNUND|FFIELD);			}		}	}}/* * write out special definitions of local symbols for * benefit of the debugger.  None of these are used * by the assembler except to save them. */prste(acs){	register struct hshtab *cs;	register nkind;	cs = acs;	switch (cs->hclass) {	case REG:		nkind = RNAME;		break;	case AUTO:		nkind = ANAME;		break;	case STATIC:		nkind = SNAME;		break;	default:		return;	}	outcode("BSN", nkind, cs->name, cs->hoffset);}/* * In case of error, skip to the next * statement delimiter. */errflush(ao){	register o;	o = ao;	while(o>RBRACE)	/* ; { } */		o = symbol();	peeksym  = o;}

⌨️ 快捷键说明

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