2018/09/29 追記
https://qiita.com/kasari/items/043764c4b3ba87a547e3#comment-5d5261c37687129f69a8
実装にバグがあったため一部修正しました。ご指摘ありがとうございました。
#include <stdio.h>
#define CODESIZE 1024
#define MEMSIZE 1024
typedef struct Code {
char code;
struct Code *addr;
} Code;
int debug = 0;
Code codes[CODESIZE];
char memory[MEMSIZE];
void step(Code *cp, char *mp) {
int i;
char ch;
printf("code: %c (%p)\nmp: %d(%c) (%p)\n", cp->code, cp, *mp, *mp, mp);
printf("memory: ");
for (i=0; i<8; i++) {
printf("%d(%c) ",memory[i], memory[i]);
}
scanf("%c", &ch);
printf("\n\n");
}
void getSource(char *fileName) {
char ch;
Code *cp = codes;
FILE *f = fopen(fileName, "r");
while ((ch=getc(f)) != EOF) {
switch (ch) {
case '>':
case '<':
case '+':
case '-':
case '.':
case ',':
case '[':
case ']':
(cp++)->code = ch;
}
}
fclose(f);
}
void analyze() {
int index = 0;
Code* stack[20];
Code *cp = codes;
for (;cp->code != 0; cp++) {
if (cp->code == '[') {
stack[index++] = cp;
} else if (cp->code == ']') {
index--;
stack[index]->addr = cp+1;
cp->addr = stack[index];
}
}
if (debug) {
for (cp=codes; cp->code!=0; cp++) {
printf("%p code: %c addr: %p\n", cp, cp->code, cp->addr);
}
}
}
void execute() {
Code *cp = codes;
char *mp = memory;
while (cp->code != 0) {
if (debug) step(cp, mp);
switch (cp->code) {
case '>': mp++; break;
case '<': mp--; break;
case '+': (*mp)++; break;
case '-': (*mp)--; break;
case '.': putchar(*mp); break;
case ',': *mp = getchar(); break;
case '[': if (*mp == 0) {cp = cp->addr; continue;} else break;
case ']': cp = cp->addr; continue;
}
cp++;
}
}
int main(int argc, char *argv[]) {
if (argc == 3) debug = 1;
getSource(argv[1]);
analyze();
execute();
return 0;
}