#include #include "defs.h" #include "prims.h" PRIM(atoi) { struct inst *v; int i; NARGS(1); v = TOS(0); if ((v->type != PROG_STRING) || !v->data.string) { i = 0; } else { i = atoi(v->data.string); } POP(1); MPUSH(PROG_INTEGER,i); } PRIM(intostr) { struct inst *v; char buf[sizeof(v->data)*CHAR_BIT]; NARGS(1); v = TOS(0); switch (v->type) { case PROG_INTEGER: case PROG_VAR: sprintf(&buf[0],"%d",v->data.number); break; case PROG_OBJECT: sprintf(&buf[0],"%d",v->data.objref); break; case PROG_FLOAT: sprintf(&buf[0],"%g",*v->data.flt); break; case PROG_QUAD: sprintf(&buf[0],"%s",mufquad_to_str(*v->data.quad)); break; default: ABORT_INTERP("Invalid argument."); break; } POP(1); MPUSH(PROG_STRING,dup_string(&buf[0])); } PRIM(dbref) { struct inst *v; dbref ref; NARGS(1); v = TOS(0); if (v->type != PROG_INTEGER) ABORT_INTERP("Non-integer argument."); ref = v->data.objref; POP(1); MPUSH(PROG_OBJECT,ref); } PRIM(int) { struct inst *v; int i; NARGS(1); v = TOS(0); switch (v->type) { case PROG_OBJECT: i = v->data.objref; break; case PROG_VAR: i = v->data.number; break; case PROG_INTEGER: return; break; default: ABORT_INTERP("Invalid argument type."); break; } POP(1); MPUSH(PROG_INTEGER,i); } PRIM(variable) { struct inst *v; int n; NARGS(1); v = TOS(0); if (v->type != PROG_INTEGER) ABORT_INTERP("Non-integer argument."); n = v->data.number; if ((n < 0) || (n >= MAX_VAR)) ABORT_INTERP("Argument out of range."); POP(1); MPUSH(PROG_VAR,n); } PRIM(ilimit) { STACKROOM(1); MPUSH(PROG_INTEGER,ilimit); } PRIM(setilimit) { struct inst *v; NARGS(1); v = TOS(0); if (v->type != PROG_INTEGER) ABORT_INTERP("Operand not an integer."); if (! PWIZARD) ABORT_INTERP("Permission denied."); if (v->data.number < ILIMIT_MIN) ABORT_INTERP("Operand too small."); ilimit = v->data.number; POP(1); } PRIM(atoq) { struct inst *v; MUFQUAD q; NARGS(1); v = TOS(0); if (v->type != PROG_STRING) ABORT_INTERP("Operand not a string."); q = str_to_mufquad(v->data.string); POP(1); MPUSH(PROG_QUAD,q); } PRIM(qtoa) { struct inst *v; MUFQUAD q; char *s; NARGS(1); v = TOS(0); switch (v->type) { case PROG_QUAD: q = *v->data.quad; break; case PROG_INTEGER: q = v->data.number; break; default: ABORT_INTERP("Invalid operand type."); break; } s = dup_string(mufquad_to_str(q)); POP(1); MPUSH(PROG_STRING,s); } PRIM(itoq) { struct inst *v; MUFQUAD q; NARGS(1); v = TOS(0); if (v->type != PROG_INTEGER) ABORT_INTERP("Operand not an integer."); if (v->data.number < 0) ABORT_INTERP("Operand is negative."); q = v->data.number; POP(1); MPUSH(PROG_QUAD,q); } PRIM(qtoi) { struct inst *v; MUFQUAD q; NARGS(1); v = TOS(0); switch (v->type) { case PROG_INTEGER: return; break; case PROG_QUAD: break; default: ABORT_INTERP("Invalid operand type."); } q = *v->data.quad; POP(1); MPUSH(PROG_INTEGER,(int)(q&0x7fffffff)); } PRIM(ftoq) { struct inst *v; MUFQUAD q; NARGS(1); v = TOS(0); if (v->type != PROG_FLOAT) ABORT_INTERP("Operand not a float."); if (*v->data.flt < 0) ABORT_INTERP("Operand is negative."); q = *v->data.flt; POP(1); MPUSH(PROG_QUAD,q); } PRIM(qtof) { struct inst *v; MUFQUAD q; NARGS(1); v = TOS(0); if (v->type != PROG_QUAD) ABORT_INTERP("Operand not a quad."); q = *v->data.quad; POP(1); MPUSH(PROG_FLOAT,(double)q); }