1 /* $Id: expr.c,v 1.20 2008/05/11 15:28:03 ragge Exp $ */
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * Redistributions of source code and documentation must retain the above
10 * copyright notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditionsand the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed or owned by Caldera
18 * Neither the name of Caldera International, Inc. nor the names of other
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
40 /* little routines to create constant blocks */
41 LOCAL
int letter(int c
);
42 LOCAL
void conspower(union constant
*, struct bigblock
*, ftnint
);
43 LOCAL
void consbinop(int, int, union constant
*, union constant
*,
45 LOCAL
void zdiv(struct dcomplex
*, struct dcomplex
*, struct dcomplex
*);
46 LOCAL
struct bigblock
*stfcall(struct bigblock
*, struct bigblock
*);
47 LOCAL bigptr
mkpower(struct bigblock
*p
);
48 LOCAL bigptr
fold(struct bigblock
*e
);
49 LOCAL bigptr
subcheck(struct bigblock
*, bigptr
);
51 struct bigblock
*mkconst(t
)
54 register struct bigblock
*p
;
63 struct bigblock
*mklogcon(l
)
66 register struct bigblock
* p
;
68 p
= mkconst(TYLOGICAL
);
69 p
->b_const
.fconst
.ci
= l
;
75 struct bigblock
*mkintcon(l
)
78 register struct bigblock
*p
;
81 p
->b_const
.fconst
.ci
= l
;
83 if(l
>= -MAXSHORT
&& l
<= MAXSHORT
)
91 struct bigblock
*mkaddcon(l
)
94 register struct bigblock
*p
;
97 p
->b_const
.fconst
.ci
= l
;
103 struct bigblock
*mkrealcon(t
, d
)
107 register struct bigblock
*p
;
110 p
->b_const
.fconst
.cd
[0] = d
;
115 struct bigblock
*mkbitcon(shift
, leng
, s
)
120 register struct bigblock
*p
;
122 p
= mkconst(TYUNKNOWN
);
123 p
->b_const
.fconst
.ci
= 0;
126 p
->b_const
.fconst
.ci
= (p
->b_const
.fconst
.ci
<< shift
) | hextoi(*s
++);
134 struct bigblock
*mkstrcon(l
,v
)
138 register struct bigblock
*p
;
142 p
->vleng
= MKICON(l
);
143 p
->b_const
.fconst
.ccp
= s
= (char *) ckalloc(l
);
150 struct bigblock
*mkcxcon(realp
,imagp
)
151 register bigptr realp
, imagp
;
154 register struct bigblock
*p
;
156 rtype
= realp
->vtype
;
157 itype
= imagp
->vtype
;
159 if( ISCONST(realp
) && ISNUMERIC(rtype
) && ISCONST(imagp
) && ISNUMERIC(itype
) )
161 p
= mkconst( (rtype
==TYDREAL
||itype
==TYDREAL
) ? TYDCOMPLEX
: TYCOMPLEX
);
163 p
->b_const
.fconst
.cd
[0] = realp
->b_const
.fconst
.ci
;
164 else p
->b_const
.fconst
.cd
[0] = realp
->b_const
.fconst
.cd
[0];
166 p
->b_const
.fconst
.cd
[1] = imagp
->b_const
.fconst
.ci
;
167 else p
->b_const
.fconst
.cd
[1] = imagp
->b_const
.fconst
.cd
[0];
171 err("invalid complex constant");
181 struct bigblock
*errnode()
200 if(t
==TYUNKNOWN
|| t
==TYERROR
)
201 fatal1("mkconv of impossible type %d", t
);
205 else if( ISCONST(p
) && p
->vtype
!=TYADDR
)
208 consconv(t
, &(q
->b_const
.fconst
), p
->vtype
, &(p
->b_const
.fconst
));
213 q
= mkexpr(OPCONV
, p
, 0);
221 struct bigblock
*addrof(p
)
224 return( mkexpr(OPADDR
, p
, NULL
) );
235 register chainp ep
, pp
;
238 static int blksize
[ ] = { 0, sizeof(struct nameblock
), sizeof(struct constblock
),
239 sizeof(struct exprblock
), sizeof(struct addrblock
),
240 sizeof(struct primblock
), sizeof(struct listblock
),
241 sizeof(struct errorblock
)
248 if( (tag
= p
->tag
) == TNAME
)
252 e
= cpblock( blksize
[p
->tag
] , p
);
254 e
= cpblock( sizeof(struct bigblock
) , p
);
260 if(e
->vtype
== TYCHAR
)
262 e
->b_const
.fconst
.ccp
= copyn(1+strlen(e
->b_const
.fconst
.ccp
), e
->b_const
.fconst
.ccp
);
263 e
->vleng
= cpexpr(e
->vleng
);
269 e
->b_expr
.leftp
= cpexpr(p
->b_expr
.leftp
);
270 e
->b_expr
.rightp
= cpexpr(p
->b_expr
.rightp
);
274 if((pp
= p
->b_list
.listp
))
276 ep
= e
->b_list
.listp
= mkchain( cpexpr(pp
->chain
.datap
), NULL
);
277 for(pp
= pp
->chain
.nextp
; pp
; pp
= pp
->chain
.nextp
)
278 ep
= ep
->chain
.nextp
= mkchain( cpexpr(pp
->chain
.datap
), NULL
);
283 e
->vleng
= cpexpr(e
->vleng
);
284 e
->b_addr
.memoffset
= cpexpr(e
->b_addr
.memoffset
);
285 e
->b_addr
.istemp
= NO
;
289 e
->b_prim
.argsp
= cpexpr(e
->b_prim
.argsp
);
290 e
->b_prim
.fcharp
= cpexpr(e
->b_prim
.fcharp
);
291 e
->b_prim
.lcharp
= cpexpr(e
->b_prim
.lcharp
);
295 fatal1("cpexpr: impossible tag %d", tag
);
315 ckfree(p
->b_const
.fconst
.ccp
);
327 frexpr(p
->b_addr
.memoffset
);
337 frexpr(p
->b_prim
.argsp
);
338 frexpr(p
->b_prim
.fcharp
);
339 frexpr(p
->b_prim
.lcharp
);
343 frexpr(p
->b_expr
.leftp
);
345 frexpr(p
->b_expr
.rightp
);
349 for(q
= p
->b_list
.listp
; q
; q
= q
->chain
.nextp
)
350 frexpr(q
->chain
.datap
);
351 frchain( &(p
->b_list
.listp
) );
355 fatal1("frexpr: impossible tag %d", p
->tag
);
361 /* fix up types in expression; replace subtrees and convert
362 names to address blocks */
374 if( ! ONEOF(p
->vtype
, MSKINT
|MSKLOGICAL
|MSKADDR
) )
379 p
->b_addr
.memoffset
= fixtype(p
->b_addr
.memoffset
);
386 fatal1("fixtype: impossible tag %d", p
->tag
);
389 return( fixexpr(p
) );
395 if(p
->b_prim
.argsp
&& p
->b_prim
.namep
->vclass
!=CLVAR
)
396 return( mkfunct(p
) );
397 else return( mklhs(p
) );
405 /* special case tree transformations and cleanups of expression trees */
408 register struct bigblock
*p
;
413 int opcode
, ltype
, rtype
, ptype
, mtype
;
417 else if(p
->tag
!= TEXPR
)
418 fatal1("fixexpr: invalid tag %d", p
->tag
);
419 opcode
= p
->b_expr
.opcode
;
420 lp
= p
->b_expr
.leftp
= fixtype(p
->b_expr
.leftp
);
422 if(opcode
==OPASSIGN
&& lp
->tag
!=TADDR
)
424 err("left side of assignment must be variable");
431 rp
= p
->b_expr
.rightp
= fixtype(p
->b_expr
.rightp
);
440 /* force folding if possible */
441 if( ISCONST(lp
) && (rp
==NULL
|| ISCONST(rp
)) )
443 q
= mkexpr(opcode
, lp
, rp
);
446 ckfree(q
); /* constants did not fold */
449 if( (ptype
= cktype(opcode
, ltype
, rtype
)) == TYERROR
)
459 p
->vleng
= mkexpr(OPPLUS
, cpexpr(lp
->vleng
),
466 if( ! ISCONST(rp
) && ISREAL(ltype
) && ISREAL(rtype
) )
468 if( ISCOMPLEX(ltype
) || ISCOMPLEX(rtype
) )
470 if( ONEOF(ltype
, MSKADDR
|MSKINT
) && ONEOF(rtype
, MSKADDR
|MSKINT
)
471 && typesize
[ltype
]>=typesize
[rtype
] )
473 p
->b_expr
.rightp
= fixtype( mkconv(ptype
, rp
) );
477 if( ISCOMPLEX(rtype
) )
479 p
= call2(ptype
, ptype
==TYCOMPLEX
? "c_div" : "z_div",
480 mkconv(ptype
, lp
), mkconv(ptype
, rp
) );
487 if(ptype
==TYDREAL
&& ( (ltype
==TYREAL
&& ! ISCONST(lp
) ) ||
488 (rtype
==TYREAL
&& ! ISCONST(rp
) ) ))
490 if( ISCOMPLEX(ptype
) )
493 p
->b_expr
.leftp
= fixtype(mkconv(ptype
,lp
));
495 p
->b_expr
.rightp
= fixtype(mkconv(ptype
,rp
));
499 return( mkpower(p
) );
509 mtype
= cktype(OPMINUS
, ltype
, rtype
);
510 if(mtype
==TYDREAL
&& ( (ltype
==TYREAL
&& ! ISCONST(lp
)) ||
511 (rtype
==TYREAL
&& ! ISCONST(rp
)) ))
513 if( ISCOMPLEX(mtype
) )
516 p
->b_expr
.leftp
= fixtype(mkconv(mtype
,lp
));
518 p
->b_expr
.rightp
= fixtype(mkconv(mtype
,rp
));
523 ptype
= cktype(OPCONV
, p
->vtype
, ltype
);
524 if(lp
->tag
==TEXPR
&& lp
->b_expr
.opcode
==OPCOMMA
)
526 lp
->b_expr
.rightp
= fixtype( mkconv(ptype
, lp
->b_expr
.rightp
) );
533 if(lp
->tag
==TEXPR
&& lp
->b_expr
.opcode
==OPADDR
)
534 fatal("addr of addr");
555 for efficient subscripting, replace long ints by shorts
564 if(p
->vtype
!= TYLONG
)
575 return( mkconv(TYINT
,p
) );
581 fatal1("shorten: invalid tag %d", p
->tag
);
589 q
= shorten( cpexpr(p
->rightp
) );
590 if(q
->vtype
== TYINT
)
592 p
->leftp
= shorten(p
->leftp
);
593 if(p
->leftp
->vtype
== TYLONG
)
605 p
->leftp
= shorten(p
->leftp
);
606 if(p
->leftp
->vtype
== TYINT
)
628 register bigptr q
, t
;
634 for(p
= p0
->b_list
.listp
; p
; p
= p
->chain
.nextp
)
641 if(q
->vtype
== TYSHORT
)
642 q
= mkconv(tyint
, q
);
644 p
->chain
.datap
= putconst(q
);
648 else if(qtag
==TPRIM
&& q
->b_prim
.argsp
==0 && q
->b_prim
.namep
->vclass
==CLPROC
)
649 p
->chain
.datap
= mkaddr(q
->b_prim
.namep
);
650 else if(qtag
==TPRIM
&& q
->b_prim
.argsp
==0 && q
->b_prim
.namep
->b_name
.vdim
!=NULL
)
651 p
->chain
.datap
= mkscalar(q
->b_prim
.namep
);
652 else if(qtag
==TPRIM
&& q
->b_prim
.argsp
==0 && q
->b_prim
.namep
->b_name
.vdovar
&&
653 (t
= memversion(q
->b_prim
.namep
)) )
654 p
->chain
.datap
= fixtype(t
);
655 else p
->chain
.datap
= fixtype(q
);
662 register struct bigblock
*np
;
664 register struct bigblock
*ap
;
670 /* on the VAX, prolog causes array arguments
671 to point at the (0,...,0) element, except when
672 subscript checking is on
674 if( !checksubs
&& np
->vstg
==STGARG
)
676 register struct dimblock
*dp
;
678 frexpr(ap
->memoffset
);
679 ap
->memoffset
= mkexpr(OPSTAR
, MKICON(typesize
[np
->vtype
]),
680 cpexpr(dp
->baseoffset
) );
691 register struct bigblock
* p
;
696 register struct bigblock
*np
;
697 register struct bigblock
*q
;
701 np
= p
->b_prim
.namep
;
704 if(class == CLUNKNOWN
)
706 np
->vclass
= class = CLPROC
;
707 if(np
->vstg
== STGUNKNOWN
)
709 if((k
= intrfunct(np
->b_name
.varname
)))
712 np
->b_name
.vardesc
.varno
= k
;
713 np
->b_name
.vprocclass
= PINTRINSIC
;
717 extp
= mkext( varunder(VL
,np
->b_name
.varname
) );
718 extp
->extstg
= STGEXT
;
720 np
->b_name
.vardesc
.varno
= extp
- extsymtab
;
721 np
->b_name
.vprocclass
= PEXTERNAL
;
724 else if(np
->vstg
==STGARG
)
726 if(np
->vtype
!=TYCHAR
&& !ftn66flag
)
727 warn("Dummy procedure not declared EXTERNAL. Code may be wrong.");
728 np
->b_name
.vprocclass
= PEXTERNAL
;
733 fatal1("invalid class code for function", class);
734 if(p
->b_prim
.fcharp
|| p
->b_prim
.lcharp
)
736 err("no substring of function call");
740 nargs
= fixargs( np
->b_name
.vprocclass
!=PINTRINSIC
, p
->b_prim
.argsp
);
742 switch(np
->b_name
.vprocclass
)
747 q
= mkexpr(OPCALL
, ap
, p
->b_prim
.argsp
);
748 q
->vtype
= np
->vtype
;
750 q
->vleng
= cpexpr(np
->vleng
);
754 q
= intrcall(np
, p
->b_prim
.argsp
, nargs
);
758 q
= stfcall(np
, p
->b_prim
.argsp
);
762 warn("recursive call");
763 for(ep
= entries
; ep
; ep
= ep
->entrypoint
.nextp
)
764 if(ep
->entrypoint
.enamep
== np
)
767 fatal("mkfunct: impossible recursion");
768 ap
= builtin(np
->vtype
, varstr(XL
, ep
->entrypoint
.entryname
->extname
) );
772 fatal1("mkfunct: impossible vprocclass %d", np
->b_name
.vprocclass
);
785 LOCAL
struct bigblock
*
786 stfcall(struct bigblock
*np
, struct bigblock
*actlist
)
788 register chainp actuals
;
790 chainp oactp
, formals
;
792 struct bigblock
*q
, *rhs
;
798 actuals
= actlist
->b_list
.listp
;
808 formals
= (chainp
)np
->b_name
.vardesc
.vstfdesc
->chain
.datap
;
809 rhs
= (bigptr
)np
->b_name
.vardesc
.vstfdesc
->chain
.nextp
;
811 /* copy actual arguments into temporaries */
812 while(actuals
!=NULL
&& formals
!=NULL
) {
813 rp
= ALLOC(rplblock
);
814 rp
->rplblock
.rplnp
= q
= formals
->chain
.datap
;
815 ap
= fixtype(actuals
->chain
.datap
);
816 if(q
->vtype
==ap
->vtype
&& q
->vtype
!=TYCHAR
817 && (ap
->tag
==TCONST
|| ap
->tag
==TADDR
) ) {
818 rp
->rplblock
.rplvp
= ap
;
819 rp
->rplblock
.rplxp
= NULL
;
820 rp
->rplblock
.rpltag
= ap
->tag
;
822 rp
->rplblock
.rplvp
= fmktemp(q
->vtype
, q
->vleng
);
823 rp
->rplblock
.rplxp
= fixtype( mkexpr(OPASSIGN
,
824 cpexpr(rp
->rplblock
.rplvp
), ap
) );
825 if( (rp
->rplblock
.rpltag
=
826 rp
->rplblock
.rplxp
->tag
) == TERROR
)
827 err("disagreement of argument types in statement function call");
829 rp
->rplblock
.nextp
= tlist
;
831 actuals
= actuals
->chain
.nextp
;
832 formals
= formals
->chain
.nextp
;
836 if(actuals
!=NULL
|| formals
!=NULL
)
837 err("statement function definition and argument list differ");
840 now push down names involved in formal argument list, then
841 evaluate rhs of statement function definition in this environment
843 rpllist
= hookup(tlist
, rpllist
);
844 q
= mkconv(type
, fixtype(cpexpr(rhs
)) );
846 /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */
847 while(--nargs
>= 0) {
848 if(rpllist
->rplblock
.rplxp
)
849 q
= mkexpr(OPCOMMA
, rpllist
->rplblock
.rplxp
, q
);
850 rp
= rpllist
->rplblock
.nextp
;
851 frexpr(rpllist
->rplblock
.rplvp
);
864 mklhs(struct bigblock
*p
)
871 /* first fixup name */
876 np
= p
->b_prim
.namep
;
878 /* is name on the replace list? */
880 for(rp
= rpllist
; rp
; rp
= rp
->rplblock
.nextp
) {
881 if(np
== rp
->rplblock
.rplnp
) {
882 if(rp
->rplblock
.rpltag
== TNAME
) {
883 np
= p
->b_prim
.namep
= rp
->rplblock
.rplvp
;
886 return( cpexpr(rp
->rplblock
.rplvp
) );
890 /* is variable a DO index in a register ? */
892 if(np
->b_name
.vdovar
&& ( (regn
= inregister(np
)) >= 0) ) {
893 if(np
->vtype
== TYERROR
)
900 s
->b_addr
.memno
= regn
;
901 s
->b_addr
.memoffset
= MKICON(0);
908 s
->b_addr
.memoffset
= mkexpr(OPPLUS
, s
->b_addr
.memoffset
, suboffset(p
) );
909 frexpr(p
->b_prim
.argsp
);
910 p
->b_prim
.argsp
= NULL
;
912 /* now do substring part */
914 if(p
->b_prim
.fcharp
|| p
->b_prim
.lcharp
) {
915 if(np
->vtype
!= TYCHAR
)
916 err1("substring of noncharacter %s",
917 varstr(VL
,np
->b_name
.varname
));
919 if(p
->b_prim
.lcharp
== NULL
)
920 p
->b_prim
.lcharp
= cpexpr(s
->vleng
);
922 s
->vleng
= mkexpr(OPMINUS
, p
->b_prim
.lcharp
,
923 mkexpr(OPMINUS
, p
->b_prim
.fcharp
, MKICON(1) ));
926 s
->vleng
= p
->b_prim
.lcharp
;
931 s
->vleng
= fixtype( s
->vleng
);
932 s
->b_addr
.memoffset
= fixtype( s
->b_addr
.memoffset
);
949 struct bigblock
*memversion(np
)
950 register struct bigblock
*np
;
952 register struct bigblock
*s
;
954 if(np
->b_name
.vdovar
==NO
|| (inregister(np
)<0) )
956 np
->b_name
.vdovar
= NO
;
957 s
= mklhs( mkprim(np
, 0,0,0) );
958 np
->b_name
.vdovar
= YES
;
965 register struct bigblock
*np
;
983 register struct bigblock
*p
;
989 struct dimblock
*dimp
;
991 register struct bigblock
*np
;
993 np
= p
->b_prim
.namep
;
997 for(cp
= p
->b_prim
.argsp
->b_list
.listp
; cp
; cp
= cp
->chain
.nextp
)
999 sub
[n
++] = fixtype(cpexpr(cp
->chain
.datap
));
1002 err("more than 7 subscripts");
1007 dimp
= np
->b_name
.vdim
;
1008 if(n
>0 && dimp
==NULL
)
1009 err("subscripts on scalar variable");
1010 else if(dimp
&& dimp
->ndim
!=n
)
1011 err1("wrong number of subscripts on %s",
1012 varstr(VL
, np
->b_name
.varname
) );
1017 prod
= mkexpr(OPPLUS
, sub
[n
],
1018 mkexpr(OPSTAR
, prod
, cpexpr(dimp
->dims
[n
].dimsize
)) );
1020 if(checksubs
|| np
->vstg
!=STGARG
)
1021 prod
= mkexpr(OPMINUS
, prod
, cpexpr(dimp
->baseoffset
));
1023 prod
= mkexpr(OPMINUS
, prod
, cpexpr(dimp
->baseoffset
));
1026 prod
= subcheck(np
, prod
);
1027 if(np
->vtype
== TYCHAR
)
1028 size
= cpexpr(np
->vleng
);
1029 else size
= MKICON( typesize
[np
->vtype
] );
1030 prod
= mkexpr(OPSTAR
, prod
, size
);
1031 offp
= mkexpr(OPPLUS
, offp
, prod
);
1034 if(p
->b_prim
.fcharp
&& np
->vtype
==TYCHAR
)
1035 offp
= mkexpr(OPPLUS
, offp
, mkexpr(OPMINUS
, cpexpr(p
->b_prim
.fcharp
), MKICON(1) ));
1042 * Check if an array is addressed out of bounds.
1045 subcheck(struct bigblock
*np
, bigptr p
)
1047 struct dimblock
*dimp
;
1051 dimp
= np
->b_name
.vdim
;
1052 if(dimp
->nelt
== NULL
)
1053 return(p
); /* don't check arrays with * bounds */
1055 if(p
->b_const
.fconst
.ci
< 0)
1057 if( ISICON(dimp
->nelt
) ) {
1058 if(p
->b_const
.fconst
.ci
< dimp
->nelt
->b_const
.fconst
.ci
)
1065 if (p
->tag
==TADDR
&& p
->vstg
==STGREG
) {
1068 t
= fmktemp(p
->vtype
, NULL
);
1069 putexpr(mkexpr(OPASSIGN
, cpexpr(t
), p
));
1071 /* t now cotains evaluated expression */
1075 putif(mkexpr(OPLT
, cpexpr(t
), cpexpr(dimp
->nelt
)), l1
);
1076 putif(mkexpr(OPGE
, cpexpr(t
), MKICON(0)), l1
);
1080 badcall
= call4(t
->vtype
, "s_rnge", mkstrcon(VL
, np
->b_name
.varname
),
1081 mkconv(TYLONG
, cpexpr(t
)),
1082 mkstrcon(XL
, procname
), MKICON(lineno
));
1083 badcall
->b_expr
.opcode
= OPCCALL
;
1091 err1("subscript on variable %s out of range",
1092 varstr(VL
,np
->b_name
.varname
));
1093 return ( MKICON(0) );
1099 struct bigblock
*mkaddr(p
)
1100 register struct bigblock
*p
;
1102 struct extsym
*extp
;
1103 register struct bigblock
*t
;
1108 if(p
->vclass
!= CLPROC
)
1110 extp
= mkext( varunder(VL
, p
->b_name
.varname
) );
1111 extp
->extstg
= STGEXT
;
1113 p
->b_name
.vardesc
.varno
= extp
- extsymtab
;
1114 p
->b_name
.vprocclass
= PEXTERNAL
;
1126 t
->vclass
= p
->vclass
;
1127 t
->vtype
= p
->vtype
;
1129 t
->b_addr
.memno
= p
->b_name
.vardesc
.varno
;
1130 t
->b_addr
.memoffset
= MKICON(p
->b_name
.voffset
);
1132 t
->vleng
= cpexpr(p
->vleng
);
1136 return( intraddr(p
) );
1139 /*debug*/ fprintf(diagfile
, "mkaddr. vtype=%d, vclass=%d\n", p
->vtype
, p
->vclass
);
1140 fatal1("mkaddr: impossible storage tag %d", p
->vstg
);
1142 return 0; /* XXX gcc */
1151 register struct bigblock
*p
;
1157 p
->vstg
= (type
==TYLENG
? STGLENG
: STGARG
);
1158 p
->b_addr
.memno
= argno
;
1165 bigptr
mkprim(v
, args
, lstr
, rstr
)
1167 struct bigblock
*args
;
1170 register struct bigblock
*p
;
1172 if(v
->vclass
== CLPARAM
)
1174 if(args
|| lstr
|| rstr
)
1176 err1("no qualifiers on parameter name", varstr(VL
,v
->b_name
.varname
));
1181 return( errnode() );
1183 return( cpexpr(v
->b_param
.paramval
) );
1188 p
->vtype
= v
->vtype
;
1189 p
->b_prim
.namep
= v
;
1190 p
->b_prim
.argsp
= args
;
1191 p
->b_prim
.fcharp
= lstr
;
1192 p
->b_prim
.lcharp
= rstr
;
1199 register struct bigblock
*v
;
1206 if(v
->b_name
.vdcldone
) return;
1208 if(v
->vtype
== TYUNKNOWN
)
1210 if(v
->vclass
== CLUNKNOWN
)
1212 else if(v
->vclass
!=CLVAR
&& v
->b_name
.vprocclass
!=PTHISPROC
)
1214 dclerr("used as variable", v
);
1217 if(v
->vstg
==STGUNKNOWN
)
1218 v
->vstg
= implstg
[ letter(v
->b_name
.varname
[0]) ];
1223 v
->b_name
.vardesc
.varno
= ++lastvarno
;
1226 if(v
->vclass
==CLPROC
&& v
->b_name
.vprocclass
==PTHISPROC
)
1229 if((t
= v
->b_name
.vdim
)) {
1230 if( (neltp
= t
->nelt
) && ISCONST(neltp
) )
1231 nelt
= neltp
->b_const
.fconst
.ci
;
1233 dclerr("adjustable automatic array", v
);
1235 p
= autovar(nelt
, v
->vtype
, v
->vleng
);
1236 v
->b_name
.voffset
= p
->b_addr
.memoffset
->b_const
.fconst
.ci
;
1243 v
->b_name
.vdcldone
= YES
;
1250 register struct bigblock
*p
;
1255 if(p
->b_name
.vdcldone
|| (p
->vclass
==CLPROC
&& p
->b_name
.vprocclass
==PINTRINSIC
) )
1257 if(p
->vtype
== TYUNKNOWN
)
1259 k
= letter(p
->b_name
.varname
[0]);
1260 type
= impltype
[ k
];
1261 leng
= implleng
[ k
];
1262 if(type
== TYUNKNOWN
)
1264 if(p
->vclass
== CLPROC
)
1266 dclerr("attempt to use undefined variable", p
);
1270 settype(p
, type
, leng
);
1286 #define ICONEQ(z, c) (ISICON(z) && z->b_const.fconst.ci==c)
1287 #define COMMUTE { e = lp; lp = rp; rp = e; }
1291 mkexpr(opcode
, lp
, rp
)
1293 register bigptr lp
, rp
;
1295 register struct bigblock
*e
, *e1
;
1302 if(rp
&& opcode
!=OPCALL
&& opcode
!=OPCCALL
)
1307 else rtype
= rtag
= 0;
1309 etype
= cktype(opcode
, ltype
, rtype
);
1310 if(etype
== TYERROR
)
1315 /* check for multiplication by 0 and 1 and addition to 0 */
1323 if(rp
->b_const
.fconst
.ci
== 0)
1333 err("attempted division by zero");
1344 if(rp
->b_const
.fconst
.ci
== 1)
1347 if(rp
->b_const
.fconst
.ci
== -1)
1350 return( mkexpr(OPNEG
, lp
, 0) );
1354 if( ISSTAROP(lp
) && ISICON(lp
->b_expr
.rightp
) )
1356 if(opcode
== OPSTAR
)
1357 e
= mkexpr(OPSTAR
, lp
->b_expr
.rightp
, rp
);
1358 else if(ISICON(rp
) && lp
->b_expr
.rightp
->b_const
.fconst
.ci
% rp
->b_const
.fconst
.ci
== 0)
1359 e
= mkexpr(OPSLASH
, lp
->b_expr
.rightp
, rp
);
1362 e1
= lp
->b_expr
.leftp
;
1364 return( mkexpr(OPSTAR
, e1
, e
) );
1378 return( mkexpr(OPNEG
, rp
, 0) );
1390 if(rp
->b_const
.fconst
.ci
== 0)
1392 if( ISPLUSOP(lp
) && ISICON(lp
->b_expr
.rightp
) )
1394 e
= mkexpr(OPPLUS
, lp
->b_expr
.rightp
, rp
);
1395 e1
= lp
->b_expr
.leftp
;
1397 return( mkexpr(OPPLUS
, e1
, e
) );
1407 if(ltag
==TEXPR
&& lp
->b_expr
.opcode
==OPNEG
)
1409 e
= lp
->b_expr
.leftp
;
1416 if(ltag
==TEXPR
&& lp
->b_expr
.opcode
==OPNOT
)
1418 e
= lp
->b_expr
.leftp
;
1427 if(rp
!=NULL
&& rp
->b_list
.listp
==NULL
)
1441 if(rp
->b_const
.fconst
.ci
== 0)
1446 else if(opcode
== OPOR
)
1482 fatal1("mkexpr: impossible opcode %d", opcode
);
1487 e
->b_expr
.opcode
= opcode
;
1489 e
->b_expr
.leftp
= lp
;
1490 e
->b_expr
.rightp
= rp
;
1491 if(ltag
==TCONST
&& (rp
==0 || rtag
==TCONST
) )
1505 if(rp
&& opcode
!=OPCALL
&& opcode
!=OPCCALL
)
1507 return( errnode() );
1510 #define ERR(s) { errs = s; goto error; }
1514 register int op
, lt
, rt
;
1516 char *errs
= NULL
; /* XXX gcc */
1518 if(lt
==TYERROR
|| rt
==TYERROR
)
1524 if(op
!=OPNOT
&& op
!=OPBITNOT
&& op
!=OPNEG
&& op
!=OPCALL
&& op
!=OPCCALL
&& op
!=OPADDR
)
1535 if( ISNUMERIC(lt
) && ISNUMERIC(rt
) )
1536 return( maxtype(lt
, rt
) );
1537 ERR("nonarithmetic operand of arithmetic operator")
1542 ERR("nonarithmetic operand of negation")
1547 ERR("NOT of nonlogical")
1553 if(lt
==TYLOGICAL
&& rt
==TYLOGICAL
)
1555 ERR("nonlogical operand of logical operator")
1563 if(lt
==TYCHAR
|| rt
==TYCHAR
|| lt
==TYLOGICAL
|| rt
==TYLOGICAL
)
1566 ERR("illegal comparison")
1569 else if( ISCOMPLEX(lt
) || ISCOMPLEX(rt
) )
1571 if(op
!=OPEQ
&& op
!=OPNE
)
1572 ERR("order comparison of complex data")
1575 else if( ! ISNUMERIC(lt
) || ! ISNUMERIC(rt
) )
1576 ERR("comparison of nonarithmetic data")
1580 if(lt
==TYCHAR
&& rt
==TYCHAR
)
1582 ERR("concatenation of nonchar data")
1595 if( ISINT(lt
) && rt
==TYCHAR
)
1597 if(lt
==TYCHAR
|| rt
==TYCHAR
|| lt
==TYLOGICAL
|| rt
==TYLOGICAL
)
1598 if(op
!=OPASSIGN
|| lt
!=rt
)
1600 /* debug fprintf(diagfile, " lt=%d, rt=%d, op=%d\n", lt, rt, op); */
1601 /* debug fatal("impossible conversion. possible compiler bug"); */
1602 ERR("impossible conversion")
1620 fatal1("cktype: impossible opcode %d", op
);
1623 error1
: return(TYERROR
);
1626 LOCAL bigptr
fold(e
)
1627 register struct bigblock
*e
;
1630 register bigptr lp
, rp
;
1631 int etype
, mtype
, ltype
, rtype
, opcode
;
1634 union constant lcon
, rcon
;
1636 opcode
= e
->b_expr
.opcode
;
1639 lp
= e
->b_expr
.leftp
;
1641 rp
= e
->b_expr
.rightp
;
1647 lp
->b_const
.fconst
.ci
= ! lp
->b_const
.fconst
.ci
;
1651 lp
->b_const
.fconst
.ci
= ~ lp
->b_const
.fconst
.ci
;
1663 fatal1("fold: invalid unary operator %d", opcode
);
1671 p
->vleng
= e
->vleng
;
1679 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
&& rp
->b_const
.fconst
.ci
;
1683 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
|| rp
->b_const
.fconst
.ci
;
1687 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
== rp
->b_const
.fconst
.ci
;
1691 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
!= rp
->b_const
.fconst
.ci
;
1695 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
& rp
->b_const
.fconst
.ci
;
1699 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
| rp
->b_const
.fconst
.ci
;
1703 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
^ rp
->b_const
.fconst
.ci
;
1707 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
<< rp
->b_const
.fconst
.ci
;
1711 p
->b_const
.fconst
.ci
= lp
->b_const
.fconst
.ci
>> rp
->b_const
.fconst
.ci
;
1715 ll
= lp
->vleng
->b_const
.fconst
.ci
;
1716 lr
= rp
->vleng
->b_const
.fconst
.ci
;
1717 p
->b_const
.fconst
.ccp
= q
= (char *) ckalloc(ll
+lr
);
1718 p
->vleng
= MKICON(ll
+lr
);
1719 s
= lp
->b_const
.fconst
.ccp
;
1720 for(i
= 0 ; i
< ll
; ++i
)
1722 s
= rp
->b_const
.fconst
.ccp
;
1723 for(i
= 0; i
< lr
; ++i
)
1729 if( ! ISINT(rtype
) )
1731 conspower(&(p
->b_const
.fconst
), lp
, rp
->b_const
.fconst
.ci
);
1738 lcon
.ci
= cmpstr(lp
->b_const
.fconst
.ccp
, rp
->b_const
.fconst
.ccp
,
1739 lp
->vleng
->b_const
.fconst
.ci
, rp
->vleng
->b_const
.fconst
.ci
);
1744 mtype
= maxtype(ltype
, rtype
);
1745 consconv(mtype
, &lcon
, ltype
, &(lp
->b_const
.fconst
) );
1746 consconv(mtype
, &rcon
, rtype
, &(rp
->b_const
.fconst
) );
1748 consbinop(opcode
, mtype
, &(p
->b_const
.fconst
), &lcon
, &rcon
);
1758 /* assign constant l = r , doing coercion */
1760 consconv(lt
, lv
, rt
, rv
)
1762 register union constant
*lv
, *rv
;
1770 else lv
->ci
= rv
->cd
[0];
1779 /* fall through and do real assignment of
1784 lv
->cd
[1] = 0; break;
1787 lv
->cd
[1] = rv
->cd
[1]; break;
1794 else lv
->cd
[0] = rv
->cd
[0];
1806 register struct bigblock
*p
;
1812 p
->b_const
.fconst
.ci
= - p
->b_const
.fconst
.ci
;
1817 p
->b_const
.fconst
.cd
[1] = - p
->b_const
.fconst
.cd
[1];
1818 /* fall through and do the real parts */
1821 p
->b_const
.fconst
.cd
[0] = - p
->b_const
.fconst
.cd
[0];
1824 fatal1("consnegop: impossible type %d", p
->vtype
);
1831 conspower(powp
, ap
, n
)
1832 register union constant
*powp
;
1833 struct bigblock
*ap
;
1839 switch(type
= ap
->vtype
) /* pow = 1 */
1853 fatal1("conspower: invalid type %d", type
);
1862 err("integer ** negative power ");
1866 consbinop(OPSLASH
, type
, &x
, powp
, &(ap
->b_const
.fconst
));
1869 consbinop(OPSTAR
, type
, &x
, powp
, &(ap
->b_const
.fconst
));
1874 consbinop(OPSTAR
, type
, powp
, powp
, &x
);
1876 consbinop(OPSTAR
, type
, &x
, &x
, &x
);
1884 /* do constant operation cp = a op b */
1888 consbinop(opcode
, type
, cp
, ap
, bp
)
1890 register union constant
*ap
, *bp
, *cp
;
1902 cp
->ci
= ap
->ci
+ bp
->ci
;
1906 cp
->cd
[1] = ap
->cd
[1] + bp
->cd
[1];
1909 cp
->cd
[0] = ap
->cd
[0] + bp
->cd
[0];
1919 cp
->ci
= ap
->ci
- bp
->ci
;
1923 cp
->cd
[1] = ap
->cd
[1] - bp
->cd
[1];
1926 cp
->cd
[0] = ap
->cd
[0] - bp
->cd
[0];
1936 cp
->ci
= ap
->ci
* bp
->ci
;
1940 cp
->cd
[0] = ap
->cd
[0] * bp
->cd
[0];
1944 temp
= ap
->cd
[0] * bp
->cd
[0] -
1945 ap
->cd
[1] * bp
->cd
[1] ;
1946 cp
->cd
[1] = ap
->cd
[0] * bp
->cd
[1] +
1947 ap
->cd
[1] * bp
->cd
[0] ;
1957 cp
->ci
= ap
->ci
/ bp
->ci
;
1961 cp
->cd
[0] = ap
->cd
[0] / bp
->cd
[0];
1965 zdiv(&cp
->dc
, &ap
->dc
, &bp
->dc
);
1973 cp
->ci
= ap
->ci
% bp
->ci
;
1977 fatal("inline mod of noninteger");
1979 default: /* relational ops */
1986 else if(ap
->ci
== bp
->ci
)
1992 if(ap
->cd
[0] < bp
->cd
[0])
1994 else if(ap
->cd
[0] == bp
->cd
[0])
2000 if(ap
->cd
[0] == bp
->cd
[0] &&
2001 ap
->cd
[1] == bp
->cd
[1] )
2005 default: /* XXX gcc */
2042 fatal( "sgn(nonconstant)" );
2048 if(p
->b_const
.fconst
.ci
> 0) return(1);
2049 if(p
->b_const
.fconst
.ci
< 0) return(-1);
2054 if(p
->b_const
.fconst
.cd
[0] > 0) return(1);
2055 if(p
->b_const
.fconst
.cd
[0] < 0) return(-1);
2060 return(p
->b_const
.fconst
.cd
[0]!=0 || p
->b_const
.fconst
.cd
[1]!=0);
2063 fatal1( "conssgn(type %d)", p
->vtype
);
2066 return 0; /* XXX gcc */
2069 char *powint
[ ] = { "pow_ii", "pow_ri", "pow_di", "pow_ci", "pow_zi" };
2072 LOCAL bigptr
mkpower(p
)
2073 register struct bigblock
*p
;
2075 register bigptr q
, lp
, rp
;
2076 int ltype
, rtype
, mtype
;
2078 lp
= p
->b_expr
.leftp
;
2079 rp
= p
->b_expr
.rightp
;
2085 if(rp
->b_const
.fconst
.ci
== 0)
2089 return( MKICON(1) );
2091 return( putconst( mkconv(ltype
, MKICON(1))) );
2093 if(rp
->b_const
.fconst
.ci
< 0)
2098 err("integer**negative");
2099 return( errnode() );
2101 rp
->b_const
.fconst
.ci
= - rp
->b_const
.fconst
.ci
;
2102 p
->b_expr
.leftp
= lp
= fixexpr(mkexpr(OPSLASH
, MKICON(1), lp
));
2104 if(rp
->b_const
.fconst
.ci
== 1)
2111 if( ONEOF(ltype
, MSKINT
|MSKREAL
) )
2119 if(ltype
==TYSHORT
&& rtype
==TYSHORT
)
2120 q
= call2(TYSHORT
, "pow_hh", lp
, rp
);
2122 if(ltype
== TYSHORT
)
2125 lp
= mkconv(TYLONG
,lp
);
2127 q
= call2(ltype
, powint
[ltype
-TYLONG
], lp
, mkconv(TYLONG
, rp
));
2130 else if( ISREAL( (mtype
= maxtype(ltype
,rtype
)) ))
2131 q
= call2(mtype
, "pow_dd",
2132 mkconv(TYDREAL
,lp
), mkconv(TYDREAL
,rp
));
2134 q
= call2(TYDCOMPLEX
, "pow_zz",
2135 mkconv(TYDCOMPLEX
,lp
), mkconv(TYDCOMPLEX
,rp
));
2136 if(mtype
== TYCOMPLEX
)
2137 q
= mkconv(TYCOMPLEX
, q
);
2145 /* Complex Division. Same code as in Runtime Library
2152 register struct dcomplex
*a
, *b
, *c
;
2157 if( (abr
= b
->dreal
) < 0.)
2159 if( (abi
= b
->dimag
) < 0.)
2164 fatal("complex division by zero");
2165 ratio
= b
->dreal
/ b
->dimag
;
2166 den
= b
->dimag
* (1 + ratio
*ratio
);
2167 c
->dreal
= (a
->dreal
*ratio
+ a
->dimag
) / den
;
2168 c
->dimag
= (a
->dimag
*ratio
- a
->dreal
) / den
;
2173 ratio
= b
->dimag
/ b
->dreal
;
2174 den
= b
->dreal
* (1 + ratio
*ratio
);
2175 c
->dreal
= (a
->dreal
+ a
->dimag
*ratio
) / den
;
2176 c
->dimag
= (a
->dimag
- a
->dreal
*ratio
) / den
;