|
#include <stdio.h> |
|
#include <string.h> |
|
#include <assert.h> |
|
FILE *in; long M[1<<24]={0}, *D, *R, H=0x130000, IP=0, T; |
|
long getu() { long t, h = getc(in); if (h < 0xC0) return h; |
|
t = ((h&0x1F) << 6) | (getc(in) & 0x3F); if (h < 0xE0) return t; |
|
t = ( t << 6) | (getc(in) & 0x3F); if (h < 0xF0) return t; |
|
t = ( t << 6) | (getc(in) & 0x3F); return t & 0x1FFFFF; } |
|
void putu(long c) { if (c < 0x80) { putchar(c); return; } |
|
if (c < 0x7FF) { putchar(0xC0|(c>>6)); } else { |
|
if (c < 0x10000) { putchar(0xE0|(c>>12)); } else { |
|
putchar(0xF0 | (c>>18)); putchar(0x80 | ((c>>12) & 0x3F)); } |
|
putchar(0x80 | ((c>>6) & 0x3F)); } putchar(0x80 | (c & 0x3F)); } |
|
int main(int argc, char** argv) { D = M + 0x120000; R = D + 0x1000; |
|
for (int i = 1; i < argc; i++) { in = fopen(argv[i], "r"); |
|
assert(in); long OP = getu(); while(OP >= 0) { switch (OP) { |
|
case 0xFF3B: *--D = H; while ((OP = getu()) != 0xFF3D) |
|
{ assert(OP>0); M[H++]=OP; } M[H++]=0; break; /* []quote */ |
|
case 0x3060: M[D[1]] = D[0]; D += 2; break; /* だ is */ |
|
case 0x51fa: case 0: IP = *R++; break; /* 出 exit */ |
|
case 0x5199: D--; D[0] = D[1]; break; /* 写 dup */ |
|
case 0x6368: D++; break; /* 捨 drop */ |
|
case 0x787b: T=D[0]; D[0]=D[1]; D[1]=T; break; /* 移 swap */ |
|
case 0x8db3: D[1] += D[0]; D++; break; /* 足 add */ |
|
case 0x5f15: D[1] -= D[0]; D++; break; /* 引 sub */ |
|
case 0x639b: D[1] *= D[0]; D++; break; /* 掛 mul */ |
|
case 0x5272: D[1] /= D[0]; D++; break; /* 割 div */ |
|
case 0x6b8b: D[1] %= D[0]; D++; break; /* 残 mod */ |
|
case 0x540c: D[1] = (D[1] == D[0]); D++; break; /* 同 equal */ |
|
case 0x4e0b: D[1] = (D[1] < D[0]); D++; break; /* 下 less */ |
|
case 0x4e00: *--D = 1; break; /* 一 one */ |
|
case 0x8aad: *--D = getu(); break; /* 読 read */ |
|
case 0x66f8: putu(*D++); break; /* 書 write */ |
|
case 0x6570: printf("%ld ", *D++); break; /* 数 count */ |
|
case 0x5b57: *--D = IP?M[IP++]:getu(); break; /* 字 char */ |
|
case 0x6b64: *--D = H; break; /* 此 here */ |
|
case 0x3067: H = *D++; break; /* で at */ |
|
case 0x8a18: M[H++] = *D++; break; /* 記 note */ |
|
default: if (OP < 128) break; /* ignore ascii */ |
|
*--R = IP; IP=M[OP]; assert(IP); /* perform call */ |
|
} OP = IP ? M[IP++] : getu(); } } } |