美文网首页
快速撸出一个Brainfuck语言解释器

快速撸出一个Brainfuck语言解释器

作者: yfgeek | 来源:发表于2017-11-30 22:43 被阅读164次

    一直都知道一个很有趣的语言,Brainfuck,只是一直尚未研究,今天晚上看了一下,竟然不是那么难,而且还撸出来了一个解释器。这是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。

    就象它的名字所暗示的,brainfuck程序很难读懂。尽管如此,brainfuck图灵机一样可以完成任何计算任务。虽然brainfuck的计算方式如此与众不同,但它确实能够正确运行。

    这种语言基于一个简单的机器模型,除了指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。

    下面是这八种状态的描述,其中每个状态由一个字符标识:

    字符 含义
    > 指针加一
    < 指针减一
    + 指针指向的字节的值加一
    - 指针指向的字节的值减一
    . 输出指针指向的单元内容(ASCII码)
    , 输入内容到指针指向的单元(ASCII码)
    [ 如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处
    ] 如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处

    举个例子,hello world

    [ This program prints "Hello World!" and a newline to the screen, its
      length is 106 active command characters [it is not the shortest.]
     
      This loop is a "comment loop", it's a simple way of adding a comment
      to a BF program such that you don't have to worry about any command
      characters. Any ".", ",", "+", "-", "<" and ">" characters are simply
      ignored, the "[" and "]" characters just have to be balanced.
    ]
    +++++ +++               Set Cell #0 to 8
    [
        >++++               Add 4 to Cell #1; this will always set Cell #1 to 4
        [                   as the cell will be cleared by the loop
            >++             Add 2 to Cell #2
            >+++            Add 3 to Cell #3
            >+++            Add 3 to Cell #4
            >+              Add 1 to Cell #5
            <<<<-           Decrement the loop counter in Cell #1
        ]                   Loop till Cell #1 is zero; number of iterations is 4
        >+                  Add 1 to Cell #2
        >+                  Add 1 to Cell #3
        >-                  Subtract 1 from Cell #4
        >>+                 Add 1 to Cell #6
        [<]                 Move back to the first zero cell you find; this will
                            be Cell #1 which was cleared by the previous loop
        <-                  Decrement the loop Counter in Cell #0
    ]                       Loop till Cell #0 is zero; number of iterations is 8
     
    The result of this is:
    Cell No :   0   1   2   3   4   5   6
    Contents:   0   0  72 104  88  32   8
    Pointer :   ^
     
    >>.                     Cell #2 has value 72 which is 'H'
    >---.                   Subtract 3 from Cell #3 to get 101 which is 'e'
    +++++++..+++.           Likewise for 'llo' from Cell #3
    >>.                     Cell #5 is 32 for the space
    <-.                     Subtract 1 from Cell #4 for 87 to give a 'W'
    <.                      Cell #3 was set to 'o' from the end of 'Hello'
    +++.------.--------.    Cell #3 for 'rl' and 'd'
    >>+.                    Add 1 to Cell #5 gives us an exclamation point
    >++.                    And finally a newline from Cell #6
    

    自己看下原理并不难,于是自己撸了一个解释器,话不多说直接上代码,用es6写的。

    /**
     * Brainfuck Interpreter
     * author: yfgeek
     * https://github.com/yfgeek
     */
    'use strict';
    
    class Interpreter{
        constructor(code,input) {
            this.code = code.trim().replace(/ /g, "").replace(/(\r\n|\n|\r)/gm,"").split("");
            this.input = input || [];
            this.pointer = 0;
            this.codePointer = 0 ;
            this.dataset = [];
            this.bracketStack = [];
            this.output = [];
        }
    
        operation(str){
    
            switch(str){
                case '+':  {
                    this.dataset[this.pointer] = this.dataset[this.pointer] || 0;
                    ++this.dataset[this.pointer];
                    break;
                }
    
                case  '-':  {
                    this.dataset[this.pointer] = this.dataset[this.pointer] || 0;
                    --this.dataset[this.pointer];
                    break;
                }
    
                case  '<':{
                    this.pointer = --this.pointer<0 ? 0: this.pointer;
                    break;
                }
    
                case '>': {
                    this.pointer++;
                    break;
                }
    
                case '.':{
                    this.output.push(String.fromCharCode(this.dataset[this.pointer]));
                    break;
                }
    
                case ',':{
                    let c = this.input.shift();
                    if (typeof c === "string") {
                        this.dataset[this.pointer] = c.charCodeAt(0);
                    }
                    break;
                }
    
                case '[': {
                    this.leftBracket();
                    break;
                }
    
                case ']': {
                    this.rightBracket();
                    break;
                }
            }
    
        };
    
        leftBracket(){
            let openBrackets = 1;
            if (this.dataset[this.pointer]) {
                this.bracketStack.push(this.codePointer);
            } else {
                while (openBrackets && this.code[++this.codePointer]) {
                    if (this.code[this.codePointer] === ']') {
                        openBrackets--;
                    } else if (this.code[this.codePointer] === '[') {
                        openBrackets++;
                    }
                }
            }
        }
    
        rightBracket(){
            this.codePointer =  this.bracketStack.pop() - 1;
        }
    
        run(){
            let list = ['+','-','<','>','.',',','[',']'];
            do{
               let c = this.code[this.codePointer];
               if(list.indexOf(c) >= 0)  this.operation(c);
            }while(++this.codePointer < this.code.length);
            return this.output;
        }
    
        toString(){
            return this.run().join('');
        }
    
    }
    
    let code = '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.';
    let i = new Interpreter(code,[]);
    console.log(i.toString());
    

    相关文章

      网友评论

          本文标题:快速撸出一个Brainfuck语言解释器

          本文链接:https://www.haomeiwen.com/subject/xngbbxtx.html