#include <cstdio>
#include <cstring>
int mem[65537] = {
}, st[16]; // mem 为虚拟机内存,共 64KB(懒得搞其他的了,直接拿 int 当 char 使吧)
int ip, sp;
// 内存中的下一个字节
#define NEXT_BYTE mem[(((ip += 1) &= 65535) - 1) & 65535]
// 栈顶
#define ST st[sp]
// 压栈
#define PUSH(d) (st[sp = (sp - 1) & 15] = d)
// 弹栈
#define POP(d) do {d = ST; sp = (sp + 1) & 15;} while (false)
// case-break 的简化
#define CASE(exp, dos) case exp: dos; break
// 内存操作数
#define OPMEM mem[NEXT_BYTE]
// 栈操作数
#define OPST st[(NEXT_BYTE + sp) & 15]
// 基本运算的统一形式
#define CALC(d, op, t) CASE(d, ST = (ST op t))
// 函数调用统一形式
#define FUNC(d, fun, t) CASE(d, ST = fun(ST, t))
// 运算指令集
#define CAFUSET(d, t) CALC(d, +, t);CALC(d + 1, -, t);CALC(d + 2, *, t);CALC(d + 3, /, t);FUNC(d + 4, xchg, t);FUNC(d + 5, gcd, t);FUNC(d + 6, quick_pow, t)
/*
0x00 end
0x01 out stack-top
0x02 read stack-top
0x03 push mem[a]
0x04 popstack -> mem
0x05 popstack -> null
0x06 stack-top += stack[i]
0x07 stack-top -= stack[i]
0x08 stack-top *= stack[i]
0x09 stack-top /= stack[i]
0x0A swap(stack-top, stack[i])
0x0B stack-top = gcd(stack-top, stack[i])
0x0C stack-top = pow(stack-top, stack[i])
0x0D stack-top += mem[i]
0x0E stack-top -= mem[i]
0x0F stack-top *= mem[i]
0x10 stack-top /= mem[i]
0x11 swap(stack-top, mem[i])
0x12 stack-top = gcd(stack-top, mem[i])
0x13 stack-top = pow(stack-top, mem[i])
0x14 goto a
0x15 goto stack[i]
0x16 if stack-top == 0 then goto a
0x17 push stack-top
0x18 out char(stack-top)
*/
// 交换
inline int xchg(int a, int& b)
{
int t;
t = b; b = a;
return t;
}
// 最大公约数(辗转相除法)
int gcd(int a, int b)
{
int r = a % b;
while (r)
{
a = b;
b = r;
r = a % b;
}
return a;
}
// 乘幂(二分法)
int quick_pow(int a, int b)
{
if (!b) return 1;
int k = quick_pow(a, b >> 1);
k *= k;
if (b & 1) k *= a;
return k;
}
// 从文件中读入内存初始值
void read_mem()
{
memset(mem, 0, sizeof mem);
FILE * fin = fopen("mem.in", "r");
int i;
for (i = 0; i < 65536 && !feof(fin); i++)
fscanf(fin, "%X", &mem[i]);
}
// 主函数
int main()
{
int now;
ip = sp = 0;
while (true)
{
now = NEXT_BYTE;
if (now == 0)
break;
switch (now)
{
CASE(1, printf("%d", ST));
CASE(2, scanf("%d", &ST));
CASE(3, PUSH(OPMEM));
CASE(4, POP(OPMEM));
CASE(5, POP(now));
CAFUSET(6, OPST);
CAFUSET(13, OPMEM);
CASE(20, ip = NEXT_BYTE);
CASE(21, ip = ST);
CASE(22, if (!ST) ip = NEXT_BYTE; else NEXT_BYTE);
CASE(23, now = ST; PUSH(now));
CASE(24, putchar(ST));
}
}
return 0;
}
/*
A + B Problem :
0x03,
0x02,
0x02,
0x17,
0x02,
0x06,
0x01,
0x01,
0x00
*/