#include <stdio.h>
#include <stdlib.h>
#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.y; cnt++) { // for every new column a row is added
char *tmp;
printf("cnt=%lisize=%li\n", cnt, playfieldsize.y); // added for debugging purpose
if (tmp = realloc(playfield[cnt], sizeof(char) * playfieldsize.x)) // segfault happens at this line
playfield[cnt] = tmp;
else
die("Not enough initial memory");
}
} else // if storage could not be reallocated
die("Not enough initial memory");
}
if (x >= 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<playfieldsize.y; y++) {
for (x=0; x<playfieldsize.x; x++) {
if (playfield[y][x])
printf("[%c]",playfield[y][x]);
else
printf("[ ]");
}
printf("\n");
}*/
}