* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)stkrval.c 5.2 (Berkeley) 11/12/86";
* stkrval Rvalue - an expression, and coerce it to be a stack quantity.
* Contype is the type that the caller would prefer, nand is important
* if constant sets or constant strings are involved, the latter
* because of string padding.
* for the obj version, this is a copy of rvalue hacked to use fancy new
* push-onto-stack-and-convert opcodes.
* for the pc version, i just call rvalue and convert if i have to,
* based on the return type of rvalue.
stkrval(r
, contype
, required
)
register struct tnode
*r
;
* The root of the tree tells us what sort of expression we have.
(void) put(2, O_CON14
, 0);
putleaf( PCC_ICON
, 0 , 0 , PCCT_INT
, (char *) 0 );
p
= lookup(r
->var_node
.cptr
);
if (p
== NLNIL
|| p
->class == BADUSE
)
if (r
->var_node
.qual
!= TR_NIL
)
return(stklval(r
, NOFLAGS
));
q
= rvalue( r
, contype
, (int) required
);
sconv(p2type(q
),PCCT_INT
);
* might consider a rvalue.
if ( required
== RREQ
) {
putop( PCCOM_UNARY PCC_MUL
, p2type( q
) );
sconv(p2type(q
),PCCT_INT
);
if (r
->var_node
.qual
!= TR_NIL
) {
error("%s is a constant and cannot be qualified", r
->var_node
.cptr
);
* Find the size of the string
if (contype
!= NIL
&& !opt('s')) {
if (width(contype
) < c
&& classify(contype
) == TSTR
) {
error("Constant string too long");
(void) put(2, O_LVCON
, lenstr(cp1
, w
- c
));
putCONG( cp1
, w
, LREQ
);
* Define the string temporarily
* so later people can know its
q
= defnl((char *) 0, STR
, NLNIL
, w
);
(void) put(2, O_CONC4
, (int)p
->value
[0]);
putleaf(PCC_ICON
, p
-> value
[0], 0, PCCT_INT
,
* Every other kind of constant here
(void) put(2, O_CON8
, p
->real
);
conv((int *) (&f
.pdouble
));
(void) put(2, O_CON4
, l
);
(void) put(2, O_CON8
, p
->real
);
(void) put(2, O_CON4
, p
->range
[0]);
(void) put(2, O_CON24
, (short)p
->range
[0]);
(void) put(2, O_CON14
, p
->value
[0]);
q
= rvalue( r
, contype
, (int) required
);
sconv(p2type(q
),PCCT_INT
);
switch (pt
->list_node
.list
->tag
) {
error("Can't qualify a function result value");
if (classify(q
) == TSTR
) {
roundup(c
+1, (long) A_SHORT
));
sconv(p2type(p
),PCCT_INT
);
error("Type names (e.g. %s) allowed only in declarations", p
->symbol
);
error("Procedure %s found where expression required", p
->symbol
);
p
= rvalue(r
, contype
, (int) required
);
sconv(p2type(p
),PCCT_INT
);
p
= rvalue(r
, contype
, (int) required
);
if (r
->const_node
.cptr
== (char *) NIL
)
f
.pdouble
= a8tol(r
->const_node
.cptr
);
f
.pdouble
= atof(r
->const_node
.cptr
);
if (f
.pdouble
> MAXINT
|| f
.pdouble
< MININT
) {
error("Constant too large for this implementation");
(void) put(2, O_CON24
, (short)l
);
putleaf( PCC_ICON
, (short) l
, 0 , PCCT_INT
,
(void) put(2, O_CON4
, l
);
putleaf( PCC_ICON
, (int) l
, 0 , PCCT_INT
, (char *) 0 );
* A floating point number
(void) put(2, O_CON8
, atof(r
->const_node
.cptr
));
putCON8( atof( r
->const_node
.cptr
) );
* Constant strings. Note that constant characters
* are constant strings of length one; there is
* no constant string of length one.
(void) put(2, O_CONC4
, cp
[0]);
putleaf( PCC_ICON
, cp
[0] , 0 , PCCT_INT
,
* push a value onto the interpreter stack, longword aligned.
bn
= BLOCKNO(p
->nl_block
);
(void) put(2, O_RV8
| bn
<< 8+INDX
, (int)p
->value
[0]);
(void) put(2, O_RV4
| bn
<< 8+INDX
, (int)p
->value
[0]);
(void) put(2, O_RV24
| bn
<< 8+INDX
, (int)p
->value
[0]);
(void) put(2, O_RV14
| bn
<< 8+INDX
, (int)p
->value
[0]);
(void) put(3, O_RV
| bn
<< 8+INDX
, (int)p
->value
[0], w
);