1 /* loadexp.c - load expressions for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
16 PUBLIC value_t
constexpression()
18 struct nodestruct
*etmark
;
19 struct nodestruct
*exp
;
20 struct symstruct
*exprmark
;
21 struct symstruct
*symptr
;
25 exp
= assignment_exp();
28 if (exp
->tag
== LEAF
&& (symptr
= exp
->left
.symptr
)->storage
== CONSTANT
29 && symptr
->type
->scalar
& ISCALAR
)
30 return symptr
->offset
.offv
;
31 error("constant expression required");
35 PUBLIC
void initexpression(type
)
36 struct typestruct
*type
;
38 struct nodestruct
*etmark
;
39 struct nodestruct
*exp
;
40 struct symstruct
*exprmark
;
41 struct nodestruct
*lhs
;
42 struct symstruct
*symptr
;
45 if (gvarsymptr
->storage
!= GLOBAL
)
49 exp
= assignment_exp();
50 if (gvarsymptr
->storage
!= GLOBAL
)
52 lhs
= leafnode(exprsym(gvarsymptr
));
53 if (!(lhs
->nodetype
->constructor
& (ARRAY
| FUNCTION
| VOID
)))
55 makeleaf(node(ASSIGNOP
, lhs
, exp
));
57 else if (exp
->tag
!= LEAF
||
58 ((symptr
= exp
->left
.symptr
)->storage
!= CONSTANT
&&
59 (symptr
->storage
!= GLOBAL
|| symptr
->indcount
!= 0 ||
60 type
->scalar
& DLONG
)) ||
61 (type
->constructor
| (symptr
->type
->constructor
& ~FUNCTION
)) &
63 error("initializer too complicated");
66 if ((symptr
->type
->scalar
| type
->scalar
) & RSCALAR
)
68 /* Can only afford castnode if result known constant. */
69 exp
= castnode(type
, exp
);
70 symptr
= exp
->left
.symptr
;
72 if (type
->scalar
& RSCALAR
)
74 if (type
->scalar
& FLOAT
)
78 val
= *symptr
->offset
.offd
;
79 deflong(((uoffset_T
*) &val
)[0]);
83 deflong(((uoffset_T
*) symptr
->offset
.offd
)[0]);
84 deflong(((uoffset_T
*) symptr
->offset
.offd
)[1]);
86 etptr
= etmark
; /* XXX - stuff from end of function */
90 if (type
->typesize
== 1)
92 else if (type
->typesize
== 2)
95 else if (!(type
->scalar
& DLONG
))
98 switch (symptr
->storage
)
101 value
= (uoffset_T
) symptr
->offset
.offv
;
102 if (type
->scalar
& DLONG
)
107 /* XXX - put sizes in type struct to avoid tests */
108 if (type
->scalar
& CHAR
)
110 else if (type
->scalar
& SHORT
)
111 value
&= shortmaskto
;
112 else if (type
->scalar
& INT
)
114 /* XXX - no longmaskto */
118 if (symptr
->flags
& LABELLED
)
120 outlabel(symptr
->name
.label
);
122 outnhex((uoffset_T
) symptr
->offset
.offi
);
125 if (*symptr
->name
.namep
== 0) /* constant address */
127 outnhex((uoffset_T
) symptr
->offset
.offi
);
130 outccname(symptr
->name
.namep
);
131 if (symptr
->offset
.offi
!= 0)
133 if (symptr
->offset
.offi
> 0)
135 outshex(symptr
->offset
.offi
);
145 PUBLIC
struct typestruct
*loadexpression(targreg
, targtype
)
147 struct typestruct
*targtype
;
149 struct nodestruct
*etmark
;
150 struct nodestruct
*exp
;
151 struct symstruct
*exprmark
;
156 if (targtype
!= NULL
)
157 exp
= castnode(targtype
, exp
);
159 if (targtype
== NULL
) /* this is for a switch */
161 targtype
= exp
->left
.symptr
->type
;
162 if (!(targtype
->scalar
& (CHAR
| INT
))
163 && (targtype
->scalar
& (LONG
| DLONG
)) != LONG
)
165 if (targtype
->scalar
& SHORT
)
166 targtype
= promote(targtype
);
169 error("non-integral selector in switch");
172 makeleaf(exp
= castnode(targtype
, exp
));
175 load(exp
->left
.symptr
, targreg
); /* resets stack if value was there */
178 return exp
->left
.symptr
->type
;