/* Copyright (c) 1979 Regents of the University of California */
* Convert a p1 into a p2.
* Mostly used for different
* length integers and "to real" conversions.
if (p1
== NIL
|| p2
== NIL
)
switch (width(p1
) - width(p2
)) {
* p1 and p2 are compatible
* types for an assignment like
* context, i.e. value parameters,
* indicies for 'in', etc.
if (c2
== TINT
&& divflg
== 0) {
c1
= classify(rvalue(t
, NIL
));
error("Type clash: real is incompatible with integer");
cerror("This resulted because you used '/' which always returns real rather");
cerror("than 'div' which divides integers and returns integers");
if (scalar(p1
) != scalar(p2
)) {
derror("Type clash: non-identical scalar types");
if (width(p1
) != width(p2
)) {
derror("Type clash: unequal length strings");
derror("Type clash: files not allowed in this context");
derror("Type clash: non-identical %s types", clnames
[c1
]);
if (p1
->nl_flags
& NFILES
) {
derror("Type clash: %ss with file components not allowed in this context", clnames
[c1
]);
derror("Type clash: %s is incompatible with %s", clnames
[c1
], clnames
[c2
]);
* Rangechk generates code to
* check if the type p on top
* of the stack is in range for
* assignment to a variable
* When op is 1 we are checking length
* 4 numbers against length 2 bounds,
* and adding it to the opcode forces
* generation of appropriate tests.
op
= wq
!= wrp
&& (wq
== 4 || wrp
== 4);
put3(O_RANG2
+op
, rp
->value
[1], rp
->value
[3]);
put(5, O_RANG4
+op
, rp
->range
[0], rp
->range
[1]);
put3(O_RANG2
+op
, rp
->value
[1], rp
->value
[3]);
put(5, O_RANG4
+op
, rp
->range
[0], rp
->range
[1]);
if (rp
!= nl
+T2INT
&& rp
!= nl
+T4INT
)
put3(O_RANG2
+op
, rp
->value
[1], rp
->value
[3]);
* Range whose lower bounds are
* zero can be treated as scalars.
put2(O_RSNG2
+op
, rp
->value
[3]);
put3(O_RSNG4
+op
, rp
->range
[1]);
newfp
[0] = dub
[0] & 0100000;
exp
= ((dub
[0] >> 7) & 0377) - 0200;
newfp
[0] |= (mant
>> 17) & 077777;
newfp
[1] |= (((int) (mant
>> 1)) & 0177400) | (exp
<< 1);