Brainfuck+2

From Esolang
Jump to navigation Jump to search

Brainfuck+2 is exactly what it sounds: brainfuck, but with 2 more commands (there's actually 3, but Brainfuck+3 was already taken). Those 3 make it easier to handle input and output when dealing with numbers. For more info about brainfuck, check out its wiki page.

Note: All brainfuck programs without extra commands are compatible with Brainfuck+2.

If an input operation receives nothing, the cell will be set to 0.

New brainfuck

+ Adds one to the current cell
- Subtracts one from the current cell
> Moves the memory pointer right one cell
< Moves the memory pointer left one cell
, Takes a single character input from user and stores its Unicode value in the current cell
; Does the same but with a number; sets the cell value to the number
. Outputs the current cell as a Unicode character
: Outputs the current cell as a number. (Having 65 in a cell would output 65, not A)

Overflow mode

' Toggles overflow mode. If on (by default), it will behave like standard brainfuck. If a cell is greater than 255, loop back to 0. Same thing for the other direction: if a cell is less than 0, loop to 255. If off, cells don't have this limit but can only be positive (>0).

Programs

Hello, World!

A Hello, World! program in Brainfuck+2 is the same as one you would see in brainfuck.

>+++++ +++           8 (loop counter)
[
	>
    +++++ ++++       72  (perfect)
    >
    +++++ +++++ ++   96  (5 up) (used twice)
    >
    +++++ +++++ +++  104 (4 up) (used twice)
    >
    +++++ +++++ ++++ 112 (1 down)
    >
    +++++ +          48  (4 down)
    >
    ++++             32  (perfect) (space)
    >
    +++++ +++++ +    84  (1 down)
    >
    +++++ +++++ ++++ 112 (1 down) (used 3 times)
    last one is ! but we can use space and add 1
    
    
    [<]>-
]

>.      H
>+++++. e
>++++.. ll
>-.     o
>----.  (comma)
>.      (space)
>-.     W
<<<.    o
+++.    r
<.      l
<-.     d
>>>>+.  !

Here is the same thing without all the comments and newlines:

>++++++++[>+++++++++>++++++++++++>+++++++++++++>++++++++++++++>++++++>++++>+++++++++++>++++++++++++++[<]>-]>.>+++++.>++++..>-.>----.>.>-.<<<.+++.<.<-.>>>>+.

A+B Problem

Unlike brainfuck, you don't have to handle number input/output yourself, which results in a more simple program:

';>;[<+>-]<:

It turns off overflow mode to accept all unbounded unsigned integers.

Infinite counter

>++++++++++<'+:>.<[+:>.<]

Truth-machine

;[:]:

Fixed Repeating Output

';[>+:-<-]>:

Implementations

Python

import sys
def bfp2(code):
    s=[]
    matches={}
    tape=[0]*1000000
    for i,j in enumerate(code):
        if j=='[':
            s.append(i)
        if j==']':
            m=s.pop()
            matches[m]=i
            matches[i]=m
    cp=0
    p=0
    overflow_mode=True
    while cp<len(code):
        if code[cp]=='+':
            tape[p]=(tape[p]+1)&(255 if overflow_mode else -1)
            tape[p]=max(0,tape[p])
        if code[cp]=='-':
            tape[p]=(tape[p]-1)&(255 if overflow_mode else -1)
            tape[p]=max(0,tape[p])
        if code[cp]==',':
            c=sys.stdin.read(1)
            tape[p]=(ord(c) if c else 0)&(255 if overflow_mode else -1)
            tape[p]=max(0,tape[p])
        if code[cp]==';':
            try:
                tape[p]=int(input())&(255 if overflow_mode else -1)
            except:
                tape[p]=0
            tape[p]=max(0,tape[p])
        if code[cp]=='.':
            print(chr(tape[p]),end='')
        if code[cp]==':':
            print(tape[p],end='')
        if code[cp]=='<':
            p-=1
        if code[cp]=='>':
            p+=1
        if code[cp]=='\'':
            overflow_mode=(not overflow_mode)
        if code[cp]=='[':
            if not tape[p]:
                cp=matches[cp]
        if code[cp]==']':
            if tape[p]:
                cp=matches[cp]
        cp+=1
bfp2(sys.stdin.read())

An integer input should end with a newline.

JavaScript

function bfp2(program,input){
    var stack=[];
    var matches={};
    var ip=0;
    var tape=[];
    var p=0;
    var output='';
    var overflow=true;
    for(let i=0;i<1000000;i++){
        tape.push(0);
    }
    for(var i=0;i<program.length;i++){
        if(program[i]=='['){
            stack.push(i);
        }
        if(program[i]==']'){
            if(stack.length==0){
                throw new Error('Right bracket does not match left bracket');
            }
            var mt=stack.pop();
            matches[mt]=i;
            matches[i]=mt;
        }
    }
    if(stack.length!=0){
        throw new Error('Left bracket does not match right bracket');
    }
    while(ip<program.length){
        if(program[ip]=='+'){
            tape[p]=tape[p]+1;
            ip=ip+1;
        }
        if(program[ip]=='-'){
            tape[p]=tape[p]-1;
            ip=ip+1;
        }
        if(program[ip]=='>'){
            p=p+1;
            if(p>=1000000){
                throw new Error('Pointer overflow');
            }
            ip=ip+1;
        }
        if(program[ip]=='<'){
            p=p-1;
            if(p<0){
                throw new Error('Pointer underflow');
            }
            ip=ip+1;
        }
        if(program[ip]==','){
            if(input==''){
                tape[p]=0;
            }else{
                tape[p]=input.charCodeAt(0);
                input=input.slice(1);
            }
            ip=ip+1;
        }
        if(program[ip]=='.'){
            output+=String.fromCharCode(tape[p]);
            ip=ip+1;
        }
        if(program[ip]==';'){
            matched=input.match(/\d*\s*/);
            input=input.slice(matched[0].length);
            matched=matched[0].match(/\d*/)[0];
            if(isNaN(parseInt(matched))){
                tape[p]=0;
            }else{
                tape[p]=parseInt(matched);
            }
            ip=ip+1;
        }
        if(program[ip]==':'){
            output+=tape[p];
            ip=ip+1;
        }
        if(program[ip]=='\''){
            overflow=!overflow;
            ip=ip+1;
        }
        if(program[ip]=='['){
            if(tape[p]==0){
                ip=matches[ip];
            }else{
                ip=ip+1;
            }
        }
        if(program[ip]==']'){
            if(tape[p]!=0){
                ip=matches[ip];
            }else{
                ip=ip+1;
            }
        }
        if(!('+-,.[]<>:;\''.includes(program[ip]))){
            ip=ip+1;
        }
        tape[p]&=(overflow?255:-1);
        tape[p]=Math.max(tape[p],0);
    }
    return output;
}

External Resources