1 /****************************************************************
2 Copyright 1990, 1991 by AT&T Bell Laboratories and Bellcore.
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T Bell Laboratories or
10 Bellcore or any of their entities not be used in advertising or
11 publicity pertaining to distribution of the software without
12 specific, written prior permission.
14 AT&T and Bellcore disclaim all warranties with regard to this
15 software, including all implied warranties of merchantability
16 and fitness. In no event shall AT&T or Bellcore be liable for
17 any special, indirect or consequential damages or any damages
18 whatsoever resulting from loss of use, data or profits, whether
19 in an action of contract, negligence or other tortious action,
20 arising out of or in connection with the use or performance of
22 ****************************************************************/
28 LOCAL void conspower(), consbinop(), zdiv();
29 LOCAL expptr fold(), mkpower(), stfcall();
31 #define stfcall_MAX 144
34 typedef struct { double dreal, dimag; } dcomplex;
36 extern char dflttype[26];
38 /* little routines to create constant blocks */
45 p = ALLOC(Constblock);
52 /* mklogcon -- Make Logical Constant */
59 p = mkconst(TYLOGICAL);
66 /* mkintcon -- Make Integer Constant */
81 /* mkaddcon -- Make Address Constant, given integer value */
95 /* mkrealcon -- Make Real Constant. The type t is assumed
96 to be TYREAL or TYDREAL */
98 expptr mkrealcon(t, d)
105 p->Const.cds[0] = cds(d,CNULL);
107 return( (expptr) p );
111 /* mkbitcon -- Make bit constant. Reads the input string, which is
112 assumed to correctly specify a number in base 2^shift (where shift
113 is the input parameter). shift may not exceed 4, i.e. only binary,
114 quad, octal and hex bases may be input. Constants may not exceed 32
115 bits, or whatever the size of (struct Constblock).ci may be. */
117 expptr mkbitcon(shift, leng, s)
129 x = (x << shift) | hextoi(*s++);
130 /* mwm wanted to change the type to short for short constants,
131 * but this is dangerous -- there is no syntax for long constants
135 return( (expptr) p );
142 /* mkstrcon -- Make string constant. Allocates storage and initializes
143 the memory for a copy of the input Fortran-string. */
154 p->Const.ccp = s = (char *) ckalloc(l+1);
155 p->Const.ccp1.blanks = 0;
159 return( (expptr) p );
164 /* mkcxcon -- Make complex contsant. A complex number is a pair of
165 values, each of which may be integer, real or double. */
167 expptr mkcxcon(realp,imagp)
168 register expptr realp, imagp;
174 rtype = realp->headblock.vtype;
175 itype = imagp->headblock.vtype;
177 if( ISCONST(realp) && ISNUMERIC(rtype) && ISCONST(imagp) && ISNUMERIC(itype) )
179 p = mkconst( (rtype==TYDREAL||itype==TYDREAL)
180 ? TYDCOMPLEX : tycomplex);
181 if (realp->constblock.vstg || imagp->constblock.vstg) {
183 p->Const.cds[0] = ISINT(rtype)
184 ? string_num("", realp->constblock.Const.ci)
185 : realp->constblock.vstg
186 ? realp->constblock.Const.cds[0]
187 : dtos(realp->constblock.Const.cd[0]);
188 p->Const.cds[1] = ISINT(itype)
189 ? string_num("", imagp->constblock.Const.ci)
190 : imagp->constblock.vstg
191 ? imagp->constblock.Const.cds[0]
192 : dtos(imagp->constblock.Const.cd[0]);
195 p->Const.cd[0] = ISINT(rtype)
196 ? realp->constblock.Const.ci
197 : realp->constblock.Const.cd[0];
198 p->Const.cd[1] = ISINT(itype)
199 ? imagp->constblock.Const.ci
200 : imagp->constblock.Const.cd[0];
205 err("invalid complex constant");
206 p = (Constp)errnode();
211 return( (expptr) p );
215 /* errnode -- Allocate a new error block */
219 struct Errorblock *p;
220 p = ALLOC(Errorblock);
223 return( (expptr) p );
230 /* mkconv -- Make type conversion. Cast expression p into type t.
231 Note that casting to a character copies only the first sizeof(char)
239 register int pt, charwarn = 1;
246 if(t==TYUNKNOWN || t==TYERROR)
247 badtype("mkconv", t);
248 pt = p->headblock.vtype;
250 /* Casting to the same type is a no-op */
255 /* If we're casting a constant which is not in the literal table ... */
257 else if( ISCONST(p) && pt!=TYADDR && pt != TYCHAR)
259 if (ISINT(t) && ISINT(pt) || ISREAL(t) && ISREAL(pt)) {
260 /* avoid trouble with -i2 */
261 p->headblock.vtype = t;
264 q = (expptr) mkconst(t);
265 consconv(t, &q->constblock, &p->constblock );
269 if (pt == TYCHAR && t != TYADDR && charwarn)
271 "ichar([first char. of] char. string) assumed for conversion to numeric");
276 q->constblock.vleng = ICON(1);
282 /* opconv -- Convert expression p to type t using the main
283 expression evaluator; returns an OPCONV expression, I think 14-jun-88 mwm */
292 err("illegal use of subroutine name");
293 q = mkexpr(OPCONV, p, ENULL);
294 q->headblock.vtype = t;
300 /* addrof -- Create an ADDR expression operation */
305 return( mkexpr(OPADDR, p, ENULL) );
310 /* cpexpr - Returns a new copy of input expression p */
317 register chainp ep, pp;
320 /* This table depends on the ordering of the T macros, e.g. TNAME */
322 static int blksize[ ] =
325 sizeof(struct Nameblock),
326 sizeof(struct Constblock),
327 sizeof(struct Exprblock),
328 sizeof(struct Addrblock),
329 sizeof(struct Primblock),
330 sizeof(struct Listblock),
331 sizeof(struct Impldoblock),
332 sizeof(struct Errorblock)
338 /* TNAMEs are special, and don't get copied. Each name in the current
339 symbol table has a unique TNAME structure. */
341 if( (tag = p->tag) == TNAME)
344 e = cpblock(blksize[p->tag], (char *)p);
349 if(e->constblock.vtype == TYCHAR)
351 e->constblock.Const.ccp =
352 copyn((int)e->constblock.vleng->constblock.Const.ci+1,
353 e->constblock.Const.ccp);
354 e->constblock.vleng =
355 (expptr) cpexpr(e->constblock.vleng);
361 e->exprblock.leftp = (expptr) cpexpr(p->exprblock.leftp);
362 e->exprblock.rightp = (expptr) cpexpr(p->exprblock.rightp);
366 if(pp = p->listblock.listp)
368 ep = e->listblock.listp =
369 mkchain((char *)cpexpr((tagptr)pp->datap), CHNULL);
370 for(pp = pp->nextp ; pp ; pp = pp->nextp)
372 mkchain((char *)cpexpr((tagptr)pp->datap),
378 e->addrblock.vleng = (expptr) cpexpr(e->addrblock.vleng);
379 e->addrblock.memoffset = (expptr)cpexpr(e->addrblock.memoffset);
380 e->addrblock.istemp = NO;
384 e->primblock.argsp = (struct Listblock *)
385 cpexpr((expptr)e->primblock.argsp);
386 e->primblock.fcharp = (expptr) cpexpr(e->primblock.fcharp);
387 e->primblock.lcharp = (expptr) cpexpr(e->primblock.lcharp);
391 badtag("cpexpr", tag);
397 /* frexpr -- Free expression -- frees up memory used by expression p */
412 free( (charptr) (p->constblock.Const.ccp) );
413 frexpr(p->constblock.vleng);
418 if (p->addrblock.vtype > TYERROR) /* i/o block */
420 frexpr(p->addrblock.vleng);
421 frexpr(p->addrblock.memoffset);
427 /* TNAME blocks don't get free'd - probably because they're pointed to in
428 the hash table. 14-Jun-88 -- mwm */
434 frexpr((expptr)p->primblock.argsp);
435 frexpr(p->primblock.fcharp);
436 frexpr(p->primblock.lcharp);
440 frexpr(p->exprblock.leftp);
441 if(p->exprblock.rightp)
442 frexpr(p->exprblock.rightp);
446 for(q = p->listblock.listp ; q ; q = q->nextp)
447 frexpr((tagptr)q->datap);
448 frchain( &(p->listblock.listp) );
452 badtag("frexpr", p->tag);
463 warn1("fixing wrong type inferred for %.65s", np->fvarname);
465 c = letter(np->fvarname[0]);
466 if ((np->vtype = impltype[c]) == TYCHAR
467 && (k = implleng[c]))
471 /* fix up types in expression; replace subtrees and convert
472 names to address blocks */
484 if(ONEOF(p->constblock.vtype,MSKINT|MSKLOGICAL|MSKADDR|
488 return( (expptr) putconst((Constp)p) );
491 p->addrblock.memoffset = fixtype(p->addrblock.memoffset);
498 badtag("fixtype", p->tag);
500 /* This case means that fixexpr can't call fixtype with any expr,
501 only a subexpr of its parameter. */
504 return( fixexpr((Exprp)p) );
507 return( (expptr) p );
510 if(p->primblock.argsp && p->primblock.namep->vclass!=CLVAR)
512 if(p->primblock.namep->vtype == TYSUBR)
514 err("function invocation of subroutine");
518 if (p->primblock.namep->vinftype)
519 wronginf(p->primblock.namep);
520 return( mkfunct(p) );
524 /* The lack of args makes p a function name, substring reference
527 else return( mklhs((struct Primblock *) p) );
538 rv = cpexpr(p->headblock.vleng);
539 if (ISCONST(p) && p->constblock.vtype == TYCHAR)
540 rv->constblock.Const.ci += p->constblock.Const.ccp1.blanks;
545 /* special case tree transformations and cleanups of expression trees.
546 Parameter p should have a TEXPR tag at its root, else an error is
555 int opcode, ltype, rtype, ptype, mtype;
558 return( (expptr) p );
559 else if(p->tag != TEXPR)
560 badtag("fixexpr", p->tag);
563 /* First set the types of the left and right subexpressions */
566 if (!ISCONST(lp) || lp->constblock.vtype != TYCHAR)
567 lp = p->leftp = fixtype(lp);
568 ltype = lp->headblock.vtype;
570 if(opcode==OPASSIGN && lp->tag!=TADDR)
572 err("left side of assignment must be variable");
579 if (!ISCONST(rp) || rp->constblock.vtype != TYCHAR)
580 rp = p->rightp = fixtype(rp);
581 rtype = rp->headblock.vtype;
586 if(ltype==TYERROR || rtype==TYERROR)
592 /* Now work on the whole expression */
594 /* force folding if possible */
596 if( ISCONST(lp) && (rp==NULL || ISCONST(rp)) )
598 q = opcode == OPCONV && lp->constblock.vtype == p->vtype
599 ? lp : mkexpr(opcode, lp, rp);
601 /* mkexpr is expected to reduce constant expressions */
604 p->leftp = p->rightp = 0;
608 free( (charptr) q ); /* constants did not fold */
611 if( (ptype = cktype(opcode, ltype, rtype)) == TYERROR)
617 if (ltype == TYCHAR && ISCONST(lp))
618 p->leftp = lp = (expptr)putconst((Constp)lp);
619 if (rtype == TYCHAR && ISCONST(rp))
620 p->rightp = rp = (expptr)putconst((Constp)rp);
626 p->vleng = mkexpr(OPPLUS, cplenexpr(lp),
637 if( ! ISCONST(rp) && ISREAL(ltype) && ISREAL(rtype) )
639 if( ISCOMPLEX(ltype) || ISCOMPLEX(rtype) )
641 if( ONEOF(ltype, MSKADDR|MSKINT) && ONEOF(rtype, MSKADDR|MSKINT)
642 && typesize[ltype]>=typesize[rtype] )
645 /* Cast the right hand side to match the type of the expression */
647 p->rightp = fixtype( mkconv(ptype, rp) );
651 if( ISCOMPLEX(rtype) )
653 p = (Exprp) call2(ptype,
655 /* Handle double precision complex variables */
657 ptype == TYCOMPLEX ? "c_div" : "z_div",
658 mkconv(ptype, lp), mkconv(ptype, rp) );
665 if(ptype==TYDREAL && ( (ltype==TYREAL && ! ISCONST(lp) ) ||
666 (rtype==TYREAL && ! ISCONST(rp) ) ))
668 if( ISCOMPLEX(ptype) )
671 /* Cast both sides of the expression to match the type of the whole
674 if(ltype != ptype && (ltype < TYSHORT || ptype > TYDREAL))
675 p->leftp = fixtype(mkconv(ptype,lp));
676 if(rtype != ptype && (rtype < TYSHORT || ptype > TYDREAL))
677 p->rightp = fixtype(mkconv(ptype,rp));
681 return( mkpower((expptr)p) );
691 mtype = cktype(OPMINUS, ltype, rtype);
692 if(mtype==TYDREAL && ( (ltype==TYREAL && ! ISCONST(lp)) ||
693 (rtype==TYREAL && ! ISCONST(rp)) ))
695 if( ISCOMPLEX(mtype) )
698 p->leftp = fixtype(mkconv(mtype,lp));
700 p->rightp = fixtype(mkconv(mtype,rp));
704 ptype = cktype(OPCONV, p->vtype, ltype);
705 if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA)
707 lp->exprblock.rightp =
708 fixtype( mkconv(ptype, lp->exprblock.rightp) );
715 if(lp->tag==TEXPR && lp->exprblock.opcode==OPADDR)
716 Fatal("addr of addr");
744 /* fix an argument list, taking due care for special first level cases */
747 int doput; /* doput is true if constants need to be passed by reference */
748 struct Listblock *p0;
751 register tagptr q, t;
758 for(p = p0->listp ; p ; p = p->nextp)
761 q = (tagptr)p->datap;
766 /* Call putconst() to store values in a constant table. Since even
767 constants must be passed by reference, this can optimize on the storage
770 p->datap = doput ? (char *)putconst((Constp)q)
774 /* Take a function name and turn it into an Addr. This only happens when
775 nothing else has figured out the function beforehand */
777 else if(qtag==TPRIM && q->primblock.argsp==0 &&
778 q->primblock.namep->vclass==CLPROC &&
779 q->primblock.namep->vprocclass != PTHISPROC)
780 p->datap = (char *)mkaddr(q->primblock.namep);
782 else if(qtag==TPRIM && q->primblock.argsp==0 &&
783 q->primblock.namep->vdim!=NULL)
784 p->datap = (char *)mkscalar(q->primblock.namep);
786 else if(qtag==TPRIM && q->primblock.argsp==0 &&
787 q->primblock.namep->vdovar &&
788 (t = (tagptr) memversion(q->primblock.namep)) )
789 p->datap = (char *)fixtype(t);
791 p->datap = (char *)fixtype(q);
798 /* mkscalar -- only called by fixargs above, and by some routines in
809 /* The prolog causes array arguments to point to the
810 * (0,...,0) element, unless subscript checking is on.
812 if( !checksubs && np->vstg==STGARG)
814 register struct Dimblock *dp;
816 frexpr(ap->memoffset);
817 ap->memoffset = mkexpr(OPSTAR,
820 (tagptr)ICON(typesize[np->vtype]) ),
821 cpexpr(dp->baseoffset) );
828 adjust_arginfo(np) /* adjust arginfo to omit the length arg for the
829 arg that we now know to be a character-valued
833 struct Entrypoint *ep;
834 register chainp args;
837 for(ep = entries; ep; ep = ep->entnextp)
838 for(args = ep->arglist; args; args = args->nextp)
839 if (np == (Namep)args->datap
840 && (at = ep->entryname->arginfo))
849 register struct Primblock *p = (struct Primblock *)p0;
850 struct Entrypoint *ep;
856 extern chainp new_procs;
867 if(class == CLUNKNOWN)
869 np->vclass = class = CLPROC;
870 if(np->vstg == STGUNKNOWN)
872 if(np->vtype!=TYSUBR && (k = intrfunct(np->fvarname))
873 && (zflag || !(*(struct Intrpacked *)&k).f4
877 np->vardesc.varno = k;
878 np->vprocclass = PINTRINSIC;
882 extp = mkext(np->fvarname,
883 addunder(np->cvarname));
884 extp->extstg = STGEXT;
886 np->vardesc.varno = extp - extsymtab;
887 np->vprocclass = PEXTERNAL;
890 else if(np->vstg==STGARG)
892 if(np->vtype == TYCHAR) {
895 char wbuf[160], *who;
897 sprintf(wbuf, "%s%s%s\n\t%s%s%s",
898 "Character-valued dummy procedure ",
899 who, " not declared EXTERNAL.",
900 "Code may be wrong for previous function calls having ",
901 who, " as a parameter.");
905 np->vprocclass = PEXTERNAL;
910 fatali("invalid class code %d for function", class);
912 /* F77 doesn't allow subscripting of function calls */
914 if(p->fcharp || p->lcharp)
916 err("no substring of function call");
920 np->vimpltype = 0; /* invoking as function ==> inferred type */
922 nargs = fixargs( np->vprocclass!=PINTRINSIC, p->argsp);
924 switch(np->vprocclass)
927 if(np->vtype == TYUNKNOWN)
929 dclerr("attempt to use untyped function", np);
930 np->vtype = dflttype[letter(np->fvarname[0])];
933 if (!extsymtab[np->vardesc.varno].extseen) {
934 new_procs = mkchain((char *)np, new_procs);
935 extsymtab[np->vardesc.varno].extseen = 1;
938 q = mkexpr(OPCALL, (expptr)ap, (expptr)p->argsp);
939 q->exprblock.vtype = np->vtype;
941 q->exprblock.vleng = (expptr) cpexpr(np->vleng);
945 q = intrcall(np, p->argsp, nargs);
949 q = stfcall(np, p->argsp);
953 warn("recursive call");
955 /* entries is the list of multiple entry points */
957 for(ep = entries ; ep ; ep = ep->entnextp)
961 Fatal("mkfunct: impossible recursion");
963 ap = builtin(np->vtype, ep->entryname->cextname, -2);
964 /* the negative last arg prevents adding */
965 /* this name to the list of used builtins */
969 fatali("mkfunct: impossible vprocclass %d",
970 (int) (np->vprocclass) );
982 LOCAL expptr stfcall(np, actlist)
984 struct Listblock *actlist;
986 register chainp actuals;
988 chainp oactp, formals;
990 expptr Ln, Lq, q, q1, rhs, ap;
992 register struct Rplblock *rp;
993 struct Rplblock *tlist;
994 static int inv_count;
996 if (++inv_count > stfcall_MAX)
997 Fatal("Loop invoking recursive statement function?");
1000 actuals = actlist->listp;
1001 free( (charptr) actlist);
1009 if( (type = np->vtype) == TYUNKNOWN)
1011 dclerr("attempt to use untyped statement function", np);
1012 type = np->vtype = dflttype[letter(np->fvarname[0])];
1014 formals = (chainp) np->varxptr.vstfdesc->datap;
1015 rhs = (expptr) (np->varxptr.vstfdesc->nextp);
1017 /* copy actual arguments into temporaries */
1018 while(actuals!=NULL && formals!=NULL)
1020 rp = ALLOC(Rplblock);
1021 rp->rplnp = tnp = (Namep) formals->datap;
1022 ap = fixtype((tagptr)actuals->datap);
1023 if(tnp->vtype==ap->headblock.vtype && tnp->vtype!=TYCHAR
1024 && (ap->tag==TCONST || ap->tag==TADDR) )
1027 /* If actuals are constants or variable names, no temporaries are required */
1028 rp->rplvp = (expptr) ap;
1030 rp->rpltag = ap->tag;
1033 rp->rplvp = (expptr) mktmp(tnp->vtype, tnp->vleng);
1035 putexpr ( mkexpr(OPASSIGN, cpexpr(rp->rplvp), ap));
1036 if((rp->rpltag = rp->rplvp->tag) == TERROR)
1037 err("disagreement of argument types in statement function call");
1039 rp->rplnextp = tlist;
1041 actuals = actuals->nextp;
1042 formals = formals->nextp;
1046 if(actuals!=NULL || formals!=NULL)
1047 err("statement function definition and argument list differ");
1050 now push down names involved in formal argument list, then
1051 evaluate rhs of statement function definition in this environment
1054 if(tlist) /* put tlist in front of the rpllist */
1056 for(rp = tlist; rp->rplnextp; rp = rp->rplnextp)
1058 rp->rplnextp = rpllist;
1062 /* So when the expression finally gets evaled, that evaluator must read
1063 from the globl rpllist 14-jun-88 mwm */
1065 q = (expptr) mkconv(type, fixtype(cpexpr(rhs)) );
1067 /* get length right of character-valued statement functions... */
1071 && (Lq = q->exprblock.vleng)
1072 && (Lq->tag != TCONST
1073 || Ln->constblock.Const.ci != Lq->constblock.Const.ci)) {
1074 q1 = (expptr) mktmp(type, Ln);
1075 putexpr ( mkexpr(OPASSIGN, cpexpr(q1), q));
1079 /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */
1083 q = mkexpr(OPCOMMA, rpllist->rplxp, q);
1084 rp = rpllist->rplnextp;
1085 frexpr(rpllist->rplvp);
1086 free((char *)rpllist);
1095 static int replaced;
1097 /* mkplace -- Figure out the proper storage class for the input name and
1098 return an addrp with the appropriate stuff */
1104 register struct Rplblock *rp;
1107 /* is name on the replace list? */
1109 for(rp = rpllist ; rp ; rp = rp->rplnextp)
1114 if(rp->rpltag == TNAME)
1116 np = (Namep) (rp->rplvp);
1119 else return( (Addrp) cpexpr(rp->rplvp) );
1123 /* is variable a DO index in a register ? */
1125 if(np->vdovar && ( (regn = inregister(np)) >= 0) )
1126 if(np->vtype == TYERROR)
1127 return((Addrp) errnode() );
1130 s = ALLOC(Addrblock);
1135 s->memoffset = ICON(0);
1136 s -> uname_tag = UNAM_NAME;
1137 s -> user.name = np;
1146 static int doing_vleng;
1148 /* mklhs -- Compute the actual address of the given expression; account
1149 for array subscripts, stack offset, and substring offsets. The f -> C
1150 translator will need this only to worry about the subscript stuff */
1153 register struct Primblock *p;
1160 return( (expptr) p );
1165 if(s->tag!=TADDR || s->vstg==STGREG)
1167 free( (charptr) p );
1168 return( (expptr) s );
1171 /* compute the address modified by subscripts */
1174 s->memoffset = mkexpr(OPPLUS, s->memoffset, suboffset(p) );
1175 frexpr((expptr)p->argsp);
1178 /* now do substring part */
1180 if(p->fcharp || p->lcharp)
1182 if(np->vtype != TYCHAR)
1183 errstr("substring of noncharacter %s", np->fvarname);
1185 if(p->lcharp == NULL)
1186 p->lcharp = (expptr) cpexpr(s->vleng);
1189 s->vleng = fixtype(mkexpr(OPMINUS,
1191 mkexpr(OPMINUS, p->fcharp, ICON(1) )));
1196 s->vleng = p->lcharp;
1201 s->vleng = fixtype( s->vleng );
1202 s->memoffset = fixtype( s->memoffset );
1203 free( (charptr) p );
1204 return( (expptr) s );
1211 /* deregister -- remove a register allocation from the list; assumes that
1212 names are deregistered in stack order (LIFO order - Last In First Out) */
1217 if(nregvar>0 && regnamep[nregvar-1]==np)
1226 /* memversion -- moves a DO index REGISTER into a memory location; other
1227 objects are passed through untouched */
1229 Addrp memversion(np)
1234 if(np->vdovar==NO || (inregister(np)<0) )
1244 /* inregister -- looks for the input name in the global list regnamep */
1251 for(i = 0 ; i < nregvar ; ++i)
1252 if(regnamep[i] == np)
1253 return( regnum[i] );
1259 /* suboffset -- Compute the offset from the start of the array, given the
1260 subscripts as arguments */
1263 register struct Primblock *p;
1268 expptr e, e1, offp, prod;
1270 struct Dimblock *dimp;
1271 expptr sub[MAXDIM+1];
1278 for(cp = p->argsp->listp ; cp ; cp = cp->nextp)
1280 si = fixtype(cpexpr((tagptr)cp->datap));
1281 if (!ISINT(si->headblock.vtype)) {
1282 NOEXT("non-integer subscript");
1283 si = mkconv(TYLONG, si);
1288 erri("more than %d subscripts", maxdim);
1294 if(n>0 && dimp==NULL)
1295 errstr("subscripts on scalar variable %.68s", np->fvarname);
1296 else if(dimp && dimp->ndim!=n)
1297 errstr("wrong number of subscripts on %.68s", np->fvarname);
1302 prod = mkexpr(OPPLUS, sub[n],
1303 mkexpr(OPSTAR, prod, cpexpr(dimp->dims[n].dimsize)) );
1304 if(checksubs || np->vstg!=STGARG)
1305 prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
1307 /* Add in the run-time bounds check */
1310 prod = subcheck(np, prod);
1311 size = np->vtype == TYCHAR ?
1312 (expptr) cpexpr(np->vleng) : ICON(typesize[np->vtype]);
1313 prod = mkexpr(OPSTAR, prod, size);
1314 offp = mkexpr(OPPLUS, offp, prod);
1317 /* Check for substring indicator */
1319 if(p->fcharp && np->vtype==TYCHAR) {
1321 e1 = mkexpr(OPMINUS, cpexpr(e), ICON(1));
1322 if (!ISCONST(e) && (e->tag != TPRIM || e->primblock.argsp)) {
1323 e = (expptr)mktmp(TYLONG, ENULL);
1324 putout(putassign(cpexpr(e), e1));
1325 p->fcharp = mkexpr(OPPLUS, cpexpr(e), ICON(1));
1328 offp = mkexpr(OPPLUS, offp, e1);
1336 expptr subcheck(np, p)
1340 struct Dimblock *dimp;
1341 expptr t, checkvar, checkcond, badcall;
1344 if(dimp->nelt == NULL)
1345 return(p); /* don't check arrays with * bounds */
1350 /* check for negative (constant) offset */
1352 if(p->constblock.Const.ci < 0)
1354 if( ISICON(dimp->nelt) )
1356 /* see if constant offset exceeds the array declaration */
1358 if(p->constblock.Const.ci < dimp->nelt->constblock.Const.ci)
1364 /* We know that the subscript offset p or dimp -> nelt is not a constant.
1365 Now find a register to use for run-time bounds checking */
1367 if(p->tag==TADDR && p->addrblock.vstg==STGREG)
1369 checkvar = (expptr) cpexpr(p);
1373 checkvar = (expptr) mktmp(p->headblock.vtype, ENULL);
1374 t = mkexpr(OPASSIGN, cpexpr(checkvar), p);
1376 checkcond = mkexpr(OPLT, t, cpexpr(dimp->nelt) );
1378 checkcond = mkexpr(OPAND, checkcond,
1379 mkexpr(OPLE, ICON(0), cpexpr(checkvar)) );
1381 /* Construct the actual test */
1383 badcall = call4(p->headblock.vtype, "s_rnge",
1384 mkstrcon(strlen(np->fvarname), np->fvarname),
1385 mkconv(TYLONG, cpexpr(checkvar)),
1386 mkstrcon(strlen(procname), procname),
1388 badcall->exprblock.opcode = OPCCALL;
1389 p = mkexpr(OPQUEST, checkcond,
1390 mkexpr(OPCOLON, checkvar, badcall));
1396 errstr("subscript on variable %s out of range", np->fvarname);
1414 if(p->vclass == CLPROC && p->vprocclass == PTHISPROC)
1415 return (Addrp) cpexpr((expptr)xretslot[p->vtype]);
1419 if(p->vclass != CLPROC)
1421 extp = mkext(p->fvarname, addunder(p->cvarname));
1422 extp->extstg = STGEXT;
1424 p->vardesc.varno = extp - extsymtab;
1425 p->vprocclass = PEXTERNAL;
1426 if ((extp->exproto || infertypes)
1427 && (p->vtype == TYUNKNOWN || p->vimpltype)
1428 && (k = extp->extype))
1440 t = ALLOC(Addrblock);
1443 t->vclass = p->vclass;
1444 t->vtype = p->vtype;
1446 t->memno = p->vardesc.varno;
1447 t->memoffset = ICON(p->voffset);
1452 t->vleng = (expptr) cpexpr(p->vleng);
1453 if( ISICON(t->vleng) )
1454 t->varleng = t->vleng->constblock.Const.ci;
1457 /* Keep the original name around for the C code generation */
1459 t -> uname_tag = UNAM_NAME;
1465 return ( intraddr (p));
1467 badstg("mkaddr", p->vstg);
1468 /* NOT REACHED */ return 0;
1474 /* mkarg -- create storage for a new parameter. This is called when a
1475 function returns a string (for the return value, which is the first
1476 parameter), or when a variable-length string is passed to a function. */
1478 Addrp mkarg(type, argno)
1483 p = ALLOC(Addrblock);
1488 /* TYLENG is the type of the field holding the length of a character string */
1490 p->vstg = (type==TYLENG ? STGLENG : STGARG);
1498 /* mkprim -- Create a PRIM (primary/primitive) block consisting of a
1499 Nameblock (or Paramblock), arguments (actual params or array
1500 subscripts) and substring bounds. Requires that v have lots of
1501 extra (uninitialized) storage, since it could be a paramblock or
1504 expptr mkprim(v0, args, substr)
1506 struct Listblock *args;
1510 struct Paramblock paramblock;
1511 struct Nameblock nameblock;
1512 struct Headblock headblock;
1514 register Primu v = (Primu)v0;
1515 register struct Primblock *p;
1517 if(v->headblock.vclass == CLPARAM)
1520 /* v is to be a Paramblock */
1524 errstr("no qualifiers on parameter name %s",
1525 v->paramblock.fvarname);
1526 frexpr((expptr)args);
1529 frexpr((tagptr)substr->datap);
1530 frexpr((tagptr)substr->nextp->datap);
1534 return( errnode() );
1536 return( (expptr) cpexpr(v->paramblock.paramval) );
1539 p = ALLOC(Primblock);
1541 p->vtype = v->nameblock.vtype;
1543 /* v is to be a Nameblock */
1545 p->namep = (Namep) v;
1549 p->fcharp = (expptr) substr->datap;
1550 p->lcharp = (expptr) substr->nextp->datap;
1553 return( (expptr) p);
1558 /* vardcl -- attempt to fill out the Name template for variable v.
1559 This function is called on identifiers known to be variables or
1560 recursive references to the same function */
1567 extern int doing_stmtfcn;
1569 if(v->vclass == CLUNKNOWN) {
1572 v->vtype = TYUNKNOWN;
1581 if(v->vclass == CLNAMELIST)
1584 if(v->vtype == TYUNKNOWN)
1586 else if(v->vclass!=CLVAR && v->vprocclass!=PTHISPROC)
1588 dclerr("used as variable", v);
1591 if(v->vstg==STGUNKNOWN) {
1592 if (doing_stmtfcn) {
1593 /* neither declare this variable if its only use */
1594 /* is in defining a stmt function, nor complain */
1595 /* that it is never used */
1599 v->vstg = implstg[ letter(v->fvarname[0]) ];
1603 /* Compute the actual storage location, i.e. offsets from base addresses,
1604 possibly the stack pointer */
1609 v->vardesc.varno = ++lastvarno;
1612 if(v->vclass==CLPROC && v->vprocclass==PTHISPROC)
1615 if( (neltp = t->nelt) && ISCONST(neltp) ) ;
1617 dclerr("adjustable automatic array", v);
1628 /* Set the implicit type declaration of parameter p based on its first
1638 if(p->vdcldone || (p->vclass==CLPROC && p->vprocclass==PINTRINSIC) )
1640 if(p->vtype == TYUNKNOWN)
1642 k = letter(p->fvarname[0]);
1643 type = impltype[ k ];
1644 leng = implleng[ k ];
1645 if(type == TYUNKNOWN)
1647 if(p->vclass == CLPROC)
1649 dclerr("attempt to use undefined variable", p);
1653 settype(p, type, leng);
1663 int k = impltype[letter(np->fvarname[0])];
1675 #define ICONEQ(z, c) (ISICON(z) && z->constblock.Const.ci==c)
1676 #define COMMUTE { e = lp; lp = rp; rp = e; }
1680 /* mkexpr -- Make expression, and simplify constant subcomponents (tree
1681 order is not preserved). Assumes that lp is nonempty, and uses
1682 fold() to simplify adjacent constants */
1684 expptr mkexpr(opcode, lp, rp)
1686 register expptr lp, rp;
1688 register expptr e, e1;
1694 ltype = lp->headblock.vtype;
1696 if(rp && opcode!=OPCALL && opcode!=OPCCALL)
1698 rtype = rp->headblock.vtype;
1703 etype = cktype(opcode, ltype, rtype);
1704 if(etype == TYERROR)
1709 /* check for multiplication by 0 and 1 and addition to 0 */
1717 if(rp->constblock.Const.ci == 0)
1727 err("attempted division by zero");
1734 /* Handle multiplying or dividing by 1, -1 */
1739 if(rp->constblock.Const.ci == 1)
1742 if(rp->constblock.Const.ci == -1)
1745 return( mkexpr(OPNEG, lp, ENULL) );
1749 /* Group all constants together. In particular,
1751 (x * CONST1) * CONST2 ==> x * (CONST1 * CONST2)
1752 (x * CONST1) / CONST2 ==> x * (CONST1 / CONST2)
1755 if (lp->tag != TEXPR || !lp->exprblock.rightp
1756 || !ISICON(lp->exprblock.rightp))
1759 if (lp->exprblock.opcode == OPLSHIFT) {
1760 L = 1 << lp->exprblock.rightp->constblock.Const.ci;
1761 if (opcode == OPSTAR || ISICON(rp) &&
1762 !(L % rp->constblock.Const.ci)) {
1763 lp->exprblock.opcode = OPSTAR;
1764 lp->exprblock.rightp->constblock.Const.ci = L;
1768 if (lp->exprblock.opcode == OPSTAR) {
1769 if(opcode == OPSTAR)
1770 e = mkexpr(OPSTAR, lp->exprblock.rightp, rp);
1771 else if(ISICON(rp) &&
1772 (lp->exprblock.rightp->constblock.Const.ci %
1773 rp->constblock.Const.ci) == 0)
1774 e = mkexpr(OPSLASH, lp->exprblock.rightp, rp);
1777 e1 = lp->exprblock.leftp;
1778 free( (charptr) lp );
1779 return( mkexpr(OPSTAR, e1, e) );
1793 return( mkexpr(OPNEG, rp, ENULL) );
1796 if( ISCONST(rp) && is_negatable((Constp)rp))
1799 consnegop((Constp)rp);
1802 /* Group constants in an addition expression (also subtraction, since the
1803 subtracted value was negated above). In particular,
1805 (x + CONST1) + CONST2 ==> x + (CONST1 + CONST2)
1811 if(rp->constblock.Const.ci == 0)
1813 if( ISPLUSOP(lp) && ISICON(lp->exprblock.rightp) )
1815 e = mkexpr(OPPLUS, lp->exprblock.rightp, rp);
1816 e1 = lp->exprblock.leftp;
1817 free( (charptr) lp );
1818 return( mkexpr(OPPLUS, e1, e) );
1821 if (opcode == OPMINUS && (ISINT(etype) || doing_vleng)) {
1822 /* check for (i [+const]) - (i [+const]) */
1823 if (lp->tag == TPRIM)
1825 else if (lp->tag == TEXPR && lp->exprblock.opcode == OPPLUS
1826 && lp->exprblock.rightp->tag == TCONST) {
1827 e = lp->exprblock.leftp;
1828 if (e->tag != TPRIM)
1833 if (e->primblock.argsp)
1835 if (rp->tag == TPRIM)
1837 else if (rp->tag == TEXPR && rp->exprblock.opcode == OPPLUS
1838 && rp->exprblock.rightp->tag == TCONST) {
1839 e1 = rp->exprblock.leftp;
1840 if (e1->tag != TPRIM)
1845 if (e->primblock.namep != e1->primblock.namep
1846 || e1->primblock.argsp)
1848 L = e == lp ? 0 : lp->exprblock.rightp->constblock.Const.ci;
1850 L -= rp->exprblock.rightp->constblock.Const.ci;
1862 /* Eliminate outermost double negations */
1866 if(ltag==TEXPR && lp->exprblock.opcode==OPNEG)
1868 e = lp->exprblock.leftp;
1869 free( (charptr) lp );
1874 /* Eliminate outermost double NOTs */
1877 if(ltag==TEXPR && lp->exprblock.opcode==OPNOT)
1879 e = lp->exprblock.leftp;
1880 free( (charptr) lp );
1888 if(rp!=NULL && rp->listblock.listp==NULL)
1890 free( (charptr) rp );
1902 if(rp->constblock.Const.ci == 0)
1907 else if(opcode == OPOR)
1968 badop("mkexpr", opcode);
1971 e = (expptr) ALLOC(Exprblock);
1972 e->exprblock.tag = TEXPR;
1973 e->exprblock.opcode = opcode;
1974 e->exprblock.vtype = etype;
1975 e->exprblock.leftp = lp;
1976 e->exprblock.rightp = rp;
1977 if(ltag==TCONST && (rp==0 || rtag==TCONST) )
1991 if(rp && opcode!=OPCALL && opcode!=OPCCALL)
1993 return( errnode() );
1996 #define ERR(s) { errs = s; goto error; }
1998 /* cktype -- Check and return the type of the expression */
2001 register int op, lt, rt;
2005 if(lt==TYERROR || rt==TYERROR)
2012 /* If not unary operation, return UNKNOWN */
2014 if(!is_unary_op (op) && op != OPCALL && op != OPCCALL)
2025 if( ISNUMERIC(lt) && ISNUMERIC(rt) )
2026 return( maxtype(lt, rt) );
2027 ERR("nonarithmetic operand of arithmetic operator")
2033 ERR("nonarithmetic operand of negation")
2038 ERR("NOT of nonlogical")
2044 if(lt==TYLOGICAL && rt==TYLOGICAL)
2046 ERR("nonlogical operand of logical operator")
2054 if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
2057 ERR("illegal comparison")
2060 else if( ISCOMPLEX(lt) || ISCOMPLEX(rt) )
2062 if(op!=OPEQ && op!=OPNE)
2063 ERR("order comparison of complex data")
2066 else if( ! ISNUMERIC(lt) || ! ISNUMERIC(rt) )
2067 ERR("comparison of nonarithmetic data")
2071 if(lt==TYCHAR && rt==TYCHAR)
2073 ERR("concatenation of nonchar data")
2087 if(lt==TYCHAR && ISINT(rt) )
2101 if( ISINT(lt) && rt==TYCHAR)
2103 if(lt==TYCHAR || rt==TYCHAR || lt==TYLOGICAL || rt==TYLOGICAL)
2104 if((op!=OPASSIGN && op != OPPLUSEQ && op != OPMINUSEQ)
2107 ERR("impossible conversion")
2131 case OPCOLON: /* Only checks the rightmost type because
2132 of C language definition (rightmost
2133 comma-expr is the value of the expr) */
2141 badop("cktype", op);
2149 /* fold -- simplifies constant expressions; it assumes that e -> leftp and
2150 e -> rightp are TCONST or NULL */
2157 register expptr lp, rp;
2158 int etype, mtype, ltype, rtype, opcode;
2161 struct Constblock lcon, rcon;
2165 opcode = e->exprblock.opcode;
2166 etype = e->exprblock.vtype;
2168 lp = e->exprblock.leftp;
2169 ltype = lp->headblock.vtype;
2170 rp = e->exprblock.rightp;
2176 lp->constblock.Const.ci = ! lp->constblock.Const.ci;
2178 e->exprblock.leftp = 0;
2183 lp->constblock.Const.ci = ~ lp->constblock.Const.ci;
2188 consnegop((Constp)lp);
2200 if ((L = lp->constblock.Const.ci) < 0)
2201 lp->constblock.Const.ci = -L;
2205 if (lp->constblock.vstg) {
2206 s = lp->constblock.Const.cds[0];
2208 lp->constblock.Const.cds[0] = s + 1;
2211 if ((d = lp->constblock.Const.cd[0]) < 0.)
2212 lp->constblock.Const.cd[0] = -d;
2215 return e; /* lazy way out */
2218 badop("fold", opcode);
2221 rtype = rp->headblock.vtype;
2223 p = ALLOC(Constblock);
2226 p->vleng = e->exprblock.vleng;
2237 p->Const.ci = lp->constblock.Const.ci &&
2238 rp->constblock.Const.ci;
2242 p->Const.ci = lp->constblock.Const.ci ||
2243 rp->constblock.Const.ci;
2247 p->Const.ci = lp->constblock.Const.ci ==
2248 rp->constblock.Const.ci;
2252 p->Const.ci = lp->constblock.Const.ci !=
2253 rp->constblock.Const.ci;
2257 p->Const.ci = lp->constblock.Const.ci &
2258 rp->constblock.Const.ci;
2262 p->Const.ci = lp->constblock.Const.ci |
2263 rp->constblock.Const.ci;
2267 p->Const.ci = lp->constblock.Const.ci ^
2268 rp->constblock.Const.ci;
2272 p->Const.ci = lp->constblock.Const.ci <<
2273 rp->constblock.Const.ci;
2277 p->Const.ci = lp->constblock.Const.ci >>
2278 rp->constblock.Const.ci;
2282 ll = lp->constblock.vleng->constblock.Const.ci;
2283 lr = rp->constblock.vleng->constblock.Const.ci;
2284 bl = lp->constblock.Const.ccp1.blanks;
2285 p->Const.ccp = q = (char *) ckalloc(ll+lr+bl);
2286 p->Const.ccp1.blanks = rp->constblock.Const.ccp1.blanks;
2287 p->vleng = ICON(ll+lr+bl);
2288 s = lp->constblock.Const.ccp;
2289 for(i = 0 ; i < ll ; ++i)
2291 for(i = 0 ; i < bl ; i++)
2293 s = rp->constblock.Const.ccp;
2294 for(i = 0; i < lr; ++i)
2300 if( ! ISINT(rtype) )
2302 conspower(p, (Constp)lp, rp->constblock.Const.ci);
2309 lcon.Const.ci = cmpstr(lp->constblock.Const.ccp,
2310 rp->constblock.Const.ccp,
2311 lp->constblock.vleng->constblock.Const.ci,
2312 rp->constblock.vleng->constblock.Const.ci);
2317 mtype = maxtype(ltype, rtype);
2318 consconv(mtype, &lcon, &lp->constblock);
2319 consconv(mtype, &rcon, &rp->constblock);
2321 consbinop(opcode, mtype, p, &lcon, &rcon);
2326 return( (expptr) p );
2331 /* assign constant l = r , doing coercion */
2333 consconv(lt, lc, rc)
2335 register Constp lc, rc;
2338 register union Constant *lv = &lc->Const, *rv = &rc->Const;
2341 if (ONEOF(lt, MSKREAL|MSKCOMPLEX) && ONEOF(rt, MSKREAL|MSKCOMPLEX)) {
2342 memcpy((char *)lv, (char *)rv, sizeof(union Constant));
2343 lc->vstg = rc->vstg;
2344 if (ISCOMPLEX(lt) && ISREAL(rt)) {
2346 lv->cds[1] = cds("0",CNULL);
2357 /* Casting to character means just copying the first sizeof (character)
2358 bytes into a new 1 character string. This is weird. */
2361 *(lv->ccp = (char *) ckalloc(1)) = rv->ci;
2362 lv->ccp1.blanks = 0;
2368 lv->ci = rv->ccp[0];
2369 else if( ISINT(rt) )
2371 else lv->ci = rc->vstg ? atof(rv->cds[0]) : rv->cd[0];
2394 /* Negate constant value -- changes the input node's value */
2402 if (ISCOMPLEX(p->vtype)) {
2403 s = p->Const.cds[1];
2404 p->Const.cds[1] = *s == '-' ? s+1
2405 : *s == '0' ? s : s-1;
2407 s = p->Const.cds[0];
2408 p->Const.cds[0] = *s == '-' ? s+1
2409 : *s == '0' ? s : s-1;
2416 p->Const.ci = - p->Const.ci;
2421 p->Const.cd[1] = - p->Const.cd[1];
2422 /* fall through and do the real parts */
2425 p->Const.cd[0] = - p->Const.cd[0];
2428 badtype("consnegop", p->vtype);
2434 /* conspower -- Expand out an exponentiation */
2441 register union Constant *powp = &p->Const;
2443 struct Constblock x, x0;
2446 memcpy((char *)powp, (char *)&ap->Const, sizeof(ap->Const));
2450 switch(type = ap->vtype) /* pow = 1 */
2464 badtype("conspower", type);
2469 switch(type) /* x0 = ap */
2473 x0.Const.ci = ap->Const.ci;
2478 ap->vstg ? atof(ap->Const.cds[1]) : ap->Const.cd[1];
2482 ap->vstg ? atof(ap->Const.cds[0]) : ap->Const.cd[0];
2491 err("integer ** negative number");
2494 else if (!x0.Const.cd[0]
2495 && (!ISCOMPLEX(type) || !x0.Const.cd[1])) {
2496 err("0.0 ** negative number");
2500 consbinop(OPSLASH, type, &x, p, &x0);
2503 consbinop(OPSTAR, type, &x, p, &x0);
2508 consbinop(OPSTAR, type, p, p, &x);
2510 consbinop(OPSTAR, type, &x, &x, &x);
2518 /* do constant operation cp = a op b -- assumes that ap and bp have data
2519 matching the input type */
2523 consbinop(opcode, type, cpp, app, bpp)
2525 Constp cpp, app, bpp;
2527 register union Constant *ap = &app->Const,
2531 double ad[2], bd[2], temp;
2535 if (ONEOF(type, MSKREAL|MSKCOMPLEX)) {
2536 ad[0] = app->vstg ? atof(ap->cds[0]) : ap->cd[0];
2537 bd[0] = bpp->vstg ? atof(bp->cds[0]) : bp->cd[0];
2538 if (ISCOMPLEX(type)) {
2539 ad[1] = app->vstg ? atof(ap->cds[1]) : ap->cd[1];
2540 bd[1] = bpp->vstg ? atof(bp->cds[1]) : bp->cd[1];
2550 cp->ci = ap->ci + bp->ci;
2554 cp->cd[1] = ad[1] + bd[1];
2557 cp->cd[0] = ad[0] + bd[0];
2567 cp->ci = ap->ci - bp->ci;
2571 cp->cd[1] = ad[1] - bd[1];
2574 cp->cd[0] = ad[0] - bd[0];
2584 cp->ci = ap->ci * bp->ci;
2588 cp->cd[0] = ad[0] * bd[0];
2592 temp = ad[0] * bd[0] - ad[1] * bd[1] ;
2593 cp->cd[1] = ad[0] * bd[1] + ad[1] * bd[0] ;
2603 cp->ci = ap->ci / bp->ci;
2607 cp->cd[0] = ad[0] / bd[0];
2611 zdiv((dcomplex*)cp, (dcomplex*)ad, (dcomplex*)bd);
2619 cp->ci = ap->ci % bp->ci;
2623 Fatal("inline mod of noninteger");
2631 cp->ci = ap->ci <= bp->ci ? ap->ci : bp->ci;
2635 cp->cd[0] = ad[0] <= bd[0] ? ad[0] : bd[0];
2638 Fatal("inline min of exected type");
2648 cp->ci = ap->ci >= bp->ci ? ap->ci : bp->ci;
2652 cp->cd[0] = ad[0] >= bd[0] ? ad[0] : bd[0];
2655 Fatal("inline max of exected type");
2659 default: /* relational ops */
2666 else if(ap->ci == bp->ci)
2674 else if(ad[0] == bd[0])
2680 if(ad[0] == bd[0] &&
2714 /* conssgn - returns the sign of a Fortran constant */
2722 Fatal( "sgn(nonconstant)" );
2724 switch(p->headblock.vtype)
2728 if(p->constblock.Const.ci > 0) return(1);
2729 if(p->constblock.Const.ci < 0) return(-1);
2734 if (p->constblock.vstg) {
2735 s = p->constblock.Const.cds[0];
2742 if(p->constblock.Const.cd[0] > 0) return(1);
2743 if(p->constblock.Const.cd[0] < 0) return(-1);
2747 /* The sign of a complex number is 0 iff the number is 0 + 0i, else it's 1 */
2751 if (p->constblock.vstg)
2752 return *p->constblock.Const.cds[0] != '0'
2753 && *p->constblock.Const.cds[1] != '0';
2754 return(p->constblock.Const.cd[0]!=0 || p->constblock.Const.cd[1]!=0);
2757 badtype( "conssgn", p->constblock.vtype);
2759 /* NOT REACHED */ return 0;
2763 "pow_ii", "pow_ri", "pow_di", "pow_ci", "pow_zi" };
2765 LOCAL expptr mkpower(p)
2768 register expptr q, lp, rp;
2769 int ltype, rtype, mtype, tyi;
2771 lp = p->exprblock.leftp;
2772 rp = p->exprblock.rightp;
2773 ltype = lp->headblock.vtype;
2774 rtype = rp->headblock.vtype;
2778 if(rp->constblock.Const.ci == 0)
2783 else if (ISREAL (ltype))
2784 return mkconv (ltype, ICON (1));
2786 return( (expptr) putconst((Constp)
2787 mkconv(ltype, ICON(1))) );
2789 if(rp->constblock.Const.ci < 0)
2794 err("integer**negative");
2795 return( errnode() );
2797 rp->constblock.Const.ci = - rp->constblock.Const.ci;
2798 p->exprblock.leftp = lp
2799 = fixexpr((Exprp)mkexpr(OPSLASH, ICON(1), lp));
2801 if(rp->constblock.Const.ci == 1)
2804 free( (charptr) p );
2808 if( ONEOF(ltype, MSKINT|MSKREAL) && !doin_setbound) {
2809 p->exprblock.vtype = ltype;
2815 if(ltype==TYSHORT && rtype==TYSHORT && (!ISCONST(lp) || tyint==TYSHORT) )
2816 q = call2(TYSHORT, "pow_hh", lp, rp);
2818 if(ltype == TYSHORT)
2821 lp = mkconv(TYLONG,lp);
2823 rp = mkconv(TYLONG,rp);
2827 rp = (expptr)putconst((Constp)rp);
2830 q = call2(ltype, powint[ltype-TYLONG], lp, rp);
2833 else if( ISREAL( (mtype = maxtype(ltype,rtype)) )) {
2834 extern int callk_kludge;
2835 callk_kludge = TYDREAL;
2836 q = call2(mtype, "pow_dd", mkconv(TYDREAL,lp), mkconv(TYDREAL,rp));
2840 q = call2(TYDCOMPLEX, "pow_zz",
2841 mkconv(TYDCOMPLEX,lp), mkconv(TYDCOMPLEX,rp));
2842 if(mtype == TYCOMPLEX)
2843 q = mkconv(TYCOMPLEX, q);
2845 free( (charptr) p );
2850 /* Complex Division. Same code as in Runtime Library
2856 register dcomplex *a, *b, *c;
2861 if( (abr = b->dreal) < 0.)
2863 if( (abi = b->dimag) < 0.)
2868 Fatal("complex division by zero");
2869 ratio = b->dreal / b->dimag ;
2870 den = b->dimag * (1 + ratio*ratio);
2871 c->dreal = (a->dreal*ratio + a->dimag) / den;
2872 c->dimag = (a->dimag*ratio - a->dreal) / den;
2877 ratio = b->dimag / b->dreal ;
2878 den = b->dreal * (1 + ratio*ratio);
2879 c->dreal = (a->dreal + a->dimag*ratio) / den;
2880 c->dimag = (a->dimag - a->dreal*ratio) / den;