/* $Header: /belch_a/users/rearl/tinymuck/src/RCS/inst.c,v 1.9 90/09/28 12:26:25 rearl Exp $ */
/*
* $Log: inst.c,v $
* Revision 1.9 90/09/28 12:26:25 rearl
* Added hack to prevent direct call of JMP or PROGRAM words, added
* shared program strings.
*
* Revision 1.8 90/09/18 07:57:35 rearl
* Changed the primitive table to work with the hash functions.
*
* Revision 1.7 90/09/13 06:24:14 rearl
* Changed some erroneous primitive strings, added PUT and EXECUTE.
*
* Revision 1.6 90/09/05 02:32:04 rearl
* Changed order of stack dump to actually reflect the stack...
*
* Revision 1.5 90/08/27 03:26:09 rearl
* Changed P's to ?'s, added INSTR, RINSTR, OK? TIME.
*
* Revision 1.4 90/08/11 04:02:32 rearl
* *** empty log message ***
*
* Revision 1.3 90/07/29 23:45:53 rearl
* Added string primitives: strncmp, strcut, strlen.
*
* Revision 1.2 90/07/29 17:34:50 rearl
* Added debugging code, also new primitives such as PRONOUN_SUB.
*
* Revision 1.1 90/07/19 23:03:40 casie
* Initial revision
*
*
*/
#include "copyright.h"
#include "config.h"
#include "db.h"
#include "inst.h"
#include "externs.h"
#include "interface.h"
#include "strings.h"
/* these arrays MUST agree with what's in inst.h */
const char *base_inst[] = {
"IF", /* 1 */
"+",
"-",
"*",
"/", /* 5 */
"POP",
"DUP",
"CALL",
"NUMBER?",
"STRCMP", /* 10 */
"STRINGCMP",
"STRCAT",
"ATOI",
"AND",
"OR", /* 15 */
"NOT",
"READ",
"NOTIFY",
"NOTIFY_EXCEPT",
"EXIT", /* 20 */
"JMP ",
"ADDPENNIES",
"@",
"!",
"GETPROPVAL", /* 25 */
"GETPROPSTR",
"SETPROP",
"REMOVE_PROP",
"MOVETO",
"PENNIES", /* 30 */
"<",
">",
"=",
"<=",
">=", /* 35 */
"RANDOM",
"%",
"INTOSTR",
"DBCMP",
"DBREF", /* 40 */
"INT",
"VARIABLE",
"SWAP",
"CONTENTS",
"NAME", /* 45 */
"SETNAME",
"EXPLODE",
"MATCH",
"COPYOBJ",
"SUBST", /* 50 */
"SET",
"LOCATION",
"PLAYER?",
"THING?",
"ROOM?", /* 55 */
"PROGRAM?",
"EXIT?",
"FLAG?",
"OWNER",
"RMATCH", /* 60 */
"OVER",
"PICK",
"PUT",
"ROT",
"ROTATE", /* 65 */
"GETLINK",
"PRONOUN_SUB",
"STRNCMP",
"STRCUT",
"STRLEN", /* 70 */
"INSTR",
"RINSTR",
"OK?",
"TIME",
"EXECUTE", /* 75 */
"EXITS",
"NEXT",
"PROGRAM ",
"ONLINE",
"AWAKE?", /* 80 */
"CONBOOT",
"CONCOUNT",
"CONDBREF",
"CONHOST",
"CONIDLE", /* 85 */
"CONNECTIONS",
"CONTIME",
"STRINGNCMP",
"PROG",
"SELF", /* 90 */
"SYSTIME",
"STRFTIME",
"DEPTH",
"WILD_MATCH",
"PRONOUN_EVAL",
"CHECKFUNC", /* 95 */
"HALT",
"TRIGOBJ",
};
/* converts an instruction into a printable string, stores the string in
an internal buffer and returns a pointer to it */
char *insttotext(struct inst *theinst)
{
static char buffer[64];
switch(theinst->type) {
case PROG_PRIMITIVE:
if (theinst->data.number >= BASE_MIN &&
theinst->data.number <= BASE_MAX)
strcpy(buffer,base_inst[theinst->data.number-BASE_MIN]);
else strcpy(buffer,"???");
break;
case PROG_STRING:
if (!theinst->data.string) {
strcpy(buffer, "\"\"");
break; }
sprintf(buffer,"\"%1.29s", theinst->data.string->data);
if (theinst->data.string->length<=30)
strcat(buffer,"\"");
else
strcat(buffer,"_");
break;
case PROG_INTEGER:
sprintf(buffer,"%d", theinst->data.number);
break;
case PROG_ADD:
strcpy(buffer, "addr");
break;
case PROG_OBJECT:
sprintf(buffer,"#%d", theinst->data.objref);
break;
case PROG_VAR:
sprintf(buffer,"V%d", theinst->data.number);
break;
case PROG_CON:
sprintf(buffer, "C%d", theinst->data.con->descriptor);
break;
default:
strcpy(buffer,"???");
break; }
return buffer;
}
/* produce one line summary of current state. Note that sp is the next
space on the stack -- 0..sp-1 is the current contents. */
char *debug_inst(struct inst *pc, struct inst *stack, int sp, dbref program)
{
static char buffer[512];
int count;
int i = (int) (pc - DBFETCH(program)->sp.program.code);
static dbref last;
if(program != last) {
sprintf(buffer, "#%-5d", (int) program);
last = program;
}
else
sprintf(buffer, "Debug ");
if(i < 0)
strcat(buffer, "[ RET ] S( ", (int) program);
else
sprintf(buffer, "%s[%5d] S( ", buffer, i);
if (sp > 5) strcat(buffer, "..., ");
count = (sp > 5) ? sp - 5 : 0;
while (count < sp) {
strcat(buffer, insttotext(stack + count));
if (++count < sp) strcat(buffer, ", ");
}
strcat(buffer, " ) ");
strcat(buffer, insttotext(pc));
return(buffer);
}