#include #include #define INCREASE 30 FILE *source; char *prgnm; struct size { int used; int available; } portsize; char *stack; unsigned long sp, stacksize; struct prgpnt { unsigned long x; unsigned long y; unsigned long dirx; unsigned long diry; } pc; char mode; struct portal { int x; int y; } *portals; int sc; void die (char *err) { fprintf(stderr, "%s: %s\n", prgnm, err); exit(1); } char **playfield; struct playfieldsize { unsigned long y; unsigned long x; } playfieldsize; int isLet (int y, int x) { if (playfield[y][x] > 64 && playfield[y][x] < 91 || playfield[y][x] > 96 && playfield[y][x] < 123) { return 1; } else { return 0; } } void nextstack () { if (++sp == stacksize) { char *tmp; if (tmp = realloc(stack, sizeof(char) * (stacksize += INCREASE))) stack = tmp; else die("Not enough memory"); } } int main (int argc, char *argv[]) { prgnm = argv[0]; if (argc == 2) { if (!(source = fopen(argv[1], "r"))) { perror(prgnm); exit(1); } } else if (argc == 1) { source = stdin; } else { die("Command line error"); } unsigned long x, y; playfieldsize.y = playfieldsize.x = y = x = 0; struct portal *tmp; if (tmp = malloc(sizeof(struct portal) * 50)) { portals = tmp; portsize.available = 50; portsize.used = 0; } char c; while ((c = getc(source))!=EOF) { if (!isascii(c) && !isprint(c)) { die("Illegal character in program. The program must only contian printable ASCII characters."); } else if (c == '$') { pc.x = x; pc.y = y; pc.dirx = 1; pc.diry = 0; } else if (c == '@') { if (portsize.used >= portsize.available) { if (tmp = realloc(portals, sizeof(struct portal) * (portsize.available += INCREASE))) portals = tmp; else die("Not enough initial memory"); } portals[portsize.used].x = x; portals[portsize.used].y = y; portsize.used++; } if (c == '\n') { x=0; y++; } else { unsigned long cnt; if (y >= playfieldsize.y) { // if the array isn't large enough char **tmp; unsigned long cnt; cnt = playfieldsize.y; // stores the old size of the array playfieldsize.y += (y - playfieldsize.y) + INCREASE; // the new array size if (tmp = realloc(playfield, playfieldsize.y * sizeof(char *))) { // if storage can be reallocated for the new size playfield = tmp; for (; cnt= playfieldsize.x) { char *tmp; playfieldsize.x += x - playfieldsize.x + INCREASE; for (cnt = 0; cnt < playfieldsize.y; cnt++) { if (tmp = realloc(playfield[cnt], sizeof(char) * playfieldsize.x)) playfield[cnt] = tmp; else die("Not enough initial memory"); } } playfield[y][x] = c; x++; } } char *tmp2; if (tmp2 = malloc(sizeof(char) * 50)) { stack = tmp2; stacksize = 50; sp = 0; } while (playfield[pc.y][pc.x] != '#') { playfield[pc.y+=pc.diry][pc.x+=pc.dirx]; if (mode == 's') { /* if string mode */ char string[1000]; if (playfield[pc.y][pc.x] == '"') { nextstack(); stack[sp] = 0; while (!(sc < 0)) { nextstack(); stack[sp] = string[sc]; --sc; } mode = 0; } else { string[sc]=playfield[pc.y][pc.x]; sc++; } } else { switch (playfield[pc.y][pc.x]) { case '/': if (pc.dirx) { pc.diry -= pc.dirx; pc.dirx = 0; } else { pc.dirx -= pc.diry; pc.diry = 0; } break; case '\\': ; unsigned long tmp; tmp = pc.diry; pc.diry = pc.dirx; pc.dirx = tmp; break; case '>': nextstack(); break; case '<': --sp; break; case '+': ++stack[sp]; break; case '-': --stack[sp]; break; case '.': printf("[%i]",stack[sp]); putchar(stack[sp]); break; case ',': stack[sp] = getchar(); break; case '!': playfield[pc.y+=pc.diry][pc.x+=pc.dirx]; break; case '|': pc.y = -(pc.y); pc.x = -(pc.x); break; case '"': mode = 's'; break; } } } /* x = y = 0; for (y=0; y