📄 proc.c
字号:
#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 + -