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

📄 proc.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "defs"/* start a new procedure */newproc(){if(parstate != OUTSIDE)	{	execerr("missing end statement", 0);	endproc();	}parstate = INSIDE;procclass = CLMAIN;	/* default */}/* end of procedure. generate variables, epilogs, and prologs */endproc(){struct labelblock *lp;if(parstate < INDATA)	enddcl();if(ctlstack >= ctls)	err("DO loop or BLOCK IF not closed");for(lp = labeltab ; lp < labtabend ; ++lp)	if(lp->stateno!=0 && lp->labdefined==NO)		err1("missing statement number %s", convic(lp->stateno) );epicode();procode();dobss();prdbginfo();#if FAMILY == SCJ	putbracket();#endifprocinit();	/* clean up for next procedure */}/* End of declaration section of procedure.  Allocate storage. */enddcl(){register struct entrypoint *p;parstate = INEXEC;docommon();doequiv();docomleng();for(p = entries ; p ; p = p->nextp)	doentry(p);}/* ROUTINES CALLED WHEN ENCOUNTERING ENTRY POINTS *//* Main program or Block data */startproc(progname, class)struct extsym * progname;int class;{register struct entrypoint *p;p = ALLOC(entrypoint);if(class == CLMAIN)	puthead("MAIN__", CLMAIN);else	puthead(NULL, CLBLOCK);if(class == CLMAIN)	newentry( mkname(5, "MAIN_") );p->entryname = progname;p->entrylabel = newlabel();entries = p;procclass = class;retlabel = newlabel();fprintf(diagfile, "   %s", (class==CLMAIN ? "MAIN" : "BLOCK DATA") );if(progname)	fprintf(diagfile, " %s", nounder(XL, procname = progname->extname) );fprintf(diagfile, ":\n");}/* subroutine or function statement */struct extsym *newentry(v)register struct nameblock *v;{register struct extsym *p;struct extsym *mkext();p = mkext( varunder(VL, v->varname) );if(p==NULL || p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )	{	if(p == 0)		dclerr("invalid entry name", v);	else	dclerr("external name already used", v);	return(0);	}v->vstg = STGAUTO;v->vprocclass = PTHISPROC;v->vclass = CLPROC;p->extstg = STGEXT;p->extinit = YES;return(p);}entrypt(class, type, length, entry, args)int class, type;ftnint length;struct extsym *entry;chainp args;{register struct nameblock *q;register struct entrypoint *p;if(class != CLENTRY)	puthead( varstr(XL, procname = entry->extname), class);if(class == CLENTRY)	fprintf(diagfile, "       entry ");fprintf(diagfile, "   %s:\n", nounder(XL, entry->extname));q = mkname(VL, nounder(XL,entry->extname) );if( (type = lengtype(type, (int) length)) != TYCHAR)	length = 0;if(class == CLPROC)	{	procclass = CLPROC;	proctype = type;	procleng = length;	retlabel = newlabel();	if(type == TYSUBR)		ret0label = newlabel();	}p = ALLOC(entrypoint);entries = hookup(entries, p);p->entryname = entry;p->arglist = args;p->entrylabel = newlabel();p->enamep = q;if(class == CLENTRY)	{	class = CLPROC;	if(proctype == TYSUBR)		type = TYSUBR;	}q->vclass = class;q->vprocclass = PTHISPROC;settype(q, type, (int) length);/* hold all initial entry points till end of declarations */if(parstate >= INDATA)	doentry(p);}/* generate epilogs */LOCAL epicode(){register int i;if(procclass==CLPROC)	{	if(proctype==TYSUBR)		{		putlabel(ret0label);		if(substars)			putforce(TYINT, ICON(0) );		putlabel(retlabel);		goret(TYSUBR);		}	else	{		putlabel(retlabel);		if(multitypes)			{			typeaddr = autovar(1, TYADDR, NULL);			putbranch( cpexpr(typeaddr) );			for(i = 0; i < NTYPES ; ++i)				if(rtvlabel[i] != 0)					{					putlabel(rtvlabel[i]);					retval(i);					}			}		else			retval(proctype);		}	}else if(procclass != CLBLOCK)	{	putlabel(retlabel);	goret(TYSUBR);	}}/* generate code to return value of type  t */LOCAL retval(t)register int t;{register struct addrblock *p;switch(t)	{	case TYCHAR:	case TYCOMPLEX:	case TYDCOMPLEX:		break;	case TYLOGICAL:		t = tylogical;	case TYADDR:	case TYSHORT:	case TYLONG:		p = cpexpr(retslot);		p->vtype = t;		putforce(t, p);		break;	case TYREAL:	case TYDREAL:		p = cpexpr(retslot);		p->vtype = t;		putforce(t, p);		break;	default:		fatal1("retval: impossible type %d", t);	}goret(t);}/* Allocate extra argument array if needed. Generate prologs. */LOCAL procode(){register struct entrypoint *p;struct addrblock *argvec;#if TARGET==GCOS	argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);#else	if(lastargslot>0 && nentry>1)		argvec = autovar(lastargslot/SZADDR, TYADDR, NULL);	else		argvec = NULL;#endif#if TARGET == PDP11	/* for the optimizer */	if(fudgelabel)		putlabel(fudgelabel);#endiffor(p = entries ; p ; p = p->nextp)	prolog(p, argvec);#if FAMILY == SCJ	putrbrack(procno);#endifprendproc();}/*   manipulate argument lists (allocate argument slot positions) * keep track of return types and labels */LOCAL doentry(ep)struct entrypoint *ep;{register int type;register struct nameblock *np;chainp p;register struct nameblock *q;++nentry;if(procclass == CLMAIN)	{	putlabel(ep->entrylabel);	return;	}else if(procclass == CLBLOCK)	return;impldcl( np = mkname(VL, nounder(XL, ep->entryname->extname) ) );type = np->vtype;if(proctype == TYUNKNOWN)	if( (proctype = type) == TYCHAR)		procleng = (np->vleng ? np->vleng->const.ci : (ftnint) 0);if(proctype == TYCHAR)	{	if(type != TYCHAR)		err("noncharacter entry of character function");	else if( (np->vleng ? np->vleng->const.ci : (ftnint) 0) != procleng)		err("mismatched character entry lengths");	}else if(type == TYCHAR)	err("character entry of noncharacter function");else if(type != proctype)	multitype = YES;if(rtvlabel[type] == 0)	rtvlabel[type] = newlabel();ep->typelabel = rtvlabel[type];if(type == TYCHAR)	{	if(chslot < 0)		{		chslot = nextarg(TYADDR);		chlgslot = nextarg(TYLENG);		}	np->vstg = STGARG;	np->vardesc.varno = chslot;	if(procleng == 0)		np->vleng = mkarg(TYLENG, chlgslot);	}else if( ISCOMPLEX(type) )	{	np->vstg = STGARG;	if(cxslot < 0)		cxslot = nextarg(TYADDR);	np->vardesc.varno = cxslot;	}else if(type != TYSUBR)	{	if(nentry == 1)		retslot = autovar(1, TYDREAL, NULL);	np->vstg = STGAUTO;	np->voffset = retslot->memoffset->const.ci;	}for(p = ep->arglist ; p ; p = p->nextp)	if(! ((q = p->datap)->vdcldone) )		q->vardesc.varno = nextarg(TYADDR);for(p = ep->arglist ; p ; p = p->nextp)	if(! ((q = p->datap)->vdcldone) )		{		impldcl(q);		q->vdcldone = YES;		if(q->vtype == TYCHAR)			{			if(q->vleng == NULL)	/* character*(*) */				q->vleng = mkarg(TYLENG, nextarg(TYLENG) );			else if(nentry == 1)				nextarg(TYLENG);			}		else if(q->vclass==CLPROC && nentry==1)			nextarg(TYLENG) ;		}putlabel(ep->entrylabel);}LOCAL nextarg(type)int type;{int k;k = lastargslot;lastargslot += typesize[type];return(k);}/* generate variable references */LOCAL dobss(){register struct hashentry *p;register struct nameblock *q;register int i;int align;ftnint leng, iarrl, iarrlen();struct extsym *mkext();char *memname();pruse(asmfile, USEBSS);for(p = hashtab ; p<lasthash ; ++p)    if(q = p->varp)	{	if( (q->vclass==CLUNKNOWN && q->vstg!=STGARG) ||	    (q->vclass==CLVAR && q->vstg==STGUNKNOWN) )		warn1("local variable %s never used", varstr(VL,q->varname) );	else if(q->vclass==CLVAR && q->vstg==STGBSS)		{		align = (q->vtype==TYCHAR ? ALILONG : typealign[q->vtype]);		if(bssleng % align != 0)			{			bssleng = roundup(bssleng, align);			preven(align);			}		prlocvar( memname(STGBSS, q->vardesc.varno), iarrl = iarrlen(q) );		bssleng += iarrl;		}	else if(q->vclass==CLPROC && q->vprocclass==PEXTERNAL && q->vstg!=STGARG)		mkext(varunder(VL, q->varname)) ->extstg = STGEXT;	if(q->vclass==CLVAR && q->vstg!=STGARG)		{		if(q->vdim && !ISICON(q->vdim->nelt) )			dclerr("adjustable dimension on non-argument", q);		if(q->vtype==TYCHAR && (q->vleng==NULL || !ISICON(q->vleng)))			dclerr("adjustable leng on nonargument", q);		}	}for(i = 0 ; i < nequiv ; ++i)	if(eqvclass[i].eqvinit==NO && (leng = eqvclass[i].eqvleng)!=0 )		{		bssleng = roundup(bssleng, ALIDOUBLE);		preven(ALIDOUBLE);		prlocvar( memname(STGEQUIV, i), leng);		bssleng += leng;		}}doext(){struct extsym *p;

⌨️ 快捷键说明

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