Brainfuck JavaScript 编译器

问题描述 投票:0回答:1

我用 javascript 编写了一个 Brainfuck 编译器,它可以很好地使用以下代码: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.++++ +++..+++.>>.<-.<.+++.------.--------.>>+.>++。 (输出:你好世界!) 但嵌套循环会陷入无限循环。嵌套循环: +[-[<<[+[--->]-[<<<]]]>>>-]>-.---.>..>.<<<<-.<+.>>>>>.>.<<.<-. (output: hello world) What sould I modify?

这是代码:

class BrainfuckInterpreter {
    constructor() {
      this.memory = new Array(30000).fill(0); // Brainfuck memory tape
      this.pointer = 0; // Memory pointer
      this.inputBuffer = ''; // Input buffer for ,
      this.outputBuffer = ''; // Output buffer for .
      this.loopStack = []; // Stack to keep track of loop positions
    }
  
    interpret(code, input) {
      this.inputBuffer = input;
      this.outputBuffer = '';
      this.pointer = 0;
      this.loopStack = [];
  
      for (let i = 0; i < code.length; i++) {
        const command = code.charAt(i);
  
        switch (command) {
          case '>':
            this.pointer++;
            break;
  
          case '<':
            this.pointer--;
            break;
  
          case '+':
            this.memory[this.pointer]++;
            break;
  
          case '-':
            this.memory[this.pointer]--;
            break;
  
          case '.':
            this.outputBuffer += String.fromCharCode(this.memory[this.pointer]);
            break;
  
          case ',':
            if (this.inputBuffer.length > 0) {
              this.memory[this.pointer] = this.inputBuffer.charCodeAt(0);
              this.inputBuffer = this.inputBuffer.slice(1);
            } else {
              this.memory[this.pointer] = 0;
            }
            break;
  
            case '[':
              if (this.memory[this.pointer] === 0) {
                  let depth = 1;
                  while (depth > 0) {
                      i++;
                      if (code.charAt(i) === '[') depth++;
                      if (code.charAt(i) === ']') depth--;
                  }
              } else {
                  this.loopStack.push(i);
              }
              break;
          
          case ']':
              if (this.memory[this.pointer] !== 0) {
                  i = this.loopStack[this.loopStack.length - 1];
              } else {
                  this.loopStack.pop();
              }
              break;
              
            }
      }
  
      return this.outputBuffer;
    }
  }
  function Compile()
  {
    // Example usage:
    let code = '+[-[<<[+[--->]-[<<<]]]>>>-]>-.---.>..>.<<<<-.<+.>>>>>.>.<<.<-.';
    let input = '';
    const interpreter = new BrainfuckInterpreter();
    let output = interpreter.interpret(code, input);
    // Display the output
    document.getElementById('output_field').innerText = this.output;
    console.log(output);
  }
javascript nested-loops infinite-loop interpreter brainfuck
1个回答
0
投票

问题是你让记忆细胞变成负值。但是 BF 内存 应该由 bytes 组成,因此您不应允许超出 0..255 范围的值,而应应用模运算。

因此更改

-
+
命令的执行方式如下:

            case '+':
                this.memory[this.pointer] = (this.memory[this.pointer] + 1) % 256;
                break;
      
            case '-':
                this.memory[this.pointer] = (this.memory[this.pointer] + 255) % 256;
                break;

更正片段:

class BrainfuckInterpreter {
    constructor() {
        this.memory = new Array(30000).fill(0); // Brainfuck memory tape
        this.pointer = 0; // Memory pointer
        this.inputBuffer = ''; // Input buffer for ,
        this.outputBuffer = ''; // Output buffer for .
        this.loopStack = []; // Stack to keep track of loop positions
    }
  
    interpret(code, input) {
        this.inputBuffer = input;
        this.outputBuffer = '';
        this.pointer = 0;
        this.loopStack = [];

        for (let i = 0; i < code.length; i++) {
            const command = code.charAt(i);
      
            switch (command) {
            case '>':
                this.pointer++;
                break;
      
            case '<':
                this.pointer--;
                break;
      
            case '+':
                this.memory[this.pointer] = (this.memory[this.pointer] + 1) % 256;
                break;
      
            case '-':
                this.memory[this.pointer] = (this.memory[this.pointer] + 255) % 256;
                break;
      
            case '.':
                this.outputBuffer += String.fromCharCode(this.memory[this.pointer]);
                break;
      
            case ',':
                if (this.inputBuffer.length > 0) {
                    this.memory[this.pointer] = this.inputBuffer.charCodeAt(0);
                    this.inputBuffer = this.inputBuffer.slice(1);
                } else {
                    this.memory[this.pointer] = 0;
                }
                break;
      
            case '[':
                if (this.memory[this.pointer] === 0) {
                    let depth = 1;
                    while (depth > 0) {
                        i++;
                        if (code.charAt(i) === '[') depth++;
                        if (code.charAt(i) === ']') depth--;
                    }
                } else {
                    this.loopStack.push(i);
                }
                break;
              
            case ']':
                if (this.memory[this.pointer] !== 0) {
                    i = this.loopStack[this.loopStack.length - 1];
                } else {
                    this.loopStack.pop();
                }
                break;
                  
            }
        }
      
        return this.outputBuffer;
    }
}

function Compile()
{
    // Example usage:
    let code = '+[-[<<[+[--->]-[<<<]]]>>>-]>-.---.>..>.<<<<-.<+.>>>>>.>.<<.<-.';
    let input = '';
    const interpreter = new BrainfuckInterpreter();
    let output = interpreter.interpret(code, input);
    // Display the output
    //document.getElementById('output_field').innerText = this.output;
    console.log(output);
}

Compile();

© www.soinside.com 2019 - 2024. All rights reserved.