/* hitomi0.c - Don Yang (uguu.org) Huffman encoder/decoder, huffman bytecode version. 10/21/01 */ #include #include /* btw: string too long for -pedantic */ static char *bytecode = ";O`WQIuxyp`QMGoJDQlp@>kpplZ>hZxWorS;KTfZoEuRUT[byFH[ciGl^QUGkN=DQB]R?G_DG?w]xpdf>YoEciiw@f]u;[um;JxRU;RXTibgoWJGCsRPpl?v>QXtKkJWjSHW>kyH[ubiSq>Ozo`>Oz;w]p@u>OzKgi?cXrXrXReCuXrypkBoygzM>yep_<]=Oau[_um;jxRUtImjoMmOB[ORJrw=mBGWn^fFA[ff^ZljeOfp`>OepZCQU;LMFA;EV`WAsxFH;?gJXxg_;`Sh<wy`QI?w^Qecv[xfbf[z;CqqUl;KXT;CsBFHkypN@Xr>eFNQH[pDOzKkylE?wNRecv;UXkBCqM@pXoBORAsxFHJk>ypD;SZuuoJ<;ORAsdzM>CENXT]Bho?]R?GcfiW;s@zuKgoGjv>Sefb>;jsxff>lMnwiR?G[diiSzuaJwc`axfFQQXXqfWjMxNNRJxLafon>lUNdbBd]wmLExwScbrU;WXl=WXXwNq>Uy;aumX_ZdTy?;NLefrNZu;"; #define OFFSET ';' enum { exec_while = 575, exec_if, exec_frame, end_bytecode }; enum { state_exec, state_getlabel, state_jmplabel, state_ignlabel, state_endbegin, state_exit, slabel_break, slabel_assignid, slabel_heappush, slabel_writebits }; static int ip, *sp, i, j, Memory[9][512], Register[14], Stack[512]; static int ExecState, ExecArg, pBytecode[7000]; static char *p, *String[3] = { "Decoded", "Encoded", "Empty file" }; static int Constant[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, -2, -3, 256 }; /*************************************************************** ProcLabel */ static void ProcLabel(int label) { if( ExecState == state_getlabel ) { *(++sp) = ip; *(++sp) = exec_frame; ExecArg = label; ExecState = state_jmplabel; } else if( ExecState == state_jmplabel ) { if( ExecArg == label ) ExecState = state_exec; } else if( ExecState == state_ignlabel ) { ExecState = state_jmplabel; } } /* ProcLabel() */ /****************************************************************** GetBit */ static int GetBit() { return pBytecode[ip++]; } /* GetBit() */ /******************************************************************** main */ int main(int argc, char **argv) { FILE *infile, *outfile; if( argc > 2 && (infile = fopen(argv[1], "rb")) != NULL && (outfile = fopen(argv[2], "wb+")) != NULL ) { sp = pBytecode; for(p = bytecode; *p; p++) { if( *p >= OFFSET ) { for(i = 0; i < 6; i++) *(sp++) = ((*p - OFFSET) & (1 << i)) ? 1 : 0; } } sp = Stack; ip = 0; for(ExecState = state_exec; ExecState != state_exit;) { if( GetBit() ) { /* 1 */ if( GetBit() ) { /* 11 */ if( GetBit() ) { /* 111 */ if( GetBit() ) { /* 1111 -> rget */ if( ExecState == state_exec ) { i = Register[*sp]; *sp = i; } } else { /* 1110 -> pop */ if( ExecState == state_exec ) sp--; } } else { /* 110 */ if( GetBit() ) { /* 1101 */ if( GetBit() ) { /* 11011 */ if( GetBit() ) { /* 110111 -> inc */ if( ExecState == state_exec ) { i = Register[*sp]++; *sp = i; } } else { /* 110110 -> sub */ if( ExecState == state_exec ) { sp[-1] -= *sp; sp--; } } } else { /* 11010 */ if( GetBit() ) { /* 110101 -> add */ if( ExecState == state_exec ) { sp[-1] += *sp; sp--; } } else { /* 110100 -> cmp */ if( ExecState == state_exec ) { i = sp[-1] < *sp ? 1 : 0; *(--sp) = i; } } } } else { /* 1100 */ if( GetBit() ) { /* 11001 */ if( GetBit() ) { /* 110011 -> sget */ if( ExecState == state_exec ) { for(i = -1; sp[i] != exec_frame; i--); i = sp[*sp + i]; *sp = i; } } else { /* 110010 -> mput */ if( ExecState == state_exec ) { Memory[sp[-1]][*sp] = sp[-2]; sp -= 2; } } } else { /* 11000 -> mget */ if( ExecState == state_exec ) { i = Memory[sp[-1]][*sp]; *(--sp) = i; } } } } } else { /* 10 */ if( GetBit() ) { /* 101 */ if( GetBit() ) { /* 1011 */ if( GetBit() ) { /* 10111 -> end */ if( ExecState == state_exec ) { if( *sp == exec_while ) ip = sp[-1]; else sp--; } else if( ExecState == state_endbegin ) { ExecArg--; if( ExecArg == 0 ) { ExecState = state_exec; sp -= (*sp == exec_while) ? 2 : 1; } } } else { /* 10110 -> begin */ if( ExecState == state_exec ) { if( *(sp--) == 0 ) { ExecState = state_endbegin; ExecArg = 1; } } else if( ExecState == state_endbegin ) { ExecArg++; } } } else { /* 1010 -> rput */ if( ExecState == state_exec ) { Register[*sp] = sp[-1]; sp--; } } } else { /* 100 */ if( GetBit() ) { /* 1001 */ if( GetBit() ) { /* 10011 */ if( GetBit() ) { /* 100111 -> ifcond */ if( ExecState == state_exec ) *(++sp) = exec_if; } else { /* 100110 -> whilecond */ if( ExecState == state_exec ) { *(++sp) = ip; *(++sp) = exec_while; } } } else { /* 10010 */ if( GetBit() ) { /* 100101 */ if( GetBit() ) { /* 1001011 */ if( GetBit() ) { /* 10010111 */ if( GetBit() ) { /* 100101111 -> ret */ if( ExecState == state_exec ) { sp--; ip = *(sp--); } } else { /* 100101110 -> end_bytecode */ ip = 0; } } else { /* 10010110 -> output */ if( ExecState == state_exec ) ExecState = state_exit; } } else { /* 1001010 -> call */ if( ExecState == state_exec ) { ExecState = state_getlabel; } else if( ExecState == state_jmplabel ) { ExecState = state_ignlabel; } } } else { /* 100100 */ if( GetBit() ) { /* 1001001 */ if( GetBit() ) { /* 10010011 -> fsek */ if( ExecState == state_exec ) fseek(infile, *(sp--), SEEK_SET); } else { /* 10010010 -> fget */ if( ExecState == state_exec ) *(++sp) = fgetc(infile); } } else { /* 1001000 -> fput */ if( ExecState == state_exec ) fputc(abs(*(sp--)), outfile); } } } } else { /* 1000 */ if( GetBit() ) { /* 10001 */ if( GetBit() ) { /* 100011 -> otherwise */ if( ExecState == state_exec ) { ExecState = state_endbegin; ExecArg = 1; } else if( ExecState == state_endbegin && ExecArg == 1 ) { ExecState = state_exec; } } else { /* 100010 */ if( GetBit() ) { /* 1000101 */ if( GetBit() ) { /* 10001011 -> label_heappush */ ProcLabel(slabel_heappush); } else { /* 10001010 -> label_assignid */ ProcLabel(slabel_assignid); } } else { /* 1000100 */ if( GetBit() ) { /* 10001001 -> label_writebits */ ProcLabel(slabel_writebits); } else { /* 10001000 -> label_break */ ProcLabel(slabel_break); } } } } else { /* 10000 */ if( GetBit() ) { /* 100001 */ if( GetBit() ) { /* 1000011 -> and */ if( ExecState == state_exec ) { sp[-1] &= *sp; sp--; } } else { /* 1000010 -> shr */ if( ExecState == state_exec ) { sp[-1] >>= *sp; sp--; } } } else { /* 100000 */ if( GetBit() ) { /* 1000001 -> shl */ if( ExecState == state_exec ) { sp[-1] <<= *sp; sp--; } } else { /* 1000000 -> or */ if( ExecState == state_exec ) { sp[-1] |= *sp; sp--; } } } } } } } } else { /* 0 -> data */ for(i = j = 0; i < 4; i++) j |= GetBit() << i; if( ExecState == state_exec ) *(++sp) = Constant[j]; } } puts(String[*sp]); fclose(infile); fclose(outfile); } else { puts("Error"); } return 0; } /* main() */