/* a ridiculously simplified "virtual machine" */ #include #include /* convert four int8_t values into a single int32_t value */ static int32_t bytes_to_int(int8_t a, int8_t b, int8_t c, int8_t d) { return (((int32_t)a & 0xff) << 0) | (((int32_t)b & 0xff) << 8) | (((int32_t)c & 0xff) << 16) | (((int32_t)d & 0xff) << 24); } /* the stack of the virtual machine */ int32_t stack [256]; /* the interpreter for the vm */ /* FREESTYLE OPTIMIZATIONS */ int vm(const char *insns) { int pc = 0; int sp = 0; while (insns[pc] != '\0') { int8_t op = insns[pc]; int32_t t; printf("pc: %d op: %c\n", pc, op); /* putchar(op); */ /* printf(" %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */ /* pc, sp, */ /* stack[0], stack[1], stack[2], stack[3], */ /* stack[4], stack[5], stack[6], stack[7]); */ switch (op) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': stack[sp] = op-'0'; sp++; break; case 'I': /* immediate */ stack[sp] = bytes_to_int(insns[pc+1], insns[pc+2], insns[pc+3], insns[pc+4]); pc += 4; sp++; break; case 'D': /* dup */ stack[sp] = stack[sp-1]; sp++; break; case 'X': /* exchange */ t = stack[sp-1]; stack[sp-1] = stack[sp-2]; stack[sp-2] = t; break; case 'P': /* pop */ sp--; break; case '+': /* add */ sp--; stack[sp-1] = stack[sp-1] + stack[sp]; break; case '-': /* subtract */ sp--; stack[sp-1] = stack[sp-1] - stack[sp]; break; case '*': /* multiply */ sp--; stack[sp-1] = stack[sp-1] * stack[sp]; break; case '~': /* not */ stack[sp-1] = ~stack[sp-1]; break; case '<': /* less than */ sp--; stack[sp-1] = stack[sp-1] < stack[sp] ? -1 : 0; break; case 'J': /* jump if true */ sp--; if (stack[sp] != 0) { pc += (int8_t)insns[pc+1]; } else { pc++; } break; default: /* ignore everything else */ break; } pc++; } /* printf(" %d/%d:\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\t%08x\n", */ /* pc, sp, */ /* stack[0], stack[1], stack[2], stack[3], */ /* stack[4], stack[5], stack[6], stack[7]); */ return stack[sp-1]; } int main() { /* BENCHMARK START */ /* you don't need to understand that code, the answer is '6' */ int retval = vm( "48*88*\ X1-X\ D+\ DJ\xf8\ P68*+\ DI\040\0\0\0\ <~J\005\ P88*"); /* BENCHMARK END */ putchar(retval); return retval; }