1

私は座って、BrainFuck を実装しようとしました。構文はかなり単純なようです。ばかげたことを機能させるのに苦労しています。私はこれをしばらくしてきました。睡眠が必要だと認めます。多分それがすべての問題です。インタプリタは何も出力していません。問題は単純なものだと確信しています。そして、このプログラムの方向性をよりよく把握した後、いくつかの関数呼び出しをモジュール化する必要があることを知っています。出力が得られないのはなぜですか?

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ブレインファックの「ハローワールド」です

Hello World program
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]
<.#>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[
<++++>-]<+.[-]++++++++++.
4

2 に答える 2

3

この線

switch (file.val++) {

ただ正しくはありません。現在、その下の「mem.val++」のように、ファイルチェーンの最初の「val」をインクリメントしているだけです。

その行の ++ を取り除き、命令自体ではなく、命令へのポインターをインクリメントすることについて何かをする必要があると思います。


あなたの ']' 命令は間違っています。戻らなくてもポップをする必要があります。


あなたの「[」命令は部分的に間違っています。値がゼロから始まる場合、現在、一致する「]」が見つからない最初の「]」にスキップします。

于 2015-03-06T21:31:09.143 に答える
3

それはあなたが眠る必要があり、またあなたのコードが乱雑であるためです、私はこれを見つけました

printf("c", get(&memm, memm.val)->val);

それはaを出力cし、それだけです、それはそうあるべきです

printf("%c", get(&memm, memm.val)->val);
/*      ^ it's the format specifier for the argument */

どうやってこれをそんなに早く見つけたの?

  • 非常に簡単です。コンパイラの警告を有効にしました。

ところで:get(&memm, memm.val)->valスタイルは本当に悪いですが、本当に悪いです。

于 2015-03-06T21:09:23.307 に答える