BrainFuck 实现问题:
BrainFuck implementation problems:
我坐下来尝试实施 BrainFuck。 syntax 看起来很简单。我无法让愚蠢的事情发挥作用。我已经有一段时间了;我承认我需要睡觉。也许这就是问题所在。解释器没有输出任何东西。我很确定问题很简单;而且我知道在我更好地掌握了我希望这个程序的发展方向之后,我需要模块化一些函数调用。为什么我没有输出?
main.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <memory.h>
#include "list.h"
node file;
node flow;
node memm;
void init() {
file.val = 1;
file.next = 0;
flow.val = 1;
flow.next = 0;
memm.val = 1;
memm.next = 0;
}
int run = 1;
void quit(int val) {
run = 0;
while (file.next) pop(&file);
while (flow.next) pop(&flow);
while (memm.next) pop(&memm);
}
void doop() {
switch (file.val++) {
case '>':
memm.val++;
break;
case '<':
memm.val--;
break;
case '+':
get(&memm, memm.val)->val++;
break;
case '-':
get(&memm, memm.val)->val--;
break;
case '.':
printf("c", get(&memm, memm.val)->val);
fflush(stdout);
break;
case '[':
if (!get(&memm, memm.val)->val)
while (get(&file, file.val)->val != ']')
file.val++;
else push(&flow, file.val);
case ']':
if (get(&memm, memm.val)->val)
file.val = pop(&flow);
}
}
int main(int argc, char** argv) {
int flen, c, i, f_len;
FILE *fh;
char fh_name[] = "test";
signal(SIGINT, quit);
init();
fh = fopen(fh_name, "r");
while (run && (c = fgetc(fh)) != EOF)
push(&file, c);
fclose(fh);
f_len = length(&file);
while (file.val > 0 && file.val < f_len)
doop();
return (EXIT_SUCCESS);
}
list.h
struct node {
int val;
struct node *next;
};
typedef struct node node;
int length(node *n);
void push(node *n, int i);
int pop(node *n);
node *get(node *n, int i);
list.c
#include <stdlib.h>
#include "list.h"
int length(node *m) {
int len = 0;
while (m->next) {
len++;
m = m->next;
}
return len;
}
void push(node *n, int i) {
node *m = n;
while (m->next)
m = m->next;
m->next = malloc(sizeof(struct node));
m->next->val = i;
m->next->next = 0;
}
int pop(node *n) {
node *m = n;
int i = length(n) - 1;
while (i) {
i--;
m = m->next;
}
i = m->next->val;
free(m->next);
m->next = 0;
return i;
}
node *get(node *n, int i) {
node *m = n;
while (i) {
i--;
if (!m->next)
push(n, 0);
m = m->next;
}
return m;
}
test
是 BrainFuck "hello world"
Hello World program
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
<.#>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[
<++++>-]<+.[-]++++++++++.
因为你要睡觉,也因为你的代码乱七八糟,我找到了这个
printf("c", get(&memm, memm.val)->val);
它会打印一个c
,仅此而已,应该是
printf("%c", get(&memm, memm.val)->val);
/* ^ it's the format specifier for the argument */
我怎么这么快就找到了这个?
- 很简单,我启用了编译器警告。
顺便说一句: get(&memm, memm.val)->val
风格真的很糟糕,但是真的很糟糕。
行
switch (file.val++) {
不可能是对的。目前它只是递增文件链的第一个 "val",就像它下面的 "mem.val++"。
我希望您需要去掉该行的 ++,然后做一些关于递增指向指令的指针而不是指令本身的事情。
你的']'指令有误;即使你不打算回去,你也需要做流行音乐。
您的“[”指令部分错误。如果该值从零开始,它当前将跳到第一个“]”,它发现不匹配的“]”。
我坐下来尝试实施 BrainFuck。 syntax 看起来很简单。我无法让愚蠢的事情发挥作用。我已经有一段时间了;我承认我需要睡觉。也许这就是问题所在。解释器没有输出任何东西。我很确定问题很简单;而且我知道在我更好地掌握了我希望这个程序的发展方向之后,我需要模块化一些函数调用。为什么我没有输出?
main.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <memory.h>
#include "list.h"
node file;
node flow;
node memm;
void init() {
file.val = 1;
file.next = 0;
flow.val = 1;
flow.next = 0;
memm.val = 1;
memm.next = 0;
}
int run = 1;
void quit(int val) {
run = 0;
while (file.next) pop(&file);
while (flow.next) pop(&flow);
while (memm.next) pop(&memm);
}
void doop() {
switch (file.val++) {
case '>':
memm.val++;
break;
case '<':
memm.val--;
break;
case '+':
get(&memm, memm.val)->val++;
break;
case '-':
get(&memm, memm.val)->val--;
break;
case '.':
printf("c", get(&memm, memm.val)->val);
fflush(stdout);
break;
case '[':
if (!get(&memm, memm.val)->val)
while (get(&file, file.val)->val != ']')
file.val++;
else push(&flow, file.val);
case ']':
if (get(&memm, memm.val)->val)
file.val = pop(&flow);
}
}
int main(int argc, char** argv) {
int flen, c, i, f_len;
FILE *fh;
char fh_name[] = "test";
signal(SIGINT, quit);
init();
fh = fopen(fh_name, "r");
while (run && (c = fgetc(fh)) != EOF)
push(&file, c);
fclose(fh);
f_len = length(&file);
while (file.val > 0 && file.val < f_len)
doop();
return (EXIT_SUCCESS);
}
list.h
struct node {
int val;
struct node *next;
};
typedef struct node node;
int length(node *n);
void push(node *n, int i);
int pop(node *n);
node *get(node *n, int i);
list.c
#include <stdlib.h>
#include "list.h"
int length(node *m) {
int len = 0;
while (m->next) {
len++;
m = m->next;
}
return len;
}
void push(node *n, int i) {
node *m = n;
while (m->next)
m = m->next;
m->next = malloc(sizeof(struct node));
m->next->val = i;
m->next->next = 0;
}
int pop(node *n) {
node *m = n;
int i = length(n) - 1;
while (i) {
i--;
m = m->next;
}
i = m->next->val;
free(m->next);
m->next = 0;
return i;
}
node *get(node *n, int i) {
node *m = n;
while (i) {
i--;
if (!m->next)
push(n, 0);
m = m->next;
}
return m;
}
test
是 BrainFuck "hello world"
Hello World program
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
<.#>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[
<++++>-]<+.[-]++++++++++.
因为你要睡觉,也因为你的代码乱七八糟,我找到了这个
printf("c", get(&memm, memm.val)->val);
它会打印一个c
,仅此而已,应该是
printf("%c", get(&memm, memm.val)->val);
/* ^ it's the format specifier for the argument */
我怎么这么快就找到了这个?
- 很简单,我启用了编译器警告。
顺便说一句: get(&memm, memm.val)->val
风格真的很糟糕,但是真的很糟糕。
行
switch (file.val++) {
不可能是对的。目前它只是递增文件链的第一个 "val",就像它下面的 "mem.val++"。
我希望您需要去掉该行的 ++,然后做一些关于递增指向指令的指针而不是指令本身的事情。
你的']'指令有误;即使你不打算回去,你也需要做流行音乐。
您的“[”指令部分错误。如果该值从零开始,它当前将跳到第一个“]”,它发现不匹配的“]”。