/****************************************************************** * * Copyright (c) 2003 Benjamin `Quisar' Lerman. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * ******************************************************************/ #define PUSH 0 #define DUP 1 #define SWAP 2 #define DISCARD 3 #define ADD 4 #define SUB 5 #define MUL 6 #define INTDIV 7 #define MODULO 8 #define CALL 9 #define JUMP 10 #define JUMPZ 11 #define JUMPNEG 12 #define ENDSUB 13 #define END 14 #define STORE 15 #define RETR 16 #define OUTCHAR 17 #define OUTNUM 18 #define INCHAR 19 #define INNUM 20 #define LABEL 21 int counteur; int stack; int mem; int parse_error; int com_erreur; main() { int size_used; parse_error = "Parse Error.\n"; com_erreur = "Unknown Command.\n"; counteur = *0; size_used = get_code(counteur); *0 += size_used; stack = *0; mem = (*0 + 1); resolve_label(counteur,size_used); execute_code(counteur); } execute_code(pc) { int r; int s; int t; while(1) { if(*pc == PUSH) { *stack = *(pc + 1); stack += 2; } else if(*pc == DUP) { *stack = *(stack -2); stack += 2; } else if(*pc == SWAP) { t = *(stack - 2); *(stack - 2) = *(stack - 4); *(stack - 4) = t; } else if(*pc == DISCARD) { stack -= 2; } else if(*pc == ADD) { stack -= 2; *(stack - 2) = *(stack - 2) + *(stack); } else if(*pc == SUB) { stack -= 2; *(stack - 2) = *(stack - 2) - *(stack); } else if(*pc == MUL) { stack -= 2; *(stack - 2) = *(stack - 2) * *(stack); } else if(*pc == INTDIV) { stack -= 2; *(stack - 2) = *(stack - 2) / *(stack); } else if(*pc == MODULO) { stack -= 2; *(stack - 2) = *(stack - 2) % *(stack); } else if(*pc == CALL) { execute_code(*(pc+1)); } else if(*pc == JUMP) { pc = *(pc+1) -2; } else if(*pc == JUMPZ) { stack -= 2; if(*stack == 0) pc = *(pc+1) -2; } else if(*pc == JUMPNEG) { stack -= 2; if(*stack < 0) pc = *(pc+1) -2; } else if(*pc == ENDSUB) { return 0; } else if(*pc == END) { exit(0); } else if(*pc == STORE) { stack -= 2; t = *stack; stack -= 2; r = *stack; if(r < 0) { s = mem + 2 - 4 * r; } else { s= mem + 4 * r; } *s = t; } else if(*pc == RETR) { stack -= 2; r = *stack; if(r < 0) { s = mem + 2 - 4 * r; } else { s = mem + 4 * r; } *stack = *s; stack += 2; } else if(*pc == OUTCHAR) { stack -= 2; outchar *stack; } else if(*pc == OUTNUM) { stack -= 2; outint *stack; } else if(*pc == INCHAR) { } else if(*pc == INNUM) { } else if(*pc == LABEL) { } pc+=2; } return 0; } printint(i) { outint i; outchar '\n'; return 0; } get_code(place) { int c; c = get_next_space(); if(c == -1) return 0; if(c == ' ') { if(!stackman(place)) return 2+get_code(place+2); return 0; } if(c == '\t') { c = get_next_space(); if(c == -1) { print(parse_error); return 0; } if(c == ' ') { if(!ariman(place)) return 2+get_code(place+2); { print(parse_error); return 0; } } if(c == '\t') { if(!heapaccman(place)) return 2+get_code(place+2); { print(parse_error); return 0; } } if(c == '\n') { if(!ioman(place)) return 2+get_code(place+2); print(parse_error); return 0; } /* CAN'T HAPPEN */ return -1; } if(c == '\n') { if(!flowman(place)) return 2+get_code(place+2); print(parse_error); return 0; } /* CAN'T HAPPEN */ return 0; } ariman(place) { int c; int d; c = get_next_space(); d = get_next_space(); if(c == ' ') { if(d == ' ') { *place = ADD; return 0; } if(d == '\t') { *place = SUB; return 0; } if(d == '\n') { *place = MUL; return 0; } return -1; } if(c == '\t') { if(d == ' ') { *place = INTDIV; return 0; } if(d == '\t') { *place = MODULO; return 0; } } return -1; } heapaccman(place) { int c; c = get_next_space(); if(c == ' ') { *place = STORE; return 0; } if(c == '\t') { *place = RETR; return 0; } return -1; } ioman(place) { int c; int d; c = get_next_space(); d = get_next_space(); if(c == ' ') { if(d == ' ') { *place = OUTCHAR; return 0; } if(d == '\t') { *place = OUTNUM; return 0; } return -1; } if(c == '\t') { if(d == ' ') { *place = INCHAR; return 0; } if(d == '\t') { *place = INNUM; return 0; } } return -1; } flowman(place) { int c; int d; c = get_next_space(); d = get_next_space(); if(c == ' ') { if(d == ' ') { *place = LABEL; place++; *place = readlabel(); if(*place < 1) return -1; return 0; } if(d == '\t') { *place = CALL; place++; *place = readlabel(); if(*place < 1) return -1; return 0; } if(d == '\n') { *place = JUMP; place++; *place = readlabel(); if(*place < 1) return -1; return 0; } return -1; } if(c == '\t') { if(d == ' ') { *place = JUMPZ; place++; *place = readlabel(); if(*place < 1) return -1; return 0; } if(d == '\t') { *place = JUMPNEG; place++; *place = readlabel(); if(*place < 1) return -1; return 0; } if(d == '\n') { *place = ENDSUB; return 0; } return -1; } if((c == '\n') && (d == '\n')) { *place = END; return 0; } return -1; } stackman(place) { int c; c = get_next_space(); if(c == -1) return -1; if(c == ' ') { *place = PUSH; place++; *place = readnum(); return 0; } if(c == '\n') { c = get_next_space(); if(c == -1) return -1; if(c == ' ') { *place = DUP; } else if(c == '\t') { *place = SWAP; } else *place = DISCARD; return 0; } if(c == '\t') return -1; /* CAN'T HAPPEN */ return -1; } get_next_space() { int c; do { getchar c; } while((c!=-1) && (c!='\n') && (c!=' ') && (c!='\t')); return c; } readlabel() { int c; c = get_next_space(); if(c == -1) return -1; if(c == '\n') return 1; if(c == '\t') return 2*readlabel() + 1; return 2*readlabel(); } readnum() { int c; c = get_next_space(); if(c == -1) return -1; if(c == '\n') return 0; if(c == '\t') return -1 * readnum2(0); return readnum2(0); } readnum2(i) { int c; int d; c = get_next_space(); if(c == -1) return i; if(c == '\n') return i; if(c == ' ') return readnum2(2*i); else return readnum2(2*i+1); } print(c) { while(*c) { outchar *c; c++; } } resolve_label(counter,size) { int i; int j; int k; int l; for(i=counter; i