00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "defs.h"
00025 #include "names.h"
00026 #include "output.h"
00027 #include "p1defs.h"
00028
00029
00030
00031
00032
00033 #undef roundup
00034 #define roundup(a,b) ( b * ( (a+b-1)/b) )
00035
00036 #define EXNULL (union Expression *)0
00037
00038 static void dobss Argdcl((void));
00039 static void docomleng Argdcl((void));
00040 static void docommon Argdcl((void));
00041 static void doentry Argdcl((struct Entrypoint*));
00042 static void epicode Argdcl((void));
00043 static int nextarg Argdcl((int));
00044 static void retval Argdcl((int));
00045
00046 static char Blank[] = BLANKCOMMON;
00047
00048 static char *postfix[] = { "g", "h", "i",
00049 #ifdef TYQUAD
00050 "j",
00051 #endif
00052 "r", "d", "c", "z", "g", "h", "i" };
00053
00054 chainp new_procs;
00055 int prev_proc, proc_argchanges, proc_protochanges;
00056
00057 void
00058 #ifdef KR_headers
00059 changedtype(q)
00060 Namep q;
00061 #else
00062 changedtype(Namep q)
00063 #endif
00064 {
00065 char buf[200];
00066 int qtype, type1;
00067 register Extsym *e;
00068 Argtypes *at;
00069
00070 if (q->vtypewarned)
00071 return;
00072 q->vtypewarned = 1;
00073 qtype = q->vtype;
00074 e = &extsymtab[q->vardesc.varno];
00075 if (!(at = e->arginfo)) {
00076 if (!e->exused)
00077 return;
00078 }
00079 else if (at->changes & 2 && qtype != TYUNKNOWN && !at->defined)
00080 proc_protochanges++;
00081 type1 = e->extype;
00082 if (type1 == TYUNKNOWN)
00083 return;
00084 if (qtype == TYUNKNOWN)
00085
00086
00087
00088
00089
00090
00091
00092 return;
00093 sprintf(buf, "%.90s: inconsistent declarations:\n\
00094 here %s%s, previously %s%s.", q->fvarname, ftn_types[qtype],
00095 qtype == TYSUBR ? "" : " function",
00096 ftn_types[type1], type1 == TYSUBR ? "" : " function");
00097 warn(buf);
00098 }
00099
00100 void
00101 #ifdef KR_headers
00102 unamstring(q, s)
00103 register Addrp q;
00104 register char *s;
00105 #else
00106 unamstring(register Addrp q, register char *s)
00107 #endif
00108 {
00109 register int k;
00110 register char *t;
00111
00112 k = strlen(s);
00113 if (k < IDENT_LEN) {
00114 q->uname_tag = UNAM_IDENT;
00115 t = q->user.ident;
00116 }
00117 else {
00118 q->uname_tag = UNAM_CHARP;
00119 q->user.Charp = t = mem(k+1, 0);
00120 }
00121 strcpy(t, s);
00122 }
00123
00124 static void
00125 fix_entry_returns(Void)
00126 {
00127 Addrp a;
00128 int i;
00129 struct Entrypoint *e;
00130 Namep np;
00131
00132 e = entries = (struct Entrypoint *)revchain((chainp)entries);
00133 allargs = revchain(allargs);
00134 if (!multitype)
00135 return;
00136
00137
00138
00139 for(i = TYINT1; i <= TYLOGICAL; i++)
00140 if (a = xretslot[i])
00141 sprintf(a->user.ident, "(*ret_val).%s",
00142 postfix[i-TYINT1]);
00143
00144 do {
00145 np = e->enamep;
00146 switch(np->vtype) {
00147 case TYINT1:
00148 case TYSHORT:
00149 case TYLONG:
00150 #ifdef TYQUAD
00151 case TYQUAD:
00152 #endif
00153 case TYREAL:
00154 case TYDREAL:
00155 case TYCOMPLEX:
00156 case TYDCOMPLEX:
00157 case TYLOGICAL1:
00158 case TYLOGICAL2:
00159 case TYLOGICAL:
00160 np->vstg = STGARG;
00161 }
00162 }
00163 while(e = e->entnextp);
00164 }
00165
00166 static void
00167 #ifdef KR_headers
00168 putentries(outfile)
00169 FILE *outfile;
00170 #else
00171 putentries(FILE *outfile)
00172 #endif
00173
00174 {
00175 char base[MAXNAMELEN+4];
00176 struct Entrypoint *e;
00177 Namep *A, *Ae, *Ae1, **Alp, *a, **a1, np;
00178 chainp args, lengths;
00179 int i, k, mt, nL, t, type;
00180 extern char *dfltarg[], **dfltproc;
00181
00182 e = entries;
00183 if (!e->enamep)
00184 return;
00185 nL = (nallargs + nallchargs) * sizeof(Namep *);
00186 if (!nL)
00187 nL = 8;
00188 A = (Namep *)ckalloc(nL + nallargs*sizeof(Namep **));
00189 Ae = A + nallargs;
00190 Alp = (Namep **)(Ae1 = Ae + nallchargs);
00191 i = k = 0;
00192 for(a1 = Alp, args = allargs; args; a1++, args = args->nextp) {
00193 np = (Namep)args->datap;
00194 if (np->vtype == TYCHAR && np->vclass != CLPROC)
00195 *a1 = &Ae[i++];
00196 }
00197
00198 mt = multitype;
00199 multitype = 0;
00200 sprintf(base, "%s0_", e->enamep->cvarname);
00201 do {
00202 np = e->enamep;
00203 lengths = length_comp(e, 0);
00204 proctype = type = np->vtype;
00205 if (protofile)
00206 protowrite(protofile, type, np->cvarname, e, lengths);
00207 nice_printf(outfile, "\n%s ", c_type_decl(type, 1));
00208 nice_printf(outfile, "%s", np->cvarname);
00209 if (!Ansi) {
00210 listargs(outfile, e, 0, lengths);
00211 nice_printf(outfile, "\n");
00212 }
00213 list_arg_types(outfile, e, lengths, 0, "\n");
00214 nice_printf(outfile, "{\n");
00215 frchain(&lengths);
00216 next_tab(outfile);
00217 if (mt)
00218 nice_printf(outfile,
00219 "Multitype ret_val;\n%s(%d, &ret_val",
00220 base, k);
00221 else if (ISCOMPLEX(type))
00222 nice_printf(outfile, "%s(%d,%s", base, k,
00223 xretslot[type]->user.ident);
00224 else if (type == TYCHAR)
00225 nice_printf(outfile,
00226 "%s(%d, ret_val, ret_val_len", base, k);
00227 else
00228 nice_printf(outfile, "return %s(%d", base, k);
00229 k++;
00230 memset((char *)A, 0, nL);
00231 for(args = e->arglist; args; args = args->nextp) {
00232 np = (Namep)args->datap;
00233 A[np->argno] = np;
00234 if (np->vtype == TYCHAR && np->vclass != CLPROC)
00235 *Alp[np->argno] = np;
00236 }
00237 args = allargs;
00238 for(a = A; a < Ae; a++, args = args->nextp) {
00239 t = ((Namep)args->datap)->vtype;
00240 nice_printf(outfile, ", %s", (np = *a)
00241 ? np->cvarname
00242 : ((Namep)args->datap)->vclass == CLPROC
00243 ? dfltproc[((Namep)args->datap)->vimpltype
00244 ? (Castargs ? TYUNKNOWN : TYSUBR)
00245 : t == TYREAL && forcedouble && !Castargs
00246 ? TYDREAL : t]
00247 : dfltarg[((Namep)args->datap)->vtype]);
00248 }
00249 for(; a < Ae1; a++)
00250 if (np = *a)
00251 nice_printf(outfile, ", %s",
00252 new_arg_length(np));
00253 else
00254 nice_printf(outfile, ", (ftnint)0");
00255 nice_printf(outfile, ");\n");
00256 if (mt) {
00257 if (type == TYCOMPLEX)
00258 nice_printf(outfile,
00259 "r_v->r = ret_val.c.r; r_v->i = ret_val.c.i;\n");
00260 else if (type == TYDCOMPLEX)
00261 nice_printf(outfile,
00262 "r_v->r = ret_val.z.r; r_v->i = ret_val.z.i;\n");
00263 else if (type <= TYLOGICAL)
00264 nice_printf(outfile, "return ret_val.%s;\n",
00265 postfix[type-TYINT1]);
00266 }
00267 nice_printf(outfile, "}\n");
00268 prev_tab(outfile);
00269 }
00270 while(e = e->entnextp);
00271 free((char *)A);
00272 }
00273
00274 static void
00275 #ifdef KR_headers
00276 entry_goto(outfile)
00277 FILE *outfile;
00278 #else
00279 entry_goto(FILE *outfile)
00280 #endif
00281 {
00282 struct Entrypoint *e = entries;
00283 int k = 0;
00284
00285 nice_printf(outfile, "switch(n__) {\n");
00286 next_tab(outfile);
00287 while(e = e->entnextp)
00288 nice_printf(outfile, "case %d: goto %s;\n", ++k,
00289 user_label((long)(extsymtab - e->entryname - 1)));
00290 nice_printf(outfile, "}\n\n");
00291 prev_tab(outfile);
00292 }
00293
00294
00295
00296 void
00297 newproc(Void)
00298 {
00299 if(parstate != OUTSIDE)
00300 {
00301 execerr("missing end statement", CNULL);
00302 endproc();
00303 }
00304
00305 parstate = INSIDE;
00306 procclass = CLMAIN;
00307 }
00308
00309 static void
00310 zap_changes(Void)
00311 {
00312 register chainp cp;
00313 register Argtypes *at;
00314
00315
00316
00317
00318 if (prev_proc && proc_argchanges)
00319 proc_protochanges++;
00320 prev_proc = proc_argchanges = 0;
00321 for(cp = new_procs; cp; cp = cp->nextp)
00322 if (at = ((Namep)cp->datap)->arginfo)
00323 at->changes &= ~1;
00324 frchain(&new_procs);
00325 }
00326
00327
00328
00329 void
00330 endproc(Void)
00331 {
00332 struct Labelblock *lp;
00333 Extsym *ext;
00334
00335 if(parstate < INDATA)
00336 enddcl();
00337 if(ctlstack >= ctls)
00338 err("DO loop or BLOCK IF not closed");
00339 for(lp = labeltab ; lp < labtabend ; ++lp)
00340 if(lp->stateno!=0 && lp->labdefined==NO)
00341 errstr("missing statement label %s",
00342 convic(lp->stateno) );
00343
00344
00345
00346 for (ext = extsymtab; ext < nextext; ext++)
00347 if (ext -> extstg == STGCOMMON && ext -> extp) {
00348 extern int usedefsforcommon;
00349
00350
00351
00352 copy_data (ext -> extp);
00353 if (usedefsforcommon) {
00354 wr_abbrevs (c_file, 1, ext -> extp);
00355 ext -> used_here = 1;
00356 }
00357 else
00358 ext -> extp = CHNULL;
00359
00360 }
00361
00362 if (nentry > 1)
00363 fix_entry_returns();
00364 epicode();
00365 donmlist();
00366 dobss();
00367 start_formatting ();
00368 if (nentry > 1)
00369 putentries(c_file);
00370
00371 zap_changes();
00372 procinit();
00373 }
00374
00375
00376
00377
00378
00379 void
00380 enddcl(Void)
00381 {
00382 register struct Entrypoint *ep;
00383 struct Entrypoint *ep0;
00384 chainp cp;
00385 extern char *err_proc;
00386 static char comblks[] = "common blocks";
00387
00388 err_proc = comblks;
00389 docommon();
00390
00391
00392
00393
00394
00395 err_proc = "equivalences";
00396 doequiv();
00397
00398 err_proc = comblks;
00399 docomleng();
00400
00401
00402
00403
00404 err_proc = "entries";
00405 if (ep = ep0 = (struct Entrypoint *)revchain((chainp)entries)) {
00406
00407 do doentry(ep);
00408 while(ep = ep->entnextp);
00409 entries = (struct Entrypoint *)revchain((chainp)ep0);
00410 }
00411
00412 err_proc = 0;
00413 parstate = INEXEC;
00414 p1put(P1_PROCODE);
00415 freetemps();
00416 if (earlylabs) {
00417 for(cp = earlylabs = revchain(earlylabs); cp; cp = cp->nextp)
00418 p1_label((long)cp->datap);
00419 frchain(&earlylabs);
00420 }
00421 p1_line_number(lineno);
00422
00423 }
00424
00425
00426
00427
00428
00429 void
00430 #ifdef KR_headers
00431 startproc(progname, Class)
00432 Extsym *progname;
00433 int Class;
00434 #else
00435 startproc(Extsym *progname, int Class)
00436 #endif
00437 {
00438 register struct Entrypoint *p;
00439
00440 p = ALLOC(Entrypoint);
00441 if(Class == CLMAIN) {
00442 puthead(CNULL, CLMAIN);
00443 if (progname)
00444 strcpy (main_alias, progname->cextname);
00445 } else {
00446 if (progname) {
00447
00448
00449
00450
00451 entrypt(CLPROC, TYSUBR, (ftnint)0, progname, (chainp)0);
00452 endproc();
00453 newproc();
00454 }
00455 puthead(CNULL, CLBLOCK);
00456 }
00457 if(Class == CLMAIN)
00458 newentry( mkname(" MAIN"), 0 )->extinit = 1;
00459 p->entryname = progname;
00460 entries = p;
00461
00462 procclass = Class;
00463 fprintf(diagfile, " %s", (Class==CLMAIN ? "MAIN" : "BLOCK DATA") );
00464 if(progname) {
00465 fprintf(diagfile, " %s", progname->fextname);
00466 procname = progname->cextname;
00467 }
00468 fprintf(diagfile, ":\n");
00469 fflush(diagfile);
00470 }
00471
00472
00473
00474 Extsym *
00475 #ifdef KR_headers
00476 newentry(v, substmsg)
00477 register Namep v;
00478 int substmsg;
00479 #else
00480 newentry(register Namep v, int substmsg)
00481 #endif
00482 {
00483 register Extsym *p;
00484 char buf[128], badname[64];
00485 static int nbad = 0;
00486 static char already[] = "external name already used";
00487
00488 p = mkext(v->fvarname, addunder(v->cvarname));
00489
00490 if(p->extinit || ! ONEOF(p->extstg, M(STGUNKNOWN)|M(STGEXT)) )
00491 {
00492 sprintf(badname, "%s_bad%d", v->fvarname, ++nbad);
00493 if (substmsg) {
00494 sprintf(buf,"%s\n\tsubstituting \"%s\"",
00495 already, badname);
00496 dclerr(buf, v);
00497 }
00498 else
00499 dclerr(already, v);
00500 p = mkext(v->fvarname, badname);
00501 }
00502 v->vstg = STGAUTO;
00503 v->vprocclass = PTHISPROC;
00504 v->vclass = CLPROC;
00505 if (p->extstg == STGEXT)
00506 prev_proc = 1;
00507 else
00508 p->extstg = STGEXT;
00509 p->extinit = YES;
00510 v->vardesc.varno = p - extsymtab;
00511 return(p);
00512 }
00513
00514 void
00515 #ifdef KR_headers
00516 entrypt(Class, type, length, entry, args)
00517 int Class;
00518 int type;
00519 ftnint length;
00520 Extsym *entry;
00521 chainp args;
00522 #else
00523 entrypt(int Class, int type, ftnint length, Extsym *entry, chainp args)
00524 #endif
00525 {
00526 register Namep q;
00527 register struct Entrypoint *p;
00528
00529 if(Class != CLENTRY)
00530 puthead( procname = entry->cextname, Class);
00531 else
00532 fprintf(diagfile, " entry ");
00533 fprintf(diagfile, " %s:\n", entry->fextname);
00534 fflush(diagfile);
00535 q = mkname(entry->fextname);
00536 if (type == TYSUBR)
00537 q->vstg = STGEXT;
00538
00539 type = lengtype(type, length);
00540 if(Class == CLPROC)
00541 {
00542 procclass = CLPROC;
00543 proctype = type;
00544 procleng = type == TYCHAR ? length : 0;
00545 }
00546
00547 p = ALLOC(Entrypoint);
00548
00549 p->entnextp = entries;
00550 entries = p;
00551
00552 p->entryname = entry;
00553 p->arglist = revchain(args);
00554 p->enamep = q;
00555
00556 if(Class == CLENTRY)
00557 {
00558 Class = CLPROC;
00559 if(proctype == TYSUBR)
00560 type = TYSUBR;
00561 }
00562
00563 q->vclass = Class;
00564 q->vprocclass = 0;
00565 settype(q, type, length);
00566 q->vprocclass = PTHISPROC;
00567
00568 if(parstate >= INDATA)
00569 doentry(p);
00570 }
00571
00572
00573
00574
00575
00576
00577
00578 LOCAL void
00579 epicode(Void)
00580 {
00581 extern int lastwasbranch;
00582
00583 if(procclass==CLPROC)
00584 {
00585 if(proctype==TYSUBR)
00586 {
00587
00588
00589
00590
00591 if ((substars || Ansi) && lastwasbranch != YES)
00592 p1_subr_ret (ICON(0));
00593 }
00594 else if (!multitype && lastwasbranch != YES)
00595 retval(proctype);
00596 }
00597 else if (procclass == CLMAIN && Ansi && lastwasbranch != YES)
00598 p1_subr_ret (ICON(0));
00599 lastwasbranch = NO;
00600 }
00601
00602
00603
00604
00605 LOCAL void
00606 #ifdef KR_headers
00607 retval(t)
00608 register int t;
00609 #else
00610 retval(register int t)
00611 #endif
00612 {
00613 register Addrp p;
00614
00615 switch(t)
00616 {
00617 case TYCHAR:
00618 case TYCOMPLEX:
00619 case TYDCOMPLEX:
00620 break;
00621
00622 case TYLOGICAL:
00623 t = tylogical;
00624 case TYINT1:
00625 case TYADDR:
00626 case TYSHORT:
00627 case TYLONG:
00628 #ifdef TYQUAD
00629 case TYQUAD:
00630 #endif
00631 case TYREAL:
00632 case TYDREAL:
00633 case TYLOGICAL1:
00634 case TYLOGICAL2:
00635 p = (Addrp) cpexpr((expptr)retslot);
00636 p->vtype = t;
00637 p1_subr_ret (mkconv (t, fixtype((expptr)p)));
00638 break;
00639
00640 default:
00641 badtype("retval", t);
00642 }
00643 }
00644
00645
00646
00647
00648 void
00649 #ifdef KR_headers
00650 procode(outfile)
00651 FILE *outfile;
00652 #else
00653 procode(FILE *outfile)
00654 #endif
00655 {
00656 prolog(outfile, allargs);
00657
00658 if (nentry > 1)
00659 entry_goto(outfile);
00660 }
00661
00662 static void
00663 #ifdef KR_headers
00664 bad_dimtype(q) Namep q;
00665 #else
00666 bad_dimtype(Namep q)
00667 #endif
00668 {
00669 errstr("bad dimension type for %.70s", q->fvarname);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 static void
00681 #ifdef KR_headers
00682 dim_finish(v)
00683 Namep v;
00684 #else
00685 dim_finish(Namep v)
00686 #endif
00687 {
00688 register struct Dimblock *p;
00689 register expptr q;
00690 register int i, nd;
00691
00692 p = v->vdim;
00693 v->vdimfinish = 0;
00694 nd = p->ndim;
00695 doin_setbound = 1;
00696 for(i = 0; i < nd; i++)
00697 if (q = p->dims[i].dimexpr) {
00698 q = p->dims[i].dimexpr = make_int_expr(putx(fixtype(q)));
00699 if (!ONEOF(q->headblock.vtype, MSKINT|MSKREAL))
00700 bad_dimtype(v);
00701 }
00702 if (q = p->basexpr)
00703 p->basexpr = make_int_expr(putx(fixtype(q)));
00704 doin_setbound = 0;
00705 }
00706
00707 static void
00708 #ifdef KR_headers
00709 duparg(q)
00710 Namep q;
00711 #else
00712 duparg(Namep q)
00713 #endif
00714 { errstr("duplicate argument %.80s", q->fvarname); }
00715
00716
00717
00718
00719
00720
00721 LOCAL void
00722 #ifdef KR_headers
00723 doentry(ep)
00724 struct Entrypoint *ep;
00725 #else
00726 doentry(struct Entrypoint *ep)
00727 #endif
00728 {
00729 register int type;
00730 register Namep np;
00731 chainp p, p1;
00732 register Namep q;
00733 Addrp rs;
00734 int it, k;
00735 extern char dflttype[26];
00736 Extsym *entryname = ep->entryname;
00737
00738 if (++nentry > 1)
00739 p1_label((long)(extsymtab - entryname - 1));
00740
00741
00742
00743
00744 if(procclass == CLMAIN && !ep->arglist || procclass == CLBLOCK)
00745 return;
00746
00747
00748
00749
00750
00751
00752
00753 impldcl( np = mkname(entryname->fextname) );
00754 type = np->vtype;
00755 proc_argchanges = prev_proc && type != entryname->extype;
00756 entryname->extseen = 1;
00757 if(proctype == TYUNKNOWN)
00758 if( (proctype = type) == TYCHAR)
00759 procleng = np->vleng ? np->vleng->constblock.Const.ci
00760 : (ftnint) (-1);
00761
00762 if(proctype == TYCHAR)
00763 {
00764 if(type != TYCHAR)
00765 err("noncharacter entry of character function");
00766
00767
00768
00769
00770 else if( (np->vleng ? np->vleng->constblock.Const.ci :
00771 (ftnint) (-1)) != procleng)
00772 err("mismatched character entry lengths");
00773 }
00774 else if(type == TYCHAR)
00775 err("character entry of noncharacter function");
00776 else if(type != proctype)
00777 multitype = YES;
00778 if(rtvlabel[type] == 0)
00779 rtvlabel[type] = (int)newlabel();
00780 ep->typelabel = rtvlabel[type];
00781
00782 if(type == TYCHAR)
00783 {
00784 if(chslot < 0)
00785 {
00786 chslot = nextarg(TYADDR);
00787 chlgslot = nextarg(TYLENG);
00788 }
00789 np->vstg = STGARG;
00790
00791
00792
00793
00794
00795 if(procleng < 0) {
00796 np->vleng = (expptr) mkarg(TYLENG, chlgslot);
00797 np->vleng->addrblock.uname_tag = UNAM_IDENT;
00798 strcpy (np -> vleng -> addrblock.user.ident,
00799 new_func_length());
00800 }
00801 if (!xretslot[TYCHAR]) {
00802 xretslot[TYCHAR] = rs =
00803 autovar(0, type, ISCONST(np->vleng)
00804 ? np->vleng : ICON(0), "");
00805 strcpy(rs->user.ident, "ret_val");
00806 }
00807 }
00808
00809
00810
00811
00812 else if( ISCOMPLEX(type) ) {
00813 if (!xretslot[type])
00814 xretslot[type] =
00815 autovar(0, type, EXNULL, " ret_val");
00816
00817 np->vstg = STGARG;
00818 if(cxslot < 0)
00819 cxslot = nextarg(TYADDR);
00820 }
00821 else if (type != TYSUBR) {
00822 if (type == TYUNKNOWN) {
00823 dclerr("untyped function", np);
00824 proctype = type = np->vtype =
00825 dflttype[letter(np->fvarname[0])];
00826 }
00827 if (!xretslot[type])
00828 xretslot[type] = retslot =
00829 autovar(1, type, EXNULL, " ret_val");
00830
00831 np->vstg = STGAUTO;
00832 }
00833
00834 for(p = ep->arglist ; p ; p = p->nextp)
00835 if(! (( q = (Namep) (p->datap) )->vknownarg) ) {
00836 q->vknownarg = 1;
00837 q->vardesc.varno = nextarg(TYADDR);
00838 allargs = mkchain((char *)q, allargs);
00839 q->argno = nallargs++;
00840 }
00841 else if (nentry == 1)
00842 duparg(q);
00843 else for(p1 = ep->arglist ; p1 != p; p1 = p1->nextp)
00844 if ((Namep)p1->datap == q)
00845 duparg(q);
00846
00847 k = 0;
00848 for(p = ep->arglist ; p ; p = p->nextp) {
00849 if(! (( q = (Namep) (p->datap) )->vdcldone) )
00850 {
00851 impldcl(q);
00852 q->vdcldone = YES;
00853 if(q->vtype == TYCHAR)
00854 {
00855
00856
00857
00858
00859 ++nallchargs;
00860 if (q->vclass == CLPROC)
00861 nallchargs--;
00862 else if (q->vleng == NULL) {
00863
00864 q->vleng = (expptr)
00865 mkarg(TYLENG, nextarg(TYLENG) );
00866 unamstring((Addrp)q->vleng,
00867 new_arg_length(q));
00868 }
00869 }
00870 }
00871 if (q->vdimfinish)
00872 dim_finish(q);
00873 if (q->vtype == TYCHAR && q->vclass != CLPROC)
00874 k++;
00875 }
00876
00877 if (entryname->extype != type)
00878 changedtype(np);
00879
00880
00881
00882 it = infertypes;
00883 if (entryname->exproto)
00884 infertypes = 1;
00885 save_argtypes(ep->arglist, &entryname->arginfo, &np->arginfo,
00886 0, np->fvarname, STGEXT, k, np->vtype, 2);
00887 infertypes = it;
00888 }
00889
00890
00891
00892 LOCAL int
00893 #ifdef KR_headers
00894 nextarg(type)
00895 int type;
00896 #else
00897 nextarg(int type)
00898 #endif
00899 {
00900 type = type;
00901 return(lastargslot++);
00902 }
00903
00904 LOCAL void
00905 #ifdef KR_headers
00906 dim_check(q)
00907 Namep q;
00908 #else
00909 dim_check(Namep q)
00910 #endif
00911 {
00912 register struct Dimblock *vdim = q->vdim;
00913 register expptr nelt;
00914
00915 if(!(nelt = vdim->nelt) || !ISCONST(nelt))
00916 dclerr("adjustable dimension on non-argument", q);
00917 else if (!ONEOF(nelt->headblock.vtype, MSKINT|MSKREAL))
00918 bad_dimtype(q);
00919 else if (ISINT(nelt->headblock.vtype)
00920 ? nelt->constblock.Const.ci <= 0
00921 : nelt->constblock.Const.cd[0] <= 0.)
00922 dclerr("nonpositive dimension", q);
00923 }
00924
00925 LOCAL void
00926 dobss(Void)
00927 {
00928 register struct Hashentry *p;
00929 register Namep q;
00930 int qstg, qclass, qtype;
00931 Extsym *e;
00932
00933 for(p = hashtab ; p<lasthash ; ++p)
00934 if(q = p->varp)
00935 {
00936 qstg = q->vstg;
00937 qtype = q->vtype;
00938 qclass = q->vclass;
00939
00940 if( (qclass==CLUNKNOWN && qstg!=STGARG) ||
00941 (qclass==CLVAR && qstg==STGUNKNOWN) ) {
00942 if (!(q->vis_assigned | q->vimpldovar))
00943 warn1("local variable %s never used",
00944 q->fvarname);
00945 }
00946 else if(qclass==CLVAR && qstg==STGBSS)
00947 { ; }
00948
00949
00950
00951 else if(qclass==CLPROC && q->vprocclass==PEXTERNAL
00952 && qstg!=STGARG) {
00953 e = mkext(q->fvarname,addunder(q->cvarname));
00954 e->extstg = STGEXT;
00955 q->vardesc.varno = e - extsymtab;
00956 if (e->extype != qtype)
00957 changedtype(q);
00958 }
00959 if(qclass==CLVAR) {
00960 if (qstg != STGARG && q->vdim)
00961 dim_check(q);
00962 }
00963 }
00964
00965 }
00966
00967
00968 void
00969 donmlist(Void)
00970 {
00971 register struct Hashentry *p;
00972 register Namep q;
00973
00974 for(p=hashtab; p<lasthash; ++p)
00975 if( (q = p->varp) && q->vclass==CLNAMELIST)
00976 namelist(q);
00977 }
00978
00979
00980
00981
00982 ftnint
00983 #ifdef KR_headers
00984 iarrlen(q)
00985 register Namep q;
00986 #else
00987 iarrlen(register Namep q)
00988 #endif
00989 {
00990 ftnint leng;
00991
00992 leng = typesize[q->vtype];
00993 if(leng <= 0)
00994 return(-1);
00995 if(q->vdim)
00996 if( ISICON(q->vdim->nelt) )
00997 leng *= q->vdim->nelt->constblock.Const.ci;
00998 else return(-1);
00999 if(q->vleng)
01000 if( ISICON(q->vleng) )
01001 leng *= q->vleng->constblock.Const.ci;
01002 else return(-1);
01003 return(leng);
01004 }
01005
01006 void
01007 #ifdef KR_headers
01008 namelist(np)
01009 Namep np;
01010 #else
01011 namelist(Namep np)
01012 #endif
01013 {
01014 register chainp q;
01015 register Namep v;
01016 int y;
01017
01018 if (!np->visused)
01019 return;
01020 y = 0;
01021
01022 for(q = np->varxptr.namelist ; q ; q = q->nextp)
01023 {
01024 vardcl( v = (Namep) (q->datap) );
01025 if( !ONEOF(v->vstg, MSKSTATIC) )
01026 dclerr("may not appear in namelist", v);
01027 else {
01028 v->vnamelist = 1;
01029 v->visused = 1;
01030 v->vsave = 1;
01031 y = 1;
01032 }
01033 np->visused = y;
01034 }
01035 }
01036
01037
01038
01039
01040 LOCAL void
01041 docommon(Void)
01042 {
01043 register Extsym *extptr;
01044 register chainp q, q1;
01045 struct Dimblock *t;
01046 expptr neltp;
01047 register Namep comvar;
01048 ftnint size;
01049 int i, k, pref, type;
01050 extern int type_pref[];
01051
01052 for(extptr = extsymtab ; extptr<nextext ; ++extptr)
01053 if (extptr->extstg == STGCOMMON && (q = extptr->extp)) {
01054
01055
01056
01057 q = extptr->extp = revchain(q);
01058 pref = 1;
01059 for(k = TYCHAR; q ; q = q->nextp)
01060 {
01061 comvar = (Namep) (q->datap);
01062
01063 if(comvar->vdcldone == NO)
01064 vardcl(comvar);
01065 type = comvar->vtype;
01066 if (pref < type_pref[type])
01067 pref = type_pref[k = type];
01068 if(extptr->extleng % typealign[type] != 0) {
01069 dclerr("common alignment", comvar);
01070 --nerr;
01071 #if 0
01072 extptr->extleng = roundup(extptr->extleng, typealign[type]);
01073 #endif
01074 }
01075
01076
01077
01078 comvar->voffset = extptr->extleng;
01079 comvar->vardesc.varno = extptr - extsymtab;
01080 if(type == TYCHAR)
01081 if (comvar->vleng)
01082 size = comvar->vleng->constblock.Const.ci;
01083 else {
01084 dclerr("character*(*) in common", comvar);
01085 size = 1;
01086 }
01087 else
01088 size = typesize[type];
01089 if(t = comvar->vdim)
01090 if( (neltp = t->nelt) && ISCONST(neltp) )
01091 size *= neltp->constblock.Const.ci;
01092 else
01093 dclerr("adjustable array in common", comvar);
01094
01095
01096
01097 extptr->extleng += size;
01098 }
01099
01100 extptr->extype = k;
01101
01102
01103
01104 q1 = extptr->extp;
01105 for (q = extptr->allextp, i = 0; q; i++, q = q->nextp)
01106 if (struct_eq((chainp)q->datap, q1))
01107 break;
01108 if (q)
01109 extptr->curno = extptr->maxno - i;
01110 else {
01111 extptr->curno = ++extptr->maxno;
01112 extptr->allextp = mkchain((char *)extptr->extp,
01113 extptr->allextp);
01114 }
01115 }
01116
01117
01118
01119
01120 }
01121
01122
01123
01124
01125
01126 void
01127 #ifdef KR_headers
01128 copy_data(list)
01129 chainp list;
01130 #else
01131 copy_data(chainp list)
01132 #endif
01133 {
01134 for (; list; list = list -> nextp) {
01135 Namep namep = ALLOC (Nameblock);
01136 int size, nd, i;
01137 struct Dimblock *dp;
01138
01139 cpn(sizeof(struct Nameblock), list->datap, (char *)namep);
01140 namep->fvarname = strcpy(gmem(strlen(namep->fvarname)+1,0),
01141 namep->fvarname);
01142 namep->cvarname = strcmp(namep->fvarname, namep->cvarname)
01143 ? strcpy(gmem(strlen(namep->cvarname)+1,0), namep->cvarname)
01144 : namep->fvarname;
01145 if (namep -> vleng)
01146 namep -> vleng = (expptr) cpexpr (namep -> vleng);
01147 if (namep -> vdim) {
01148 nd = namep -> vdim -> ndim;
01149 size = sizeof(int) + (3 + 2 * nd) * sizeof (expptr);
01150 dp = (struct Dimblock *) ckalloc (size);
01151 cpn(size, (char *)namep->vdim, (char *)dp);
01152 namep -> vdim = dp;
01153 dp->nelt = (expptr)cpexpr(dp->nelt);
01154 for (i = 0; i < nd; i++) {
01155 dp -> dims[i].dimsize = (expptr) cpexpr (dp -> dims[i].dimsize);
01156 }
01157 }
01158 list -> datap = (char *) namep;
01159 }
01160 }
01161
01162
01163
01164 LOCAL void
01165 docomleng(Void)
01166 {
01167 register Extsym *p;
01168
01169 for(p = extsymtab ; p < nextext ; ++p)
01170 if(p->extstg == STGCOMMON)
01171 {
01172 if(p->maxleng!=0 && p->extleng!=0 && p->maxleng!=p->extleng
01173 && strcmp(Blank, p->cextname) )
01174 warn1("incompatible lengths for common block %.60s",
01175 p->fextname);
01176 if(p->maxleng < p->extleng)
01177 p->maxleng = p->extleng;
01178 p->extleng = 0;
01179 }
01180 }
01181
01182
01183
01184
01185 void
01186 #ifdef KR_headers
01187 frtemp(p)
01188 Addrp p;
01189 #else
01190 frtemp(Addrp p)
01191 #endif
01192 {
01193
01194 holdtemps = mkchain((char *)p, holdtemps);
01195 }
01196
01197 void
01198 freetemps(Void)
01199 {
01200 register chainp p, p1;
01201 register Addrp q;
01202 register int t;
01203
01204 p1 = holdtemps;
01205 while(p = p1) {
01206 q = (Addrp)p->datap;
01207 t = q->vtype;
01208 if (t == TYCHAR && q->varleng != 0) {
01209
01210 frexpr(q->vleng);
01211 q->vleng = ICON(q->varleng);
01212 }
01213 p1 = p->nextp;
01214 p->nextp = templist[t];
01215 templist[t] = p;
01216 }
01217 holdtemps = 0;
01218 }
01219
01220
01221
01222 Addrp
01223 #ifdef KR_headers
01224 autovar(nelt0, t, lengp, name)
01225 register int nelt0;
01226 register int t;
01227 expptr lengp;
01228 char *name;
01229 #else
01230 autovar(register int nelt0, register int t, expptr lengp, char *name)
01231 #endif
01232 {
01233 ftnint leng;
01234 register Addrp q;
01235 register int nelt = nelt0 > 0 ? nelt0 : 1;
01236 extern char *av_pfix[];
01237
01238 if(t == TYCHAR)
01239 if( ISICON(lengp) )
01240 leng = lengp->constblock.Const.ci;
01241 else {
01242 Fatal("automatic variable of nonconstant length");
01243 }
01244 else
01245 leng = typesize[t];
01246
01247 q = ALLOC(Addrblock);
01248 q->tag = TADDR;
01249 q->vtype = t;
01250 if(t == TYCHAR)
01251 {
01252 q->vleng = ICON(leng);
01253 q->varleng = leng;
01254 }
01255 q->vstg = STGAUTO;
01256 q->ntempelt = nelt;
01257 q->isarray = (nelt > 1);
01258 q->memoffset = ICON(0);
01259
01260
01261 if (*name == ' ')
01262 unamstring(q, name);
01263 else {
01264 q->uname_tag = UNAM_IDENT;
01265 temp_name(av_pfix[t], ++autonum[t], q->user.ident);
01266 }
01267 if (nelt0 > 0)
01268 declare_new_addr (q);
01269 return(q);
01270 }
01271
01272
01273
01274
01275
01276 Addrp
01277 #ifdef KR_headers
01278 mktmpn(nelt, type, lengp)
01279 int nelt;
01280 register int type;
01281 expptr lengp;
01282 #else
01283 mktmpn(int nelt, register int type, expptr lengp)
01284 #endif
01285 {
01286 ftnint leng;
01287 chainp p, oldp;
01288 register Addrp q;
01289 extern int krparens;
01290
01291 if(type==TYUNKNOWN || type==TYERROR)
01292 badtype("mktmpn", type);
01293
01294 if(type==TYCHAR)
01295 if(lengp && ISICON(lengp) )
01296 leng = lengp->constblock.Const.ci;
01297 else {
01298 err("adjustable length");
01299 return( (Addrp) errnode() );
01300 }
01301 else if (type > TYCHAR || type < TYADDR) {
01302 erri("mktmpn: unexpected type %d", type);
01303 exit(1);
01304 }
01305
01306
01307
01308
01309 if (krparens == 2 && ONEOF(type,M(TYREAL)|M(TYCOMPLEX)))
01310 type++;
01311 for(oldp=CHNULL, p=templist[type]; p ; oldp=p, p=p->nextp)
01312 {
01313 q = (Addrp) (p->datap);
01314 if(q->ntempelt==nelt &&
01315 (type!=TYCHAR || q->vleng->constblock.Const.ci==leng) )
01316 {
01317 if(oldp)
01318 oldp->nextp = p->nextp;
01319 else
01320 templist[type] = p->nextp;
01321 free( (charptr) p);
01322 return(q);
01323 }
01324 }
01325 q = autovar(nelt, type, lengp, "");
01326 return(q);
01327 }
01328
01329
01330
01331
01332
01333
01334
01335 Addrp
01336 #ifdef KR_headers
01337 mktmp(type, lengp)
01338 int type;
01339 expptr lengp;
01340 #else
01341 mktmp(int type, expptr lengp)
01342 #endif
01343 {
01344 Addrp rv;
01345
01346
01347 rv = mktmpn(1,type,lengp);
01348 frtemp((Addrp)cpexpr((expptr)rv));
01349 return rv;
01350 }
01351
01352
01353 Addrp
01354 #ifdef KR_headers
01355 mktmp0(type, lengp)
01356 int type;
01357 expptr lengp;
01358 #else
01359 mktmp0(int type, expptr lengp)
01360 #endif
01361 {
01362 Addrp rv;
01363
01364
01365 rv = mktmpn(1,type,lengp);
01366 rv->istemp = YES;
01367 return rv;
01368 }
01369
01370
01371
01372
01373
01374
01375 Extsym *
01376 #ifdef KR_headers
01377 comblock(s)
01378 register char *s;
01379 #else
01380 comblock(register char *s)
01381 #endif
01382 {
01383 Extsym *p;
01384 register char *t;
01385 register int c, i;
01386 char cbuf[256], *s0;
01387
01388
01389
01390 if(*s == 0)
01391 p = mkext1(s0 = Blank, Blank);
01392 else {
01393 s0 = s;
01394 t = cbuf;
01395 for(i = 0; c = *t = *s++; t++)
01396 if (c == '_')
01397 i = 1;
01398 if (i)
01399 *t++ = '_';
01400 t[0] = '_';
01401 t[1] = 0;
01402 p = mkext1(s0,cbuf);
01403 }
01404 if(p->extstg == STGUNKNOWN)
01405 p->extstg = STGCOMMON;
01406 else if(p->extstg != STGCOMMON)
01407 {
01408 errstr("%.52s cannot be a common block: it is a subprogram.",
01409 s0);
01410 return(0);
01411 }
01412
01413 return( p );
01414 }
01415
01416
01417
01418
01419 void
01420 #ifdef KR_headers
01421 incomm(c, v)
01422 Extsym *c;
01423 Namep v;
01424 #else
01425 incomm(Extsym *c, Namep v)
01426 #endif
01427 {
01428 if (!c)
01429 return;
01430 if(v->vstg != STGUNKNOWN && !v->vimplstg)
01431 dclerr(v->vstg == STGARG
01432 ? "dummy arguments cannot be in common"
01433 : "incompatible common declaration", v);
01434 else
01435 {
01436 v->vstg = STGCOMMON;
01437 c->extp = mkchain((char *)v, c->extp);
01438 }
01439 }
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449 void
01450 #ifdef KR_headers
01451 settype(v, type, length)
01452 register Namep v;
01453 register int type;
01454 register ftnint length;
01455 #else
01456 settype(register Namep v, register int type, register ftnint length)
01457 #endif
01458 {
01459 int type1;
01460
01461 if(type == TYUNKNOWN)
01462 return;
01463
01464 if(type==TYSUBR && v->vtype!=TYUNKNOWN && v->vstg==STGARG)
01465 {
01466 v->vtype = TYSUBR;
01467 frexpr(v->vleng);
01468 v->vleng = 0;
01469 v->vimpltype = 0;
01470 }
01471 else if(type < 0)
01472 {
01473 if(v->vstg == STGUNKNOWN)
01474 v->vstg = - type;
01475 else if(v->vstg != -type)
01476 dclerr("incompatible storage declarations", v);
01477 }
01478 else if(v->vtype == TYUNKNOWN
01479 || v->vtype != type
01480 && (v->vimpltype || v->vinftype || v->vinfproc))
01481 {
01482 if( (v->vtype = lengtype(type, length))==TYCHAR )
01483 if (length>=0)
01484 v->vleng = ICON(length);
01485 else if (parstate >= INDATA)
01486 v->vleng = ICON(1);
01487 v->vimpltype = 0;
01488 v->vinftype = 0;
01489 v->vinfproc = 0;
01490
01491 if (v->vclass == CLPROC) {
01492 if (v->vstg == STGEXT
01493 && (type1 = extsymtab[v->vardesc.varno].extype)
01494 && type1 != v->vtype)
01495 changedtype(v);
01496 else if (v->vprocclass == PTHISPROC
01497 && (parstate >= INDATA
01498 || procclass == CLMAIN)
01499 && !xretslot[type]) {
01500 xretslot[type] = autovar(ONEOF(type,
01501 MSKCOMPLEX|MSKCHAR) ? 0 : 1, type,
01502 v->vleng, " ret_val");
01503 if (procclass == CLMAIN)
01504 errstr(
01505 "illegal use of %.60s (main program name)",
01506 v->fvarname);
01507
01508
01509
01510 }
01511 }
01512 }
01513 else if(v->vtype != type && v->vtype != lengtype(type, length)) {
01514 incompat:
01515 dclerr("incompatible type declarations", v);
01516 }
01517 else if (type==TYCHAR)
01518 if (v->vleng && v->vleng->constblock.Const.ci != length)
01519 goto incompat;
01520 else if (parstate >= INDATA)
01521 v->vleng = ICON(1);
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531 int
01532 #ifdef KR_headers
01533 lengtype(type, len)
01534 register int type;
01535 ftnint len;
01536 #else
01537 lengtype(register int type, ftnint len)
01538 #endif
01539 {
01540 register int length = (int)len;
01541 switch(type)
01542 {
01543 case TYREAL:
01544 if(length == typesize[TYDREAL])
01545 return(TYDREAL);
01546 if(length == typesize[TYREAL])
01547 goto ret;
01548 break;
01549
01550 case TYCOMPLEX:
01551 if(length == typesize[TYDCOMPLEX])
01552 return(TYDCOMPLEX);
01553 if(length == typesize[TYCOMPLEX])
01554 goto ret;
01555 break;
01556
01557 case TYINT1:
01558 case TYSHORT:
01559 case TYDREAL:
01560 case TYDCOMPLEX:
01561 case TYCHAR:
01562 case TYLOGICAL1:
01563 case TYLOGICAL2:
01564 case TYUNKNOWN:
01565 case TYSUBR:
01566 case TYERROR:
01567 #ifdef TYQUAD
01568 case TYQUAD:
01569 #endif
01570 goto ret;
01571
01572 case TYLOGICAL:
01573 switch(length) {
01574 case 0: return tylog;
01575 case 1: return TYLOGICAL1;
01576 case 2: return TYLOGICAL2;
01577 case 4: goto ret;
01578 }
01579 break;
01580
01581 case TYLONG:
01582 if(length == 0)
01583 return(tyint);
01584 if (length == 1)
01585 return TYINT1;
01586 if(length == typesize[TYSHORT])
01587 return(TYSHORT);
01588 #ifdef TYQUAD
01589 if(length == typesize[TYQUAD] && use_tyquad)
01590 return(TYQUAD);
01591 #endif
01592 if(length == typesize[TYLONG])
01593 goto ret;
01594 break;
01595 default:
01596 badtype("lengtype", type);
01597 }
01598
01599 if(len != 0)
01600 err("incompatible type-length combination");
01601
01602 ret:
01603 return(type);
01604 }
01605
01606
01607
01608
01609
01610
01611
01612 void
01613 #ifdef KR_headers
01614 setintr(v)
01615 register Namep v;
01616 #else
01617 setintr(register Namep v)
01618 #endif
01619 {
01620 int k;
01621
01622 if(k = intrfunct(v->fvarname)) {
01623 if ((*(struct Intrpacked *)&k).f4)
01624 if (noextflag)
01625 goto unknown;
01626 else
01627 dcomplex_seen++;
01628 v->vardesc.varno = k;
01629 }
01630 else {
01631 unknown:
01632 dclerr("unknown intrinsic function", v);
01633 return;
01634 }
01635 if(v->vstg == STGUNKNOWN)
01636 v->vstg = STGINTR;
01637 else if(v->vstg!=STGINTR)
01638 dclerr("incompatible use of intrinsic function", v);
01639 if(v->vclass==CLUNKNOWN)
01640 v->vclass = CLPROC;
01641 if(v->vprocclass == PUNKNOWN)
01642 v->vprocclass = PINTRINSIC;
01643 else if(v->vprocclass != PINTRINSIC)
01644 dclerr("invalid intrinsic declaration", v);
01645 }
01646
01647
01648
01649
01650
01651
01652 void
01653 #ifdef KR_headers
01654 setext(v)
01655 register Namep v;
01656 #else
01657 setext(register Namep v)
01658 #endif
01659 {
01660 if(v->vclass == CLUNKNOWN)
01661 v->vclass = CLPROC;
01662 else if(v->vclass != CLPROC)
01663 dclerr("invalid external declaration", v);
01664
01665 if(v->vprocclass == PUNKNOWN)
01666 v->vprocclass = PEXTERNAL;
01667 else if(v->vprocclass != PEXTERNAL)
01668 dclerr("invalid external declaration", v);
01669 }
01670
01671
01672
01673
01674
01675
01676 void
01677 #ifdef KR_headers
01678 setbound(v, nd, dims)
01679 register Namep v;
01680 int nd;
01681 struct Dims *dims;
01682 #else
01683 setbound(Namep v, int nd, struct Dims *dims)
01684 #endif
01685 {
01686 expptr q, q0, t;
01687 struct Dimblock *p;
01688 int i;
01689 extern chainp new_vars;
01690 char buf[256];
01691
01692 if(v->vclass == CLUNKNOWN)
01693 v->vclass = CLVAR;
01694 else if(v->vclass != CLVAR)
01695 {
01696 dclerr("only variables may be arrays", v);
01697 return;
01698 }
01699
01700 v->vdim = p = (struct Dimblock *)
01701 ckalloc( sizeof(int) + (3+2*nd)*sizeof(expptr) );
01702 p->ndim = nd--;
01703 p->nelt = ICON(1);
01704 doin_setbound = 1;
01705
01706 if (noextflag)
01707 for(i = 0; i <= nd; i++)
01708 if (((q = dims[i].lb) && !ISINT(q->headblock.vtype))
01709 || ((q = dims[i].ub) && !ISINT(q->headblock.vtype))) {
01710 sprintf(buf, "dimension %d of %s is not an integer.",
01711 i+1, v->fvarname);
01712 errext(buf);
01713 break;
01714 }
01715
01716 for(i = 0; i <= nd; i++) {
01717 if (((q = dims[i].lb) && !ISINT(q->headblock.vtype)))
01718 dims[i].lb = mkconv(TYINT, q);
01719 if (((q = dims[i].ub) && !ISINT(q->headblock.vtype)))
01720 dims[i].ub = mkconv(TYINT, q);
01721 }
01722
01723 for(i = 0; i <= nd; ++i)
01724 {
01725 if( (q = dims[i].ub) == NULL)
01726 {
01727 if(i == nd)
01728 {
01729 frexpr(p->nelt);
01730 p->nelt = NULL;
01731 }
01732 else
01733 err("only last bound may be asterisk");
01734 p->dims[i].dimsize = ICON(1);
01735 p->dims[i].dimexpr = NULL;
01736 }
01737 else
01738 {
01739
01740 if(dims[i].lb)
01741 {
01742 q = mkexpr(OPMINUS, q, cpexpr(dims[i].lb));
01743 q = mkexpr(OPPLUS, q, ICON(1) );
01744 }
01745 if( ISCONST(q) )
01746 {
01747 p->dims[i].dimsize = q;
01748 p->dims[i].dimexpr = (expptr) PNULL;
01749 }
01750 else {
01751 sprintf(buf, " %s_dim%d", v->fvarname, i+1);
01752 p->dims[i].dimsize = (expptr)
01753 autovar(1, tyint, EXNULL, buf);
01754 p->dims[i].dimexpr = q;
01755 if (i == nd)
01756 v->vlastdim = new_vars;
01757 v->vdimfinish = 1;
01758 }
01759 if(p->nelt)
01760 p->nelt = mkexpr(OPSTAR, p->nelt,
01761 cpexpr(p->dims[i].dimsize) );
01762 }
01763 }
01764
01765 q = dims[nd].lb;
01766 q0 = 0;
01767 if(q == NULL)
01768 q = q0 = ICON(1);
01769
01770 for(i = nd-1 ; i>=0 ; --i)
01771 {
01772 t = dims[i].lb;
01773 if(t == NULL)
01774 t = ICON(1);
01775 if(p->dims[i].dimsize) {
01776 if (q == q0) {
01777 q0 = 0;
01778 frexpr(q);
01779 q = cpexpr(p->dims[i].dimsize);
01780 }
01781 else
01782 q = mkexpr(OPSTAR, cpexpr(p->dims[i].dimsize), q);
01783 q = mkexpr(OPPLUS, t, q);
01784 }
01785 }
01786
01787 if( ISCONST(q) )
01788 {
01789 p->baseoffset = q;
01790 p->basexpr = NULL;
01791 }
01792 else
01793 {
01794 sprintf(buf, " %s_offset", v->fvarname);
01795 p->baseoffset = (expptr) autovar(1, tyint, EXNULL, buf);
01796 p->basexpr = q;
01797 v->vdimfinish = 1;
01798 }
01799 doin_setbound = 0;
01800 }
01801
01802
01803 void
01804 #ifdef KR_headers
01805 wr_abbrevs(outfile, function_head, vars)
01806 FILE *outfile;
01807 int function_head;
01808 chainp vars;
01809 #else
01810 wr_abbrevs(FILE *outfile, int function_head, chainp vars)
01811 #endif
01812 {
01813 for (; vars; vars = vars -> nextp) {
01814 Namep name = (Namep) vars -> datap;
01815 if (!name->visused)
01816 continue;
01817
01818 if (function_head)
01819 nice_printf (outfile, "#define ");
01820 else
01821 nice_printf (outfile, "#undef ");
01822 out_name (outfile, name);
01823
01824 if (function_head) {
01825 Extsym *comm = &extsymtab[name -> vardesc.varno];
01826
01827 nice_printf (outfile, " (");
01828 extern_out (outfile, comm);
01829 nice_printf (outfile, "%d.", comm->curno);
01830 nice_printf (outfile, "%s)", name->cvarname);
01831 }
01832 nice_printf (outfile, "\n");
01833 }
01834 }