* 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
[] = "@(#)eval.c 5.2 (Berkeley) 4/7/87";
#include "process/process.rep"
#include "process/pxinfo.h"
#define Boolean char /* underlying representation type for booleans */
* Evaluate a parse tree using a stack; value is left at top.
} else if (isint(p
->op
)) {
r1
= popsmall(p
->right
->nodetype
);
} else if (isint(p
->op
)) {
r0
= popsmall(p
->left
->nodetype
);
error("cannot evaluate a %s", classname(s
));
error("\"%s\" is not active", name(f
));
push(long, address(s
, NIL
));
switch (size(p
->nodetype
)) {
panic("bad size %d for LCON", size(p
->nodetype
));
push(double, p
->fconval
);
mov(p
->sconval
, sp
, len
);
long n
; /* base address for array */
long i
; /* index - lower bound */
i
= evalindex(p
->left
->nodetype
, p
->right
);
push(long, n
+ i
*size(p
->nodetype
));
error("reference through nil pointer");
dread(sp
, a
, sizeof(ADDRESS
));
* Get the value of the expression addressed by the top of the stack.
* Push the result back on the stack.
error("reference through nil pointer");
error("expression too large to evaluate");
push(double, (double) r0
);
error("error: division by 0");
error("error: div by 0");
error("error: mod by 0");
push(Boolean
, fr0
< fr1
);
push(Boolean
, fr0
<= fr1
);
push(Boolean
, fr0
> fr1
);
push(Boolean
, fr0
== fr1
);
push(Boolean
, fr0
!= fr1
);
assign(p
->left
, p
->right
);
printf("%s\n", cursource
);
fp
= fopen(p
->sconval
, "r");
error("can't read \"%s\"", p
->sconval
);
if (p
->left
->op
== O_NAME
) {
error("\"%s\" is not a procedure or function", name(b
));
error("\"%s\" is empty", name(b
));
skimsource(srcfilename(addr
));
printlines((LINENO
) r0
, (LINENO
) r1
);
if (p
->left
->op
== O_CALL
) {
b
= p
->left
->left
->nameval
;
printinst((ADDRESS
) r0
, (ADDRESS
) r1
);
printdata((ADDRESS
) r0
, (ADDRESS
) r1
);
for (o
= p
->left
; o
!= NIL
; o
= o
->right
) {
printval(o
->left
->nodetype
);
if (p
->left
->op
== O_NAME
) {
printdecl(p
->left
->nameval
);
printdecl(p
->left
->nodetype
);
alias(p
->left
->sconval
, p
->right
->sconval
);
callproc(p
->left
, p
->right
);
trace(p
->op
, p
->what
, p
->where
, p
->cond
);
stop(p
->op
, p
->what
, p
->where
, p
->cond
);
delbp((unsigned int) pop(long));
panic("eval: bad op %d", p
->op
);
* Push "len" bytes onto the expression stack from address "addr"
* in the process. Normally TRUE is returned, however if there
* isn't enough room on the stack, rpush returns FALSE.
register char *savesp
= sp
;
if (sp
+ len
>= &stack
[STACKSIZE
]) {
if (sp
>= &stack
[STACKSIZE
]) {
* Pop an item of the given type which is assumed to be no larger
* than a long and return it expanded into a long.
* A bit of a kludge here. If an array element is a record,
* the dot operation will be converted into an addition with
* the record operand having a type whose size may be larger
* than a word. Now actually this is a pointer, but the subscript
* operation isn't aware of this, so it's just hacked here.
* The right thing to do is to make dot directly evaluated
* instead of changing it into addition.
* evaluate a conditional expression
* Return the address corresponding to a given tree.