/* byte1.c - Don Yang (uguu.org) Separate instruction / constant bytecodes. 10/18/01 */ #include #include enum { exec_while = 575, exec_if, exec_frame, end_bytecode }; enum { add = 1024, sub, shl, shr, and, or, cmp, inc, mget, mput, rget, rput, fget, fput, fsek, sget, pop, call, ret, whilecond, ifcond, begin, otherwise, end, label_break, label_assignid, label_heappush, label_writebits, output }; enum { Tree = 0, x, y, LeftPtr, RightPtr, NextPtr, buffer, Dictionary, f, MEM_BANK_COUNT }; enum { i = 0, j, bit, byte, size, a, b, c, Heap, HeapPoolIndex, branch, NodeCount, FileSize, tmp, REGISTER_COUNT }; static char *String[3] = {"Decoded", "Encoded", "Empty file"}; static int Memory[MEM_BANK_COUNT][512]; static int Register[REGISTER_COUNT], z, ip, *sp; static int Stack[512]; static FILE *infile, *outfile; /************************************************************** Bytecode[] */ static int Bytecode[] = { /* main() */ /*105*/ 0, size, rput, fsek, /*106*/ whilecond, ifcond, size, rget, 579, cmp, begin, /*107*/ fget, buffer, size, rget, mput, EOF, sub, tmp, rput, pop, otherwise, 0, tmp, rput, pop, end, tmp, rget, /*108*/ begin, /*109*/ size, inc, pop, /*110*/ end, /*111*/ ifcond, size, rget, /*112*/ begin, /*113*/ buffer, 0, i, rput, FileSize, rput, mget, NodeCount, rput, pop, /*114*/ NodeCount, rget, 3, add, 2, shr, HeapPoolIndex, rput, /*115*/ NodeCount, rget, 1, shl, add, Heap, rput, pop, /*116*/ ifcond, Heap, rget, 4, add, size, rget, cmp, /*117*/ begin, /*118*/ whilecond, i, rget, NodeCount, rget, cmp, /*119*/ begin, /*120*/ 0, j, rput, pop, /*121*/ whilecond, j, rget, 4, cmp, /*122*/ begin, /*123*/ buffer, i, rget, 2, shr, 1, add, mget, j, rget, 1, shl, shr, 3, and, f, i, rget, j, inc, add, mput, pop, /*125*/ end, /*126*/ i, rget, 4, add, i, rput, pop, /*127*/ end, /*129*/ HeapPoolIndex, rget, 1, add, j, rput, pop, /*130*/ 0, i, rput, pop, /*131*/ whilecond, i, rget, NodeCount, rget, cmp, /*132*/ begin, /*133*/ 0, c, rput, pop, /*134*/ whilecond, c, rget, 2, cmp, /*135*/ begin, /*136*/ c, rget, 8, shl, i, rget, add, a, rput, pop, /*137*/ buffer, j, inc, mget, b, rput, pop, /*138*/ ifcond, f, i, rget, mget, c, rget, 1, add, and, /*139*/ begin, /*140*/ 0, b, rget, sub, Tree, a, rget, mput, pop, /*142*/ otherwise, /*144*/ b, rget, Tree, a, rget, mput, pop, /*145*/ ifcond, Tree, a, rget, mget, i, rget, 1, add, cmp, /*146*/ NodeCount, rget, Tree, a, rget, mget, 1, add, cmp, or, /*147*/ begin, /*148*/ pop, pop, pop, pop, pop, pop, pop, pop, call, label_break, /*149*/ end, /*150*/ end, /*151*/ c, inc, pop, /*152*/ end, /*153*/ i, inc, pop, /*154*/ end, /*155*/ label_break, /*156*/ ifcond, i, rget, NodeCount, rget, sub, /*157*/ begin, /*159*/ otherwise, /*161*/ 0, i, rput, FileSize, rput, pop, /*162*/ whilecond, i, rget, 32, cmp, /*163*/ begin, /*164*/ buffer, j, inc, mget, i, rget, shl, FileSize, rget, or, FileSize, rput, pop, /*165*/ i, rget, 8, add, i, rput, pop, /*166*/ end, /*167*/ end, /*168*/ end, /*169*/ ifcond, 0, FileSize, rget, cmp, /*170*/ begin, /*171*/ Heap, rget, 5, add, fsek, /*172*/ 0, j, rput, i, rput, byte, rput, pop, /*173*/ 8, bit, rput, pop, /*174*/ whilecond, i, rget, FileSize, rget, cmp, /*175*/ begin, /*176*/ ifcond, 7, bit, rget, cmp, /*177*/ begin, /*178*/ fget, byte, rput, pop, /*179*/ 0, bit, rput, pop, /*180*/ end, /*182*/ ifcond, byte, rget, 1, bit, rget, shl, and, begin, 256, tmp, rput, pop, otherwise, 0, tmp, rput, pop, end, tmp, rget, j, rget, add, branch, rput, pop, /*183*/ ifcond, Tree, branch, rget, mget, 1, cmp, /*184*/ begin, /*185*/ 0, j, rput, Tree, branch, rget, mget, sub, fput, /*187*/ i, inc, pop, /*189*/ otherwise, /*191*/ Tree, branch, rget, mget, j, rput, pop, /*192*/ end, /*193*/ bit, inc, pop, /*194*/ end, /*195*/ 0/*"Decoded"*/, output, /*197*/ otherwise, /*199*/ 0, i, rput, FileSize, rput, fsek, /*200*/ whilecond, i, rget, 256, cmp, /*201*/ begin, /*202*/ 0, f, i, inc, mput, pop, /*203*/ end, /*205*/ whilecond, fget, i, rput, EOF, sub, /*206*/ begin, /*207*/ f, i, rget, mget, 1, add, f, i, rget, mput, pop, /*208*/ FileSize, inc, pop, /*209*/ end, /*211*/ 0, i, rput, b, rput, a, rput, HeapPoolIndex, rput, 1, sub, Heap, rput, pop, /*213*/ whilecond, i, rget, 256, cmp, /*214*/ begin, /*215*/ ifcond, f, i, rget, mget, /*216*/ begin, /*217*/ call, label_heappush, /*218*/ end, /*219*/ i, inc, pop, /*220*/ end, /*221*/ ifcond, NextPtr, Heap, rget, mget, -1, sub, /*222*/ begin, otherwise, /*223*/ 0, i, rput, pop, /*224*/ whilecond, 0, f, i, rget, mget, cmp, /*225*/ begin, /*226*/ i, inc, pop, /*227*/ end, /*228*/ call, label_heappush, /*229*/ end, /*231*/ 256, i, rput, pop, /*232*/ whilecond, NextPtr, Heap, rget, mget, 1, add, /*233*/ begin, /*234*/ NextPtr, NextPtr, Heap, rget, a, rput, mget, b, rput, mget, Heap, rput, pop, /*236*/ x, a, rget, mget, x, b, rget, mget, add, f, i, rget, mput, pop, /*237*/ call, label_heappush, /*238*/ end, /*240*/ 0, NodeCount, rput, pop, /*241*/ Heap, rget, -1, call, label_assignid, pop, pop, /*243*/ NodeCount, rget, i, rput, pop, /*244*/ whilecond, i, rget, 256, cmp, /*245*/ begin, /*246*/ 256, Tree, 256, i, rget, add, mput, /*247*/ Tree, i, inc, mput, pop, /*248*/ end, /*250*/ NodeCount, rget, fput, /*251*/ 0, i, rput, pop, /*252*/ whilecond, i, rget, NodeCount, rget, cmp, /*253*/ begin, /*254*/ 0, j, rput, byte, rput, pop, /*255*/ whilecond, j, rget, 4, cmp, /*256*/ begin, /*257*/ 1, j, rget, 1, shl, shl, c, rput, pop, /*258*/ ifcond, Tree, i, rget, j, rget, add, mget, 1, cmp, /*259*/ begin, /*260*/ byte, rget, c, rget, or, byte, rput, pop, /*261*/ end, /*262*/ ifcond, Tree, i, rget, j, rget, 256, add, add, mget, 1, cmp, /*263*/ begin, /*264*/ byte, rget, c, rget, 1, shl, or, byte, rput, pop, /*265*/ end, /*266*/ j, inc, pop, /*267*/ end, /*268*/ byte, rget, fput, /*269*/ i, rget, 4, add, i, rput, pop, /*270*/ end, /*272*/ 0, i, rput, pop, /*273*/ whilecond, i, rget, NodeCount, rget, cmp, /*274*/ begin, /*275*/ Tree, i, rget, mget, fput, /*276*/ Tree, i, inc, 256, add, mget, fput, /*278*/ end, /*280*/ 0, i, rput, pop, /*281*/ whilecond, i, rget, 4, cmp, /*282*/ begin, /*283*/ FileSize, rget, i, inc, 3, shl, shr, 255, and, fput, /*285*/ end, /*287*/ 0, byte, rput, bit, rput, i, rput, fsek, /*288*/ whilecond, i, rget, FileSize, rget, cmp, /*289*/ begin, /*290*/ Dictionary, fget, j, rput, mget, /*291*/ call, label_writebits, pop, /*292*/ i, inc, pop, /*293*/ end, /*295*/ ifcond, 0, bit, rget, cmp, /*296*/ begin, /*297*/ byte, rget, fput, /*298*/ end, /*300*/ 1/*"Encoded"*/, output, /*301*/ end, /*303*/ otherwise, /*305*/ 2/*"Empty file"*/, output, /*306*/ end, /* AssignID() */ /* 25*/ label_assignid, /* 29*/ LeftPtr, -3, sget, mget, /* 30*/ RightPtr, -3, sget, mget, /* 31*/ -2, sget, NextPtr, -3, sget, mput, pop, /* 32*/ ifcond, y, -3, sget, mget, 256, sub, /* 33*/ begin, /* 34*/ -3, sget, Dictionary, y, -3, sget, mget, mput, pop, /* 36*/ otherwise, /* 38*/ NodeCount, inc, x, -3, sget, mput, pop, /* 39*/ +1, sget, -3, sget, call, label_assignid, pop, pop, /* 40*/ +2, sget, -3, sget, call, label_assignid, pop, pop, /* 43*/ ifcond, y, +1, sget, mget, 256, sub, begin, /* 44*/ 0, y, +1, sget, mget, sub, tmp, rput, pop, otherwise, /* 45*/ x, +1, sget, mget, tmp, rput, pop, end, /* 42*/ tmp, rget, Tree, x, -3, sget, mget, mput, pop, /* 47*/ ifcond, y, +2, sget, mget, 256, sub, begin, /* 48*/ 0, y, +2, sget, mget, sub, tmp, rput, pop, otherwise, /* 49*/ x, +2, sget, mget, tmp, rput, pop, end, /* 46*/ tmp, rget, Tree, 256, x, -3, sget, mget, add, mput, pop, /* 50*/ end, /* 51*/ pop, pop, ret, /* HeapPush() */ /* 53*/ label_heappush, /* 55*/ HeapPoolIndex, inc, c, rput, pop, /* 56*/ f, i, rget, y, c, rget, mput, mget, x, c, rget, mput, pop, /* 57*/ a, rget, LeftPtr, c, rget, mput, pop, /* 58*/ b, rget, RightPtr, c, rget, mput, pop, /* 60*/ ifcond, ifcond, Heap, rget, 0, cmp, /* 61*/ begin, 1, tmp, rput, pop, otherwise, x, c, rget, mget, x, Heap, rget, mget, cmp, tmp, rput, pop, end, tmp, rget, /* 62*/ begin, /* 63*/ Heap, rget, NextPtr, c, rget, mput, pop, /* 64*/ c, rget, Heap, rput, pop, /* 66*/ otherwise, /* 68*/ NextPtr, Heap, rget, a, rput, mget, b, rput, pop, /* 69*/ whilecond, ifcond, b, rget, 1, add, begin, /* 70*/ x, b, rget, mget, x, c, rget, mget, cmp, tmp, rput, pop, otherwise, 0, tmp, rput, pop, end, tmp, rget, /* 71*/ begin, /* 72*/ NextPtr, b, rget, a, rput, mget, b, rput, pop, /* 73*/ end, /* 74*/ b, rget, NextPtr, c, rget, NextPtr, a, rget, mput, mput, pop, /* 75*/ end, /* 76*/ ret, /* WriteBits() */ /* 78*/ label_writebits, /* 80*/ ifcond, NextPtr, -2, sget, mget, 1, add, /* 81*/ begin, /* 82*/ NextPtr, -2, sget, mget, call, label_writebits, pop, /* 83*/ ifcond, RightPtr, NextPtr, -2, sget, mget, mget, -2, sget, sub, begin, 0, tmp, rput, pop, otherwise, 1, tmp, rput, pop, end, tmp, rget, bit, inc, shl, byte, rget, or, byte, rput, pop, /* 84*/ ifcond, 7, bit, rget, cmp, /* 85*/ begin, /* 86*/ byte, rget, fput, /* 87*/ 0, byte, rput, bit, rput, pop, /* 88*/ end, /* 89*/ end, /* 90*/ ret, end_bytecode }; /* Bytecode[] */ void endbegin(void) { for(z = 1; z > 0;) { ip++; if( z == 1 && Bytecode[ip] == otherwise ) return; if( Bytecode[ip] == begin ) z++; if( Bytecode[ip] == end ) z--; } sp -= (*sp == exec_while) ? 2 : 1; } int main(int argc, char **argv) { if( argc < 3 ) return printf("%s \n", *argv); if( (infile = fopen(argv[1], "rb")) == NULL || (outfile = fopen(argv[2], "wb+")) == NULL ) return puts("error"); sp = &Stack[1]; for(ip = 0; Bytecode[ip] != output; ip++) { switch( Bytecode[ip] ) { case add: sp[-1] += *sp; sp--; break; case sub: sp[-1] -= *sp; sp--; break; case shl: sp[-1] <<= *sp; sp--; break; case shr: sp[-1] >>= *sp; sp--; break; case and: sp[-1] &= *sp; sp--; break; case or: sp[-1] |= *sp; sp--; break; case cmp: z = sp[-1] < *sp ? 1 : 0; *(--sp) = z; break; case inc: z = Register[*sp]++; *sp = z; break; case mget: z = Memory[sp[-1]][*sp]; *(--sp) = z; break; case mput: Memory[sp[-1]][*sp] = sp[-2]; sp-=2; break; case rget: z = Register[*sp]; *sp = z; break; case rput: Register[*sp] = sp[-1]; sp--; break; case fget: *(++sp) = fgetc(infile); break; case fput: fputc(abs(*(sp--)), outfile); break; case fsek: fseek(infile, *(sp--), SEEK_SET); break; case sget: for(z = -1; sp[z] != exec_frame; z--); z = sp[*sp + z]; *sp = z; break; case pop: sp--; break; case call: z = Bytecode[*(++sp) = ++ip]; *(++sp) = exec_frame; for(ip++; Bytecode[ip] != z; ip++) { if( Bytecode[ip] == call ) ip++; else if( Bytecode[ip] == end_bytecode ) ip = 0; } break; case ret: sp--; ip = *(sp--); break; case label_break: case label_assignid: case label_heappush: case label_writebits: break; case whilecond: *(++sp) = ip; *(++sp) = exec_while; break; case ifcond: *(++sp) = exec_if; break; case begin: if( *(sp--) == 0 ) endbegin(); break; case otherwise: endbegin(); break; case end: if( *sp == exec_while ) ip = sp[-1]; else sp--; break; default: *(++sp) = Bytecode[ip]; break; } } puts(String[*sp]); fclose(infile); fclose(outfile); return 0; }