#include #include #include #include #define max_file_size 100000 /*100K*/ #define mem_size 10000000 /*10M (40 megs of ram)*/ typedef struct { unsigned from; unsigned to; char case1; } bytecode; int *mem, vars[26], fs; char *file; unsigned char *input = 0; int geti() { int i=0; if(input) { sscanf(input, "%d", &i); while(*input >= '0' && *input <= '9') input++; } else scanf("%d", &i); return i; } int getic() { if(input) { if(*input) return *(input++); else return -1; } else { return (unsigned)getchar(); } } int debugi(int c, int *mp) { int i=0; printf("\n[ "); for(i=0; i<26; i++) printf("%c:%d ",i+'a', i==2?c:vars[i]); printf("\n"); for(i=0; i<26; i++) printf("%c:%d ",i+'A', mp[i]); printf("]\n"); return 0; } void get_input_source() { char *f; for(f=file; *f; f++) { if(!input && *f=='!') { input = f + 1; *f = '\0'; } } } void clean_code() { char goods[256]; int i; char *from, *to; from = to = file; for(i=0;i<256;i++) goods[i] = 0; for(i=65;i<91;i++) goods[i] = 1; for(i=97;i<123;i++) goods[i] = 1; for(i=48;i<58;i++) goods[i] = 1; goods[95] = goods[123] = goods[125] = goods[35] = goods[10] = 1; while(*from) { if(goods[(int)*from]) *(to++) = *from; from++; } *to = 0; fs = to - file; } void remove_pound_comments() { char *from, *to; from = to = file; while(*from) { if(*from == '#') while(*(++from) != '\n' && *from != '\0'); else if(*from != '\n') *(to++) = *from; if(!*from) break; from++; } *to = 0; fs = to - file; } void remove_bracket_comments() { char *from, *to; from = to = file; int count = 0; while(*from) { if(*from == '}') { if(count) count--; else to = file; } else if(*from == '{') { count++; } else if(!count) { *(to++) = *from; } from++; } *to = 0; fs = to - file; } bytecode *compile(char *filename) { char *fp; FILE *f = fopen(filename, "r"); if(!f) {fprintf(stderr,"file not found: %s\n", filename); exit(1); } file = malloc(max_file_size); file[fread(file, 1, max_file_size, f)]=0; fclose(f); fs=strlen(file); get_input_source(); clean_code(); remove_pound_comments(); remove_bracket_comments(); bytecode *rp, *ret = malloc((fs+10) / 2 * sizeof(bytecode)); for(fp = file, rp = ret; *fp; fp++, rp++) { char i = *fp; if(i == 'o') { rp->case1 = 2; } else if(i == 'q') { rp->case1 = 3; } else if(i == 'p') { rp->case1 = 4; } else if(i == 'c') { rp->case1 = 5; } else if(i<='Z' && i>='A') { rp->case1 = 0; rp->to = i - 'A'; } else if(i<='z' && i>='a') { rp->case1 = 1; rp->to = i - 'a'; } else if(i == '_') { rp->case1 = -1; } else if(i<='9' && i>='0') { do { i=*(++fp); } while (i<='9' && i>='0'); fp--; rp->case1 = -1; } else printf("shouldn't get here 1\n"); rp->case1 *= 8; i=*(++fp); if(!i) { fprintf(stderr, "parse error: odd number of operands\n"); exit(1); } if(i == 'i') { rp->case1 += 3; } else if(i == 'j') { rp->case1 += 4; } else if(i == 'r') { rp->case1 += 5; } else if(i == 'c') { rp->case1 += 6; } else if(i == '_') { rp->case1 += 7; } else if(i<='Z' && i>='A') { rp->from = i - 'A'; } else if(i<='z' && i>='a') { rp->case1 += 1; rp->from = i - 'a'; } else if(i<='9' && i>='0') { int num = 0; do { num*=10; num+=i-'0'; i=*(++fp); } while (i<='9' && i>='0'); fp--; rp->case1 += 2; rp->from = num; } else printf("shouldn't get here 2\n"); } rp->case1 = -1; fs = rp - ret; return ret; } int main(int argc, char **argv) { if(argc != 2) { fprintf(stderr, "usuage: iminus \n"); return 1; } bytecode *code = compile(argv[1]); srandom(time(0)); mem=calloc(mem_size+50, sizeof(int)); int maxp = mem_size / 2; int minp = -maxp; int *maxmp = mem + mem_size; int *minmp = mem; int *memp = mem + maxp; /* z -> -1, y -> -2, x -> -10, w -> -32, v -> -mem_size, last Z -> -1 */ vars[25]-=1; vars[24]-=2; vars[23]-=10; vars[22]-=32; vars[21] -= maxp; maxmp[25]-=1; int temp, *p = vars + 'p' - 'a', *r = vars + 'r' - 'a'; bytecode *cp = code; top: switch (cp->case1) { case 0: memp[cp->to] -= memp[cp->from]; cp++; goto top; case 1: memp[cp->to] -= vars[cp->from]; cp++; goto top; case 2: memp[cp->to] -= cp->from; cp++; goto top; case 3: memp[cp->to] -= getic(); cp++; goto top; case 4: memp[cp->to] -= geti(); cp++; goto top; case 5: memp[cp->to] -= (random()%(*r+!(*r))*(1-2*(((*r)>>31)&1))); cp++; goto top; case 6: memp[cp->to] -= (cp-code); cp++; goto top; case 7: memp[cp->to] -= debugi(cp-code,memp); cp++; goto top; case 8: vars[cp->to] -= memp[cp->from]; cp++; goto top; case 9: vars[cp->to] -= vars[cp->from]; cp++; goto top; case 10: vars[cp->to] -= cp->from; cp++; goto top; case 11: vars[cp->to] -= getic(); cp++; goto top; case 12: vars[cp->to] -= geti(); cp++; goto top; case 13: vars[cp->to] -= (random()%(*r+!(*r))*(1-2*(((*r)>>31)&1))); cp++; goto top; case 14: vars[cp->to] -= (cp-code); cp++; goto top; case 15: vars[cp->to] -= debugi(cp-code,memp); cp++; goto top; case 16: putchar(-memp[cp->from]); cp++; goto top; case 17: putchar(-vars[cp->from]); cp++; goto top; case 18: putchar(-cp->from); cp++; goto top; case 19: putchar(-getic()); cp++; goto top; case 20: putchar(-geti()); cp++; goto top; case 21: putchar(-(random()%(*r+!(*r))*(1-2*(((*r)>>31)&1)))); cp++; goto top; case 22: putchar(-(cp-code)); cp++; goto top; case 23: putchar(-debugi(cp-code,memp)); cp++; goto top; case 24: printf("%d", -memp[cp->from]); cp++; goto top; case 25: printf("%d", -vars[cp->from]); cp++; goto top; case 26: printf("%d", -cp->from); cp++; goto top; case 27: printf("%d", -getic()); cp++; goto top; case 28: printf("%d", -geti()); cp++; goto top; case 29: printf("%d", -(random()%(*r+!(*r))*(1-2*(((*r)>>31)&1)))); cp++; goto top; case 30: printf("%d", -(cp-code)); cp++; goto top; case 31: printf("%d", -debugi(cp-code,memp)); cp++; goto top; case 32: temp = memp[cp->from]; (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 33: temp = vars[cp->from]; (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 34: temp = cp->from; (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 35: temp = getic(); (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 36: temp = geti(); (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 37: temp = (random()%(*r+!(*r))*(1-2*(((*r)>>31)&1))); (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 38: temp = (cp-code); (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 39: temp = debugi(cp-code,memp); (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++; goto top; case 40: cp-=memp[cp->from]; if((unsigned)(++cp - code)>=fs) goto done; goto top; case 41: cp-=vars[cp->from]; if((unsigned)(++cp - code)>=fs) goto done; goto top; case 42: cp-=cp->from; if((unsigned)(++cp - code)>=fs) goto done; goto top; case 43: cp-=getic(); if((unsigned)(++cp - code)>=fs) goto done; goto top; case 44: cp-=geti(); if((unsigned)(++cp - code)>=fs) goto done; goto top; case 45: cp-=(random()%(*r+!(*r))*(1-2*(((*r)>>31)&1))); if((unsigned)(++cp - code)>=fs) goto done; goto top; case 46: cp-=(cp-code); if((unsigned)(++cp - code)>=fs) goto done; goto top; case 47: cp-=debugi(cp-code,memp); if((unsigned)(++cp - code)>=fs) goto done; goto top; } done: free(file); free(code); free(mem); return 0; } /* generated from (ruby) from=['memp[cp->from]', 'vars[cp->from]', 'cp->from', 'getic()', 'geti()', '(random()%(*r+!(*r))*(1-2*(((*r)>>31)&1)))', '(cp-code)', 'debugi(cp-code,memp)'] to=['memp[cp->to] -= from; cp++', 'vars[cp->to] -= from; cp++', 'putchar(-from); cp++', 'printf("%d", -from); cp++', 'temp = from; (*p) -= temp; memp -= temp; if(memp < minmp) { memp = minmp; (*p) = minp; } else if(memp > maxmp) { memp = maxmp; (*p) = maxp; }; cp++', 'cp-=from; if((unsigned)(++cp - code)>=fs) goto done'] 48.times{|i|puts "case #{i}: #{to[i/8].sub('from',from[i%8])}; goto top;"} */