Self-modifying Brainfuck Sharp

From Esolang
Jump to navigation Jump to search
The title of this article is not correct because of technical limitations. The correct title is actually Self-modifying Brainfuck#.

Self-modifying Brainfuck# or SMBF# is a variation of Self-modifying Brainfuck by User:None1.

Its only difference from Self-modifying Brainfuck is that the IP in Self-modifying Brainfuck# starts out in the first cell (also known as the origin), while the IP in Self-modifying Brainfuck starts out in the cell right after the code.

Some programs shown in Self-modifying Brainfuck needs cell on the left of origin, which is not mentioned in its specification. But the specification of Self-modifying Brainfuck# doesn't require this.

Examples

Hello World

Hello World!
----------[++++++++++.>----------]++++++++++

Note: The line feed is MANDATORY

Cat Program

,[.,]

Quine

[.>]

A quine with some customized text is shown in the following:

[.>]QUINES ARE EASY!

Turing completeness

Since brainfuck is Turing complete, then Self-modifying Brainfuck# is.

Interpreter

Here is an interpreter by User:None1 in JavaScript.

function smbf_sharp(program,input){
    var loop=0;
    var matches={};
    var ip=0;
    var tape=[];
    var p=0;
    var output='';
    for(let i of program){
        tape.push(i.charCodeAt(0));
    }
    for(let i=0;i<1000000;i++){
        tape.push(0);
    }
    while(ip<program.length){
        console.log(ip);
        console.log(String.fromCharCode(tape[ip]));
        console.log(tape.slice(0,40));
        if(String.fromCharCode(tape[ip])=='+'){
            tape[p]=tape[p]+1;
            if(tape[p]==256) tape[p]=0;
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])=='-'){
            tape[p]=tape[p]-1;
            if(tape[p]==-1) tape[p]=255;
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])=='>'){
            p=p+1;
            if(p>=1000000){
                throw new Error('Pointer overflow');
            }
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])=='<'){
            p=p-1;
            if(p<0){
                throw new Error('Pointer underflow');
            }
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])==','){
            if(input==''){
                tape[p]=0;
            }else{
                tape[p]=input.charCodeAt(0)%256;
                input=input.slice(1);
            }
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])=='.'){
            output+=String.fromCharCode(tape[p]);
            ip=ip+1;
        }
        if(String.fromCharCode(tape[ip])=='['){
            if(tape[p]==0){
                loop=1;
                while(loop>0){
                    ip++;
                    if(String.fromCharCode(tape[ip])=='['){
                        loop++;
                    }
                    if(String.fromCharCode(tape[ip])==']'){
                        loop--;
                    }
                }
            }
            ip++;
        }
        if(String.fromCharCode(tape[ip])==']'){
            loop=1;
            while(loop>0){
                ip--;
                if(String.fromCharCode(tape[ip])=='['){
                    loop--;
                }
                if(String.fromCharCode(tape[ip])==']'){
                    loop++;
                }
                console.log(loop,ip,tape[ip]);
            }
        }
        if(!('+-,.[]<>'.includes(String.fromCharCode(tape[ip])))){
            ip=ip+1;
        }
    }
    return output;
}

Here is another interpreter in C# also by User:None1.

using System;
public class SMBF_Sharp
{
    private static int loop = 0, cnt = 0;
    private static string program = "";
    private static int[] tape = new int[1000000];
    static void read()
    {
        int ch;
        while ((ch = Console.Read()) != -1)
        {
            program += Convert.ToChar(ch);
            tape[cnt++] = ch;
        }
    }
    static void smbf_run() {
        int ip = 0, p = 0;
        while (ip < program.Length)
        {
            switch (tape[ip])
            {
                case '+':
                    {
                        tape[p] = tape[p] + 1;
                        if (tape[p] > 255)
                        {
                            tape[p] = 0;
                        }
                        break;
                    }
                case '-':
                    {
                        tape[p] = tape[p] - 1;
                        if (tape[p] < 0)
                        {
                            tape[p] = 255;
                        }
                        break;
                    }
                case ',':
                    {
                        tape[p] = Console.Read();
                        if (tape[p] == -1)
                        {
                            tape[p] = 0;
                        }
                        break;
                    }
                case '.':
                    {
                        Console.Write(Convert.ToChar(tape[p]));
                        break;
                    }
                case '<':
                    {
                        p--;
                        if(p < 0)
                        {
                            Console.WriteLine("Pointer underflow");
                            return;
                        }
                        break;
                    }
                case '>':
                    {
                        p++;
                        if (p >= 1000000)
                        {
                            Console.WriteLine("Pointer overflow");
                            return;
                        }
                        break;
                    }
                case '[':
                    {
                        if (tape[p] == 0)
                        {
                            loop = 1;
                            while (loop > 0)
                            {
                                ip++;
                                if (tape[ip] == 91)
                                {
                                    loop++;
                                }
                                if (tape[ip] == 93)
                                {
                                    loop--;
                                }
                            }
                        }
                        break;
                    }
                case ']':
                    {
                        loop = 1;
                        while (loop > 0)
                        {
                            ip--;
                            if (tape[ip] == 91)
                            {
                                loop--;
                            }
                            if (tape[ip] == 93)
                            {
                                loop++;
                            }
                        }
                        ip--;
                        break;
                    }
            }
            ip++;
        }
    }
    static void Main(string[] args)
    {
        read();smbf_run();Console.WriteLine(""); // Weird behavior: If I don't add the writeline, the console gave me "ello World!", but it gave me "Hello World!" when I redirect output to file.
    }
}

External Resources