1
0
Files
irix-657m-src/stand/arcs/ide/common/ide_run.c
2022-09-29 17:59:04 +03:00

1778 lines
42 KiB
C

#ident "$Revision: 1.33 $"
/*
* arcs/ide/ide_run.c - Execute an ide parse tree
*
*/
#include <sys/sbd.h>
#include <genpda.h>
#include <ide_msg.h>
#include <libsc.h>
#include <libsk.h>
#include <uif.h>
#include "ide.h"
#include "ide_mp.h"
#include "ide_sets.h"
#define USE_OUR_OWN
#define EVAL_DEBUG
void doprint(context_t *context, node_t *pnode);
void doif(context_t *context, node_t *pnode);
void dowhile(context_t *context, node_t *pnode);
void dofor(context_t *context, node_t *pnode);
void dodo(context_t *context, node_t *pnode);
void doreturn(context_t *context, node_t *pnode);
void doswitch(context_t *context, node_t *pnode);
void dorepeat(context_t *context, node_t *pnode);
int findcase(context_t *, ide_int_type, node_t *, int);
sym_t *eval(context_t *, node_t *);
static int makeargv(context_t *, node_t *, sym_t **);
/*
* genpda.h evaluates MULTIPROCESSOR; ensure it's been included
*/
#ifndef __GENPDA_H__
dontcompile("#include ERROR, ide_run.c: genpda.h hasn't been included!")
#endif
/*
* dostmt - Top level entry point
*
* Establishes a context for "return" statements and initiates execution.
*
*/
context_t global_context;
#define MS1 10000 /* 10 ms */
extern int inrawcmd;/* parsing a diag command that doesn't want parsed args */
/*
* Create a global context for ide
*
* The $0..$n paramters are set up to be the same as the command
* line arguments to ide.
*
*/
int
init_context(int argc, char *argv[])
{
int i;
for ( i = 0; i < argc; i++ ) {
global_context.argv[i] = makessym(argv[i]);
global_context.argc++;
}
return 0;
}
/*
* handle interrupt - let ide scripts see and react to ^c
*
* Whenever ^C is pressed, the user defined function "trap"
* is executed. The trap function may be used to reset tty
* or graphics or anything else.
*/
void
handle_interrupt(void)
{
sym_t *psym;
node_t *pnode;
if ( (psym = findsym("trap")) && psym->sym_type == SYM_CMD ) {
pnode = makenode();
pnode->node_psym = psym;
pnode->node_type = OP_CMD;
dostmt(pnode);
destroynode(pnode);
}
close_noncons(); /* close leftover fd's */
}
/*
* dotree - execute a tree within a given context
*
*/
void
dotree(context_t *context, node_t *pnode)
{
#ifdef _STANDALONE
_scandevs();
#endif
if ( ! pnode )
return;
switch ( pnode->node_type ) {
case OP_STMT:
dotree(context, pnode->node_right);
dotree(context, pnode->node_left);
break;
case OP_PRINT:
doprint(context, pnode);
break;
case OP_IF:
doif(context, pnode);
break;
case OP_WHILE:
dowhile(context, pnode);
break;
case OP_FOR:
dofor( context, pnode);
break;
case OP_DO:
dodo( context, pnode);
break;
case OP_RETURN:
doreturn(context,pnode);
break;
case OP_BREAK:
longjmp(context->lframe, 2);
break;
case OP_CONTINUE:
longjmp(context->lframe, 3);
break;
case OP_SWITCH:
doswitch(context,pnode);
break;
case OP_REPEAT:
dorepeat(context,pnode);
break;
default:
destroysym(eval(context, pnode));
break;
}
}
/*
* Top level entry point into command executor
*
*/
void
dostmt(node_t *pnode)
{
if ( setjmp(global_context.rframe) )
return;
dotree(&global_context, pnode);
return;
}
/*
* Promote symbol to integer
*
* This routine is used whenever the context of an expression requires
* an integer and we don't have one.
*
* - If the symbol is a string (basetype SYMB_STR), this routine will try
* to figure out if it looks like a string of digits and then converts
* it to binary (like awk). The symbol's basetype is then SYMB_INT.
*
* - If symbol's basetype is SYMB_SETSTR, the sym_s field is a pointer to
* a string of ascii digits representing virtual cpu numbers, separated
* by commas. This string is converted back to the bitfield representation
* used by the sym_set field: basetype SYMB_SET.
*
* - Symbols with basetypes of SYMB_INT and SYMB_SET therefore need no
* conversion; pro_int returns the symbol unchanged.
*
* - pro_int checks for symbols with SYMB_RANGE or invalid basetypes.
*/
sym_t *
pro_int(sym_t *psym)
{
char setbuf[SETBUFSIZ];
sym_t *tmp;
int v = 0;
int base = 10;
char *p;
if (!psym)
ide_panic("pro_int: NULL psym");
msg_printf(DBG+2,
"pro_int sym \"%s\", initial strval \"%s\" type %d btype %d\n",
_SAFESTR(psym->sym_name), _SAFESTR(psym->sym_s),
psym->sym_type, psym->sym_basetype);
/*
* SYMB_SET and SYMB_INT are already in pro_int()'s output format,
* and SYMB_RANGE shouldn't be here.
*/
switch (psym->sym_basetype) {
case SYMB_SET:
sprintf_cset(setbuf, psym->sym_set);
msg_printf(JUST_DOIT,
" pro_int, symname \"%s\": btype SYMB_SET, type %d (%s)\n",
_SAFESTR(psym->sym_name), psym->sym_type, setbuf);
if (psym->sym_type != SYM_VAR) {
msg_printf(IDE_ERR,
"!pro_int 0x%x=\"%s\", SET: type %d not VAR (%d)\n",
(__psunsigned_t)psym->sym_name, _SAFESTR(psym->sym_name),
psym->sym_type, SYM_VAR);
msg_printf(JUST_DOIT, " val 0x%x=%d, or \"%s\"\n",
psym->sym_i, psym->sym_i, _SAFESTR(psym->sym_s));
}
return psym;
case SYMB_INT:
if (psym->sym_type != SYM_VAR && psym->sym_type != SYM_CON &&
psym->sym_type != SYM_UNDEFINED) {
msg_printf(IDE_ERR,
"pro_int (0x%x=\"%s\"): btype INT, bad type %d\n ",
(__psunsigned_t)psym->sym_name, _SAFESTR(psym->sym_name),
psym->sym_type);
msg_printf(JUST_DOIT, " val 0x%x or \"%s\"\n",
psym->sym_i, _XSAFESTR(psym->sym_s));
}
return psym;
case SYMB_RANGE:
if (psym->sym_type != SYM_VAR && psym->sym_type != SYM_CON) {
msg_printf(IDE_ERR,
"pro_int RANGE (%d): type %d, not VAR or CON\n",
psym->sym_basetype, psym->sym_type);
}
return psym;
case SYMB_SETSTR:
msg_printf(DBG,
"pro_int SETSTR,pre: \"%s\": type %d, bt %d, _s \"%s\"\n",
_SAFESTR(psym->sym_name), psym->sym_type,
psym->sym_basetype, _SAFESTR(psym->sym_s));
tmp = pro_set(psym);
ASSERT(tmp);
msg_printf(DBG,
"pro_int SETSTR, after: NOW type %d, btype %d _i 0x%x\n",
tmp->sym_type, tmp->sym_basetype, tmp->sym_i);
destroysym(psym);
return(tmp);
case SYMB_STR:
msg_printf(DBG+2,
"pro_int(STR=%d),pre: name \"%s\", \"%s\", type %d\n",
psym->sym_type, _SAFESTR(psym->sym_name),
_SAFESTR(psym->sym_s), psym->sym_type);
tmp = makesym();
tmp->sym_basetype = SYMB_INT;
tmp->sym_type = SYM_VAR;
p = psym->sym_s;
ASSERT(p);
/*
* figure out the base the string wants to pack
*/
if ( *p == '0' ) {
base = 8;
p++;
if ( *p == 'x' || *p == 'X' ) {
base = 16;
p++;
}
else
if ( *p == 'b' || *p == 'B' ) {
base = 2;
p++;
}
}
for ( ;isxdigit( *p ); p++ ) { /* string-->int */
if ( *p > '9' && base < 16 )
break;
if ( *p >= 'a' && *p <= 'f' )
v = (v * base) + (*p - 'a') + 10;
else
if ( *p >= 'A' && *p <= 'F' )
v = (v * base) + (*p - 'A') + 10;
else
if ( (*p - '0') >= base )
break;
v = (v * base) + (*p - '0');
}
if ( *p ) /* error in string */
tmp->sym_i = 0;
else
tmp->sym_i = v;
msg_printf(DBG+2,
"pro_int(STR) after: outval 0Lx%Lx, btype %d type %d\n",
tmp->sym_set, tmp->sym_basetype, tmp->sym_type);
destroysym(psym);
return(tmp);
default: /* possibly returning an invalid symbol from userdef */
tmp = makesym();
msg_printf(IDE_ERR,
"!!pro_int, default: \"%s\": bad btype %d, type %d\n",
_SAFESTR(psym->sym_name), psym->sym_basetype,
psym->sym_type);
msg_printf(DBG," _i 0Lx%Lx (\"%s\"), type %d flags 0x%x\n",
psym->sym_set, _XSAFESTR(psym->sym_s), psym->sym_type,
psym->sym_flags);
tmp->sym_basetype = SYMB_INT;
tmp->sym_type = SYM_VAR;
tmp->sym_i = (int)0x80000000; /* 2's comp NEGMAXINT */
destroysym(psym);
return(tmp);
} /* switch */
/*NOTREACHED*/
} /* pro_int */
/*
* promote to string
*
* This routine is called whenever a string is needed. It is much
* simpler to convert to strings than to integers.
* SYMB_INT and SYMB_SET symbols ---> SYMB_STR and SYMB_SETSTR, resp.
* SYMB_STR and SYMB_SETSTR just return.
*/
sym_t *
pro_str(sym_t *psym)
{
sym_t *tmp;
char v[MAXSTRLEN];
char r[32];
int rp = 0;
char *vp = v;
ide_int_type p;
if (!psym)
ide_panic("pro_str: NULL psym");
msg_printf(DBG+2,
"pro_str, symname \"%s\", _i %d _set 0Lx%x, type %d btype %d\n",
_SAFESTR(psym->sym_name), psym->sym_i, psym->sym_set,
psym->sym_type, psym->sym_basetype);
switch(psym->sym_basetype) {
case SYMB_STR:
case SYMB_SETSTR:
switch(psym->sym_type) {
case SYM_CON:
case SYM_PARAM:
case SYM_VAR:
msg_printf(DBG+3,
" symbol \"%s\", type %d btype %d ok: return\n",
_SAFESTR(psym->sym_name), psym->sym_type,
psym->sym_basetype);
return(psym);
default:
msg_printf(IDE_ERR,
" ??bt %d: type %d, not CON, VAR, or PARAM\n",
psym->sym_basetype, psym->sym_type);
return(psym);
} /* sym_type switch */
/* NOTREACHED */
case SYMB_SET:
tmp = pro_setstr(psym);
ASSERT(tmp);
if (tmp->sym_basetype == SYMB_SETSTR) {
msg_printf(DBG+2,
"pro_str(SETSTR): setstr _s \"%s\", type %d\n",
_SAFESTR(tmp->sym_s), tmp->sym_type);
} else {
msg_printf(IDE_ERR,
"pro_str(t%d,bt%d): name\"%s\",setval=0Lx%Lx: %s\n",
tmp->sym_type, tmp->sym_basetype,
_SAFESTR(tmp->sym_name), tmp->sym_set,
"needed SETSTR btype");
}
destroysym(psym);
return(tmp);
case SYMB_INT:
tmp = makesym();
tmp->sym_basetype = SYMB_STR;
tmp->sym_type = SYM_CON;
break;
case SYMB_RANGE:
msg_printf(IDE_ERR,
"??btype RANGE(%d), type %d: pro_str not applicable\n",
psym->sym_basetype, psym->sym_type);
return(psym);
default: /* possibly attempted echo of nonexistent symbol */
msg_printf(USER_ERR, " invalid symbol \"%s\", restart\n",
_SAFESTR(psym->sym_name));
msg_printf(JUST_DOIT, "!!->pro_str, sym \"%s\": bad btype %d\n",
_SAFESTR(psym->sym_name), psym->sym_basetype);
msg_printf(JUST_DOIT, " _i 0x%x, type %d, flags 0x%x\n",
psym->sym_i, psym->sym_type, psym->sym_flags);
badflag = 1;
tmp = makesym();
tmp->sym_basetype = SYMB_BADVAL;
tmp->sym_type = SYM_BADVAL;
tmp->sym_i = 0xdeadbeef;
destroysym(psym);
/* longjmp(intr_jump, SCRIPT_ERR_RESTART); */
/* !! psignal(SIGINT); */
return(tmp);
/*NOTREACHED*/
} /* btype switch */
/*
* only SYMB_INT basetypes remain: convert to ascii string
*/
if ( (p = psym->sym_i) < 0 ) {
*vp++ = '-';
p = -p;
}
do {
r[rp++] = (char)((p % 10)+'0');
p /= 10;
} while ( p );
while ( --rp >= 0 )
*vp++ = r[rp];
*vp = '\0';
tmp->sym_s = makestr(v);
msg_printf((EVAL_DBG|VDBG+1), " pro_str: int %d --> str \"%s\"\n",
psym->sym_i, _SAFESTR(tmp->sym_s));
if ((Reportlevel & EVAL_DBG) || Reportlevel > VDBG) {
msg_printf(JUST_DOIT, " end pro_str, tmp: ");
_dumpsym(tmp);
}
destroysym(psym);
return tmp;
} /* pro_str */
/*
* pro_set(): set symbols have basetypes of either SYMB_SET or SYMB_SETSTR.
* SYMB_SET symbols use an unsigned long long bitfield to represent the
* members in the 'sym_set' field of 'sym_t' structs. SYMB_SETSTR uses an
* ascii string of the format "0,1,2,3..", pointed to by the `sym_s' field.
* pro_set() creates a new temporary symbol by promoting "psym's" symbol
* from btype SYMB_SET to SYMB_SETSTR. For all other incoming basetypes,
* pro_set displays an IDE_ERR message and returns a negative errno.
*
* pro_set() returns a sym_t* ptr to the promoted set.
*
* Set layout is defined with member 0 represented by high bit of most
* significant byte of unsigned long long.
*/
sym_t *
pro_set(sym_t *psym)
{
char setbuf[SETBUFSIZ];
sym_t *tmp;
int bogus_bt=0, vcnt=0;
option_t vidstr;
vplist_t vidlist;
if (!psym)
ide_panic("pro_set: NULL symbol ptr!");
msg_printf((EVAL_DBG|DBG+2),
"pro_set, name \"%s\": &_s 0x%x, _s\"%s\", type %d btype %d\n",
_SAFESTR(psym->sym_name), (__psunsigned_t)psym->sym_s,
_SAFESTR(psym->sym_s), psym->sym_type, psym->sym_basetype);
switch (psym->sym_basetype) {
case SYMB_SET:
msg_printf((EVAL_DBG|DBG+2),
"pro_set: already btype %d; _set 0Lx%Lx\n", psym->sym_set);
return(psym);
case SYMB_SETSTR: /* string --> bitfield, type SYM_VAR */
msg_printf((EVAL_DBG|DBG+1),
"pro_set, btype SYMB_SETSTR: sym_s 0x%x or \"%s\"\n",
(__psunsigned_t)psym->sym_s, _SAFESTR(psym->sym_s));
/*
* use _get_arglist to break the comma-separated ascii
* vid-string into a list of args
*/
if (_get_arglist(psym->sym_s, &vidstr)) { /* PUNT! */
msg_printf(IDE_ERR,
"pro_set, SETSTR: %s failed get_arglist\n",
_SAFESTR(psym->sym_name));
return(psym);
}
/* ascii-->binary and validate the vids */
if (_check_vpids(&vidstr, &vidlist)) {
msg_printf(IDE_ERR,
"pro_set, SETSTR: %s failed _check_vpids\n",
_SAFESTR(psym->sym_name));
return(psym);
}
ASSERT(vidlist.vpcnt >= 0);
tmp = makesym();
ASSERT(tmp);
tmp->sym_set = 0;
for (vcnt = 0; vcnt < vidlist.vpcnt; vcnt++)
tmp->sym_set |= (SET_ZEROBIT>>vidlist.vps[vcnt]);
tmp->sym_basetype = SYMB_SET;
tmp->sym_type = SYM_CON;
if ((Reportlevel & EVAL_DBG) || Reportlevel > VDBG) {
sprintf_cset(setbuf, tmp->sym_set);
msg_printf((EVAL_DBG|DBG+1),
"pro_set: return a %d-cpu SYM_CON SYMB_SET: \"%s\"\n",
vcnt, _SAFESTR(setbuf));
}
destroysym(psym);
return(tmp);
default:
bogus_bt = 1; /* protect sym_tstrs array-access */
case SYMB_INT:
case SYMB_STR:
case SYMB_RANGE:
msg_printf(IDE_ERR,
"pro_set, \"%s\": bt %s(%d), _i %d, &_s 0x%x _s\"%s\"\n",
_SAFESTR(psym->sym_name),
(bogus_bt ? "?" : sym_tstrs[psym->sym_basetype]),
psym->sym_basetype, psym->sym_i, (__psunsigned_t)psym->sym_s,
_SAFESTR(psym->sym_s));
return(psym);
}
/*NOTREACHED*/
} /* pro_set */
/*
* pro_setstr() is the reverse of pro_set--promotes symbols of basetype
* SYMB_SETSTR to SYMB_SET. See pro_set() explanation.
*/
sym_t *
pro_setstr(sym_t *psym)
{
char setbuf[SETBUFSIZ];
char *cp= &setbuf[0];
sym_t *tmp;
setmask_t mask;
set_t ullval;
int i, bogus_bt=0, vcnt=0;
if (!psym)
ide_panic("pro_setstr: NULL symbol ptr!");
msg_printf((EVAL_DBG|DBG+2),
"pro_setstr, name \"%s\": _set 0Lx%Lx, type %d, btype %d\n",
_SAFESTR(psym->sym_name), psym->sym_set, psym->sym_type,
psym->sym_basetype);
switch (psym->sym_basetype) {
case SYMB_SET: /* bitfield --> ascii string, type SYM_CON */
tmp = makesym();
ASSERT(tmp);
msg_printf((EVAL_DBG|DBG+2), " : ");
tmp->sym_type = SYM_CON;
tmp->sym_basetype = SYMB_SETSTR;
ullval = psym->sym_set;
if (!ullval) {
tmp->sym_s = makestr("");
ASSERT(tmp->sym_s);
break;
}
mask = SET_ZEROBIT;
for (i = 0; i < MAXSETSIZE; i++) {
if (mask & ullval)
cp += sprintf(cp,"%s%d", (vcnt++?",":""), i);
mask >>= 1;
}
ASSERT(cp < (&setbuf[SETBUFSIZ]));
tmp->sym_s = makestr(setbuf);
ASSERT(tmp->sym_s);
msg_printf((EVAL_DBG|DBG+1),
"pro_setstr: return a %d-cpu, SYM_CON SETSTR: \"%s\"\n",
vcnt, _SAFESTR(tmp->sym_s));
break;
case SYMB_SETSTR:
msg_printf((EVAL_DBG|DBG+2),
"--> already SYMB_SETSTR: type %d: _s 0x%x, _s \"%s\"\n",
psym->sym_type, (__psunsigned_t)psym->sym_s, _SAFESTR(psym->sym_s));
return(psym);
default:
bogus_bt = 1; /* protect sym_tstrs array-access */
case SYMB_INT:
case SYMB_STR:
case SYMB_RANGE:
msg_printf(IDE_ERR,
"pro_setstr, \"%s\": bt %s(%d), _i %d, _s 0x%x _s\"%s\"\n",
_SAFESTR(psym->sym_name),
(bogus_bt ? "?" : sym_tstrs[psym->sym_basetype]),
psym->sym_basetype, psym->sym_i,(__psunsigned_t)psym->sym_s,
_SAFESTR(psym->sym_s));
return(psym);
}
destroysym(psym);
return(tmp);
} /* pro_setstr */
#if defined(STKDEBUG)
extern int _dcache_size, cp_dcache_size, cpied;
extern uint get_sp(void);
extern __psunsigned_t set_watch(__psunsigned_t, int);
int did_set_wwatch=0;
int doset_wwatch=0;
#endif /* STKDEBUG */
/*
* docmd - run a command or function.
*
* There are two different types of commands:
* 1. Those defined by the user as an ide function
* 2. Those defined by ide as builtins.
*
*/
sym_t *
docmd(context_t *context, node_t *pnode)
{
context_t ccontext;
sym_t *cmd = pnode->node_psym;
sym_t *vsym = makesym();
long rc;
int i;
#ifdef EVEREST
char *fnnamep = NULL;
int bufndx;
#endif
#if defined(STKDEBUG)
uint _SP = get_sp();
if (cpied && (cp_dcache_size != _dcache_size)) {
msg_printf(JUST_DOIT,
"!!!??eval: cp_size 0x%x _dc_size 0x%x cpied %d: sp 0x%x\n",
cp_dcache_size, _dcache_size, cpied, _SP);
cp_dcache_size = _dcache_size;
}
#ifdef NOTNOW
if (_SP <= bos) {
msg_printf(IDE_ERR,
"docmd: stack overflow!!! (tos 0x%x bos 0x%x sp 0x%x)\n",
tos, bos, _SP);
} else if (_SP <= safe_sp) {
msg_printf(JUST_DOIT,
" !!docmd warning: < 0x%x bytes of stack remain:\n",
(safe_sp-bos));
msg_printf(JUST_DOIT, " tos 0x%x bos 0x%x sp 0x%x)\n",
tos, bos, _SP);
}
#endif /* NOTNOW */
#endif /* STKDEBUG */
ccontext = *context;
if ( rc = setjmp(ccontext.rframe) ) {
--rc;
goto exit;
}
ccontext.argc = makeargv(context,pnode->node_right,&ccontext.argv[1])+1;
ccontext.argv[0] = cmd;
if ( cmd->sym_flags & SYM_UDEF ) {
#if defined(STKDEBUG)
if (doset_wwatch && !did_set_wwatch) {
__psunsigned_t k1addr = (__psunsigned_t)&_dcache_size;
__psunsigned_t paddr = K1_TO_PHYS(k1addr);
msg_printf(DBG, " eval, udef command:\n");
msg_printf(DBG,
"&_dc_size 0x%Lx; val 0x%x cp_ 0x%x, sp 0x%x\n",
paddr, _dcache_size, cp_dcache_size, _SP);
msg_printf(DBG,
" set store-watchpt at paddr 0x%x\n", paddr);
set_watch(paddr, WATCHLO_WTRAP);
did_set_wwatch = 1;
}
#endif /* STKDEBUG */
dotree(&ccontext, cmd->sym_stmt);
} else
if ( cmd->sym_flags & SYM_CHARARGV ) {
char *argv[MAXARGC+1];
#ifdef OPTION_DEBUG
if (Reportlevel & OPTVDBG) {
int i;
msg_printf(DBG+4, " docmd, sym_charargv!\n");
for (i = 0; i < ccontext.argc; i++) {
msg_printf(DBG+4, "\n argv[%d]: ",i);
if (Reportlevel >= DBG)
_dumpsym(ccontext.argv[i]);
}
msg_printf(DBG+4, "\n");
}
#endif
argv[0] = cmd->sym_name;
#ifdef EVEREST
fnnamep = argv[0];
#endif
for ( i = 1; i < ccontext.argc; i++ ) {
ccontext.argv[i] = pro_str(ccontext.argv[i]);
argv[i] = ccontext.argv[i]->sym_s;
}
argv[ccontext.argc] = 0;
#if SET_DEBUG
if (_SHOWIT(EVAL_DBG|DBG+4)) {
msg_printf(JUST_DOIT,
"\n docmd(char): ccntxt.argc %d\n argvs: ",
ccontext.argc);
for ( i = 0; i < ccontext.argc; i++ ) {
msg_printf(JUST_DOIT," %d=\"%s\"",
i, _SAFESTR(argv[i]));
}
msg_printf((EVAL_DBG|DBG+4), "\n");
}
#endif
rc = ide_dispatch(cmd->sym_func, ccontext.argc, argv);
} else { /* args in sym_t * format */
#ifdef EVEREST
fnnamep = ccontext.argv[0]->sym_name;
#endif
#if SET_DEBUG
if (_SHOWIT(EVAL_DBG|DBG+4)) {
msg_printf(JUST_DOIT,
"\n docmd(sym_t): ccntxt.argc %d\n argvs: ",
ccontext.argc);
for ( i = 0; i < ccontext.argc; i++ ) {
sym_t *tsym = ccontext.argv[i];
if (tsym->sym_basetype == SYMB_STR) {
msg_printf(JUST_DOIT,
" (%d) \"%s\"", i, _SAFESTR(tsym->sym_s));
} else {
msg_printf(JUST_DOIT,
" (%d) 0x%x (bt%d,t %d) ", i, tsym->sym_i,
tsym->sym_basetype, tsym->sym_type);
}
}
msg_printf(JUST_DOIT, "\n");
}
#endif /* SET_DEBUG */
#if EVEREST
if (ID_DIAG(cmd->sym_flags)) {
msg_printf(SUM, " %s: ",fnnamep);
}
bufndx = IDE_ME(putbufndx);
#endif /* EVEREST */
rc = (*cmd->sym_func)(ccontext.argc, (void **)ccontext.argv);
#if EVEREST
if (ID_DIAG(cmd->sym_flags)) {
char *test_result;
switch (rc) {
case TEST_PASSED:
test_result = "PASSED";
break;
case TEST_SKIPPED:
test_result = "SKIPPED";
break;
default:
test_result = "FAILED";
}
msg_printf(JUST_DOIT, "%s%s",
(bufndx == (IDE_ME(putbufndx)) ? " -- " : "\n "),
test_result);
if (Reportlevel > SUM)
msg_printf(SUM, ": returned %d\n",rc);
else
msg_printf(SUM, "\n");
}
#endif /* EVEREST */
}
exit:
for ( i = 1; i < ccontext.argc; i++ )
destroysym(ccontext.argv[i]);
vsym->sym_basetype = SYMB_INT;
vsym->sym_type = SYM_CON;
vsym->sym_i = rc;
return vsym;
} /* fn docmd */
/*
* build up an argv for a command
*
*/
/*ARGSUSED3*/
static int
makeargv(context_t *context, node_t *pnode, sym_t **argv)
{
int argc;
if ( ! pnode )
return 0;
argc = makeargv( context, pnode->node_right, argv );
if ( argc < MAXARGC )
argv[argc++]= eval( context, pnode->node_left );
return argc;
}
/*
* doif - Do an if-then-else statement
*
*/
void
doif(context_t *context, node_t *pnode)
{
sym_t *tmp = pro_int(eval(context, pnode->node_left));
us_delay (MS1); /* LATER */
if ( pnode->node_right && pnode->node_right->node_type == OP_ELSE ) {
if ( tmp->sym_i )
dotree(context,pnode->node_right->node_left);
else
dotree(context,pnode->node_right->node_right);
}
else
if ( tmp->sym_i)
dotree(context,pnode->node_right);
destroysym(tmp);
}
/*
* dorepeat - do a repeat loop
*
*/
void
dorepeat(context_t *context, node_t *pnode)
{
ide_int_type tmp;
tmp = pnode->node_psym->sym_i;
if ( tmp )
while( tmp-- )
dotree(context, pnode->node_right);
else
while( 1 )
dotree(context, pnode->node_right);
}
/*
* dowhile - do a while loop
*
*/
void
dowhile(context_t *context, node_t *pnode)
{
sym_t *tmp;
int done = 0;
do {
tmp = pro_int(eval(context, pnode->node_left));
if ( tmp->sym_i ) {
context_t lcontext;
int s;
lcontext = *context;
if ( s = setjmp( lcontext.lframe ) ) {
if ( s == 2 ) /* break */
done = 1;
}
else
dotree(&lcontext, pnode->node_right);
}
else
done = 1;
destroysym(tmp);
} while(!done);
}
/*
* dofor - do a for loop
*
*/
void
dofor(context_t *context, node_t *pnode)
{
node_t *pre;
node_t *con;
node_t *end;
node_t *bod;
sym_t *tmp;
context_t lcontext;
int s;
pre = pnode->node_left->node_left;
con = pnode->node_left->node_right;
end = pnode->node_right->node_left;
bod = pnode->node_right->node_right;
if (pre) destroysym(eval(context,pre));
do {
if ( con ) {
tmp = pro_int(eval(context, con));
if ( ! tmp->sym_i ) {
destroysym(tmp);
break;
}
destroysym(tmp);
}
lcontext = *context;
if ( s = setjmp( lcontext.lframe ) ) {
if ( s == 2 ) /* break */
break;
}
else
dotree(&lcontext, bod);
if ( end )
destroysym(eval(context, end));
} while (1);
}
/*
* doreturn - return statement
*
*/
void
doreturn(context_t *context, node_t *pnode)
{
sym_t *rsym;
int rc;
if (pnode->node_right) {
rsym = pro_int(eval(context,pnode->node_right));
rc = (int)rsym->sym_i;
destroysym(rsym);
}
else
rc = 0;
longjmp(context->rframe, rc+1);
/*NOTREACHED*/
}
/*
* dodo - do a do loop
*
*/
void
dodo(context_t *context, node_t *pnode)
{
sym_t *tmp;
int done = 0;
context_t lcontext;
int s;
do {
lcontext = *context;
if ( s = setjmp( lcontext.lframe ) ) {
if ( s == 2 ) { /* break = 2 */
done = 1;
destroysym(tmp);
break;
}
/* continue = 1 */
}
else
dotree(&lcontext, pnode->node_right);
tmp = pro_int(eval(context, pnode->node_left));
if ( !tmp->sym_i )
done = 1;
destroysym(tmp);
} while(!done);
}
void
doswitch(context_t *context, node_t *pnode)
{
context_t scontext;
ide_int_type val;
sym_t *psym = pro_int(eval(context, pnode->node_left));
val = psym->sym_i;
destroysym(psym);
scontext = *context;
if ( setjmp(scontext.lframe) )
return; /* break */
if (!findcase(&scontext, val, pnode->node_right, 0))
findcase(&scontext, val, pnode->node_right, 1);
}
int
findcase(context_t *context, ide_int_type val, node_t *pnode, int flag)
{
int found = 0;
if ( ! pnode )
return 0;
if ( pnode->node_type == OP_CASELIST ) {
found = findcase(context, val, pnode->node_right, flag);
pnode = pnode->node_left;
}
if ( ! found ) {
if ( flag && pnode->node_psym )
return 0;
if (!flag && !pnode->node_psym )
return 0; /* hit default case but still looking */
if (!flag && pnode->node_psym->sym_i != val)
return 0;
}
dotree(context, pnode->node_right);
return 1;
}
void
doprint(context_t *context, node_t *pnode)
{
char setbuffer[SETBUFSIZ];
sym_t *tmp = eval(context, pnode->node_right);
if ( pnode->node_psym )
msg_printf(JUST_DOIT, pnode->node_psym->sym_s, tmp->sym_i);
else
switch( tmp->sym_basetype ) {
case SYMB_INT:
msg_printf(JUST_DOIT, "INT value = %d\n", tmp->sym_i );
break;
case SYMB_STR:
msg_printf(JUST_DOIT, "STRing = \"%s\"\n", tmp->sym_s );
break;
case SYMB_SET:
_dumpsym(tmp);
sprintf_cset(setbuffer, tmp->sym_set);
msg_printf(JUST_DOIT, "SET = lx%Lx: (%s)\n",
tmp->sym_set, setbuffer);
#if PRO_DEBUG
msg_printf(JUST_DOIT, "or: ");
tmp = pro_setstr(tmp);
_dumpsym(tmp);
#endif
break;
case SYMB_SETSTR:
msg_printf(JUST_DOIT, "SETSTR = \"%s\"\n",
tmp->sym_s );
break;
case SYMB_RANGE:
msg_printf(JUST_DOIT,"range: start 0x%x, count 0x%x\n",
tmp->sym_start, tmp->sym_count);
break;
case SYMB_FREE:
msg_printf(JUST_DOIT,"symbol is unallocated\n");
break;
case SYMB_UNDEFINED:
msg_printf(JUST_DOIT,
"symbol is allocated, but basetype is undefined\n");
break;
case SYMB_BADVAL:
msg_printf(JUST_DOIT,
"symbol basetype was flagged as invalid\n");
break;
default:
msg_printf(IDE_ERR,
"doprint, bad basetype %d=0x%x, (type %d)\n",
tmp->sym_basetype, tmp->sym_basetype,
tmp->sym_type );
break;
}
destroysym(tmp);
}
/*
* eval - expression evaluator
*
* This is the heart of the ide interpreter. Given an expression
* tree this routine returns a symbol record containing the result
* of the evaluation. The symbol returned is a temporary symbol and
* should be destroyed after it is used.
*/
sym_t *
eval(context_t *context, node_t *pnode)
{
sym_t *rsym;
sym_t *lsym;
sym_t *vsym;
us_delay(MS1); /* LATER */
#ifdef EVAL_DEBUG
msg_printf((EVAL_DBG|DBG+4), "begin eval: nodetype %d:\n",
pnode->node_type);
#endif
switch ( pnode->node_type ) {
/* VAR node types: parameters and legit cases for all 4 basetypes */
case OP_VAR:
lsym = pnode->node_psym;
vsym = makesym();
if (_SHOWIT(EVAL_DBG|DBG+4)) {
/* */ msg_printf(JUST_DOIT,
/* */ " +++Top of OP_VAR, lsym(@ 0x%x): ", (__psunsigned_t)lsym);
_dumpsym(lsym);
}
if ( lsym->sym_type == SYM_PARAM ) {
/* */ msg_printf((EVAL_DBG|DBG+4),
" !+++- SYM_PARAM: -> %s <--\n",
(inrawcmd ? "RAW mode" : "COOKED mode"));
/* `$$' (==argc including argv[0], unlike csh's `$$' */
if ( lsym->sym_indx == MAXARGC+1 ) {
ASSERT(lsym->sym_type == SYM_PARAM);
/* */ msg_printf((EVAL_DBG|DBG+4)," #PARM: $$ ");
vsym->sym_basetype = SYMB_INT;
vsym->sym_type = SYM_VAR;
vsym->sym_i = context->argc;
break;
}
else /* $n where n > argc */
if ( lsym->sym_indx >= context->argc ) {
ASSERT(lsym->sym_type == SYM_PARAM);
/* */ msg_printf((EVAL_DBG|DBG+4), " #PARM: $n > argc ");
vsym->sym_basetype = SYMB_STR;
vsym->sym_type = SYM_VAR;
vsym->sym_s = makestr("");
break;
}
else { /* $n where n <= argc */
ASSERT(lsym->sym_type == SYM_PARAM);
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " #PARM: n <= argc; (idx %d)\n",lsym->sym_indx);
lsym = context->argv[lsym->sym_indx];
}
} /* if SYM_PARAM */
/* */ if (_SHOWIT(EVAL_DBG|DBG+4)) {
/* */ msg_printf((EVAL_DBG|DBG+4)," P+++post SYMPAR: lsym: ");
/* */ _dumpsym(lsym);
/* */ msg_printf((EVAL_DBG|DBG+4)," P+++: and vsym: ");
/* */ _dumpsym(vsym);
/* */ }
/* 5 legal basetypes */
switch (lsym->sym_basetype) {
case SYMB_STR:
vsym->sym_s = makestr(lsym->sym_s);
ASSERT(vsym->sym_s);
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " >1 eval:type OP_VAR bt STR (l:\"%s\" v:\"%s\")\n",
/* */ _SAFESTR(lsym->sym_s), _SAFESTR(vsym->sym_s));
break;
case SYMB_SETSTR:
vsym->sym_s = makestr(lsym->sym_s);
ASSERT(vsym->sym_s);
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " >2 eval:t OP_VAR bt SETSTR (l:\"%s\" v:\"%s\")\n",
/* */ _SAFESTR(lsym->sym_s), _SAFESTR(vsym->sym_s));
break;
case SYMB_RANGE:
vsym->sym_start = lsym->sym_start;
vsym->sym_count = lsym->sym_count;
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " >3 eval: OP_VAR bt RNG:lstart %d, vstart %d\n",
/* */ lsym->sym_start, vsym->sym_start);
break;
case SYMB_INT:
vsym->sym_i = lsym->sym_i;
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " >4 eval: OP_VAR, bt INT lval %d vval\n",
/* */ lsym->sym_i, vsym->sym_i);
break;
case SYMB_SET:
vsym->sym_set = lsym->sym_set;
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " >5 eval: OP_VAR, bt SET(l: lx%Lx, v: lx%Lx)\n",
/* */ lsym->sym_set, vsym->sym_set);
break;
default: /* unknown basetype */
/* */ msg_printf(IDE_ERR,
/* */ "!! >XXX 77 eval OP_VAR: bad lsym b-type (%d)\n",
/* */ lsym->sym_basetype);
/* */ msg_printf(JUST_DOIT,
/* */ " >X88 lsym type %d, val 0x%x or \"%s\"\n",
/* */ lsym->sym_type,lsym->sym_i,_XSAFESTR(lsym->sym_s));
_dumpsym(lsym);
destroysym(lsym);
#ifdef EXTREME_METHOD
psignal(SIGINT);
/*NOTREACHED*/
#else
/* */ msg_printf(JUST_DOIT,
">!!! SET BADFLAG, default case of OP_VAR\n");
badflag = 1;
vsym->sym_basetype = SYMB_BADVAL;
vsym->sym_type = SYM_BADVAL;
vsym->sym_i = 0xdeadbeef;
break;
#endif
} /* lsym->sym_basetype switch */
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_type = SYM_VAR;
/* */ if (_SHOWIT(EVAL_DBG|DBG+4)) {
/* */ msg_printf(JUST_DOIT,
"+++>7 END OP_VAR, vsym (addr 0x%x): ",(__psunsigned_t)vsym);
/* */ _dumpsym(vsym);
/* */ }
break;
case OP_ADD:
rsym = eval(context, pnode->node_right);
lsym = eval(context, pnode->node_left);
vsym = makesym();
ASSERT(rsym->sym_basetype != SYMB_SET);
if ( rsym->sym_basetype == SYMB_STR &&
lsym->sym_basetype == SYMB_STR ) {
vsym->sym_basetype = SYMB_STR;
vsym->sym_s = talloc( strlen(rsym->sym_s)+
strlen(lsym->sym_s) + 1 );
strcpy( vsym->sym_s, lsym->sym_s );
strcat( vsym->sym_s, rsym->sym_s );
}
else {
rsym = pro_int(rsym);
lsym = pro_int(lsym);
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i + rsym->sym_i;
}
destroysym(rsym);
destroysym(lsym);
break;
case OP_SUB:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i - rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_MUL:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i * rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_DIV:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
if ( rsym->sym_i == 0 )
vsym->sym_i = DIV0RESULT;
else
vsym->sym_i = lsym->sym_i / rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_MOD:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
if ( rsym->sym_i == 0 )
vsym->sym_i = DIV0RESULT;
else
vsym->sym_i = lsym->sym_i % rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_OR:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i | rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_AND:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i & rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_XOR:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i ^ rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_COM: /* complement */
rsym = pro_int(eval(context, pnode->node_right));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = ~rsym->sym_i;
destroysym(rsym);
break;
case OP_NOT: /* logical not */
rsym = pro_int(eval(context, pnode->node_right));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
if ( rsym->sym_i )
vsym->sym_i = 0;
else
vsym->sym_i = 1;
destroysym(rsym);
break;
case OP_ANDAND:
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
/* C evaluation semantics */
if ( lsym->sym_i ) {
rsym = pro_int(eval(context,pnode->node_right));
if ( rsym->sym_i )
vsym->sym_i = 1;
destroysym(rsym);
}
else
vsym->sym_i = 0;
destroysym(lsym);
break;
case OP_OROR:
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
/* C evaluation semantics */
if ( ! lsym->sym_i ) {
rsym = pro_int(eval(context,pnode->node_right));
if ( rsym->sym_i )
vsym->sym_i = 1;
destroysym(rsym);
}
else
vsym->sym_i = 1;
destroysym(lsym);
break;
case OP_LT:
case OP_LE:
case OP_GT:
case OP_GE:
case OP_EQ:
case OP_NE:
{
ide_int_type i;
rsym = eval(context, pnode->node_right);
lsym = eval(context, pnode->node_left);
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
if ( rsym->sym_basetype == SYMB_STR &&
lsym->sym_basetype == SYMB_STR )
i = strcmp(lsym->sym_s, rsym->sym_s);
else {
rsym = pro_int(rsym);
lsym = pro_int(lsym);
i = lsym->sym_i - rsym->sym_i;
}
switch(pnode->node_type) {
case OP_EQ:
vsym->sym_i = (i == 0);
break;
case OP_NE:
vsym->sym_i = (i != 0);
break;
case OP_GT:
vsym->sym_i = (i > 0);
break;
case OP_LT:
vsym->sym_i = (i < 0);
break;
case OP_GE:
vsym->sym_i = (i >= 0);
break;
case OP_LE:
vsym->sym_i = (i <= 0);
break;
}
destroysym(rsym);
destroysym(lsym);
}
break;
case OP_POSTD:
lsym = pnode->node_psym;
if ( lsym->sym_basetype == SYMB_STR ) {
destroystr(lsym->sym_s);
lsym->sym_s = NULL;
}
lsym->sym_basetype = SYMB_INT;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i--;
break;
case OP_POSTI:
lsym = pnode->node_psym;
if ( lsym->sym_basetype == SYMB_STR ) {
destroystr(lsym->sym_s);
lsym->sym_s = NULL;
}
lsym->sym_basetype = SYMB_INT;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i++;
break;
case OP_PRED:
lsym = pnode->node_psym;
if ( lsym->sym_basetype == SYMB_STR ) {
destroystr(lsym->sym_s);
lsym->sym_s = NULL;
}
lsym->sym_basetype = SYMB_INT;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = --lsym->sym_i;
break;
case OP_PREI:
lsym = pnode->node_psym;
if ( lsym->sym_basetype == SYMB_STR ) {
destroystr(lsym->sym_s);
lsym->sym_s = NULL;
}
lsym->sym_basetype = SYMB_INT;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = ++lsym->sym_i;
break;
case OP_SHL:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i << rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_SHR:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pro_int(eval(context, pnode->node_left));
vsym = makesym();
vsym->sym_basetype = SYMB_INT;
vsym->sym_i = lsym->sym_i >> rsym->sym_i;
destroysym(rsym);
destroysym(lsym);
break;
case OP_ASSIGN:
rsym = eval(context, pnode->node_right);
lsym = pnode->node_psym;
#ifdef EVAL_DEBUG
/* */ if (Reportlevel >= DBG+4 || (Reportlevel & EVAL_DBG)) {
msg_printf((EVAL_DBG|DBG+4),
" ***OP_ASS TOP: nodetype %d:\n",
pnode->node_type);
msg_printf((EVAL_DBG|DBG+4),
" ***OP_ASS: RIGHTSYM: -> ");
_dumpsym(rsym);
msg_printf((EVAL_DBG|DBG+4),
" *** OP_ASS: LEFTSYM: -> ");
_dumpsym(lsym);
}
#endif /* EVAL_DEBUG */
if (lsym->sym_basetype == SYMB_STR ||
lsym->sym_basetype == SYMB_SETSTR) {
destroystr(lsym->sym_s);
lsym->sym_s = NULL;
}
if ( lsym->sym_type == SYM_GLOBAL ) {
if (_SHOWIT(EVAL_DBG|DBG+4)) {
msg_printf((EVAL_DBG|DBG+4),
"**** CALLING set_global; LEFTsym:\n");
_dumpsym(lsym);
msg_printf((EVAL_DBG|DBG+4),"RIGHTsym:\n");
_dumpsym(rsym);
}
set_global(lsym, rsym);
} else {
switch (rsym->sym_basetype) {
case SYMB_INT:
lsym->sym_basetype = SYMB_INT;
lsym->sym_i = rsym->sym_i;
break;
case SYMB_STR:
lsym->sym_basetype = SYMB_STR;
lsym->sym_s = makestr(rsym->sym_s);
break;
case SYMB_SETSTR:
lsym->sym_basetype = SYMB_SETSTR;
lsym->sym_s = makestr(rsym->sym_s);
break;
case SYMB_SET:
lsym->sym_basetype = SYMB_SET;
lsym->sym_set = rsym->sym_set;
break;
default:
msg_printf(IDE_ERR,
"eval OP_ASS: bad rsym btype %d:\n",
rsym->sym_basetype);
_dumpsym(rsym);
break;
}
if (_SHOWIT(EVAL_DBG|DBG+4)) {
msg_printf(JUST_DOIT,
"pre-destroy: RIGHTsym:\n");
_dumpsym(rsym);
}
destroysym(rsym);
}
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_type = lsym->sym_type;
if (lsym->sym_basetype == SYMB_STR ||
lsym->sym_basetype == SYMB_SETSTR)
vsym->sym_s = makestr(lsym->sym_s);
else
if (lsym->sym_basetype == SYMB_SET)
vsym->sym_set = lsym->sym_set;
else
vsym->sym_i = lsym->sym_i;
/* */ if (_SHOWIT(EVAL_DBG|DBG+4)) {
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " ****>END OP_ASS, vsym (@0x%x): ", vsym);
_dumpsym(vsym);
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " ****>lsym (@0x%x): ", lsym);
_dumpsym(lsym);
}
break;
case OP_SUBASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i -= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_ADDASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i += rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_MULASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i *= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_DIVASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
if ( rsym->sym_i == 0 )
lsym->sym_i = DIV0RESULT;
else
lsym->sym_i /= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_MODASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
if ( rsym->sym_i == 0 )
lsym->sym_i = DIV0RESULT;
else
lsym->sym_i %= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_SHLASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i <<= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_SHRASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i >>= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_ANDASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i &= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_ORASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i |= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_XORASS:
rsym = pro_int(eval(context, pnode->node_right));
lsym = pnode->node_psym;
lsym->sym_basetype = SYMB_INT;
lsym->sym_i ^= rsym->sym_i;
vsym = makesym();
vsym->sym_basetype = lsym->sym_basetype;
vsym->sym_i = lsym->sym_i;
destroysym(rsym);
break;
case OP_CMD:
vsym = docmd(context,pnode);
break;
default:
vsym = makesym();
vsym->sym_basetype = SYMB_BADVAL;
vsym->sym_type = SYM_BADVAL;
msg_printf(IDE_ERR, "eval default: bad node type %d\n",
pnode->node_type);
break;
} /* switch pnode->node_type */
/* */ if (_SHOWIT(EVAL_DBG|DBG+4)) {
/* */ msg_printf((EVAL_DBG|DBG+4),
/* */ " bottom of eval, vsym (@0x%x): ", vsym);
/* */ _dumpsym(vsym);
/* */ }
return vsym;
} /* eval */