Skip to content

Instantly share code, notes, and snippets.

@TWal
Created July 15, 2013 17:41
Show Gist options
  • Save TWal/6001872 to your computer and use it in GitHub Desktop.
Save TWal/6001872 to your computer and use it in GitHub Desktop.
Brainfuck interpreter in brainfuck (si means "self-interpreter")
>>
>+[[-]+>>>+>++>- >++> ->+>+>+>>+++>+++ ++[<<< <
<<<<++ ++++> >+ ++>>>>++>++++++>-] >>+<<, [>>
-<<[> +<-]] >[<+>- ]>[<< <[<]<< ->>
>[>] >>-]< +++++ ++++[ <<[
>-<- ]>>>+ <<[> >-<<[<+>- ]]<[>+<-]>>> [-<<< <[< ]>[<+>-] >[>]> >>]< <<<[ <]<+>>[>]>[<+>- ]>[<+ >-]<- ]<[
-]+< <[-]> [>-<<<[-]>>[-]]>[ [-]<[ -]<< [>+>>+<<<-]>>> [<<<+>> >-]> >]<< <<]+<<[<<]>>-<+<< +[>>> [>>]> [-[
-[-[-[-[-[-[> [>>]>> [>>]>[ <<<[ <<]< <[<<]>+++++++<< <[<<]>[>[>>] +<-- ---- -<->[>- <[<+> -]]<[ >+<-] >++
++++ +>[<< <<[<< ]>->[ >>]>> -]+< ----- ---[> -<[<+>-]]<[> +<-] >+++ +++++> [<<<<[ <<]>+ >[>
>]>> -]+<< <<[<< ]>]+>[>>]>-- ---- ->[> >]>> [>>]>[< +>-] ]<[> +<-]< <[<<]<<[<<] >[<
+>-] >-<]+ >[[>> ]>>[ >>]>>[ -]+< [>-< [<+> -]]<[ >+<- ]>>[ <<<<[ <<]<<[<<]>+ +
++++ <<<[< <]>[> [>>] +>>-> ---- ---[ >-<[ <+>-] ]<[>+ <-]>+ ++++++ >[<<<< [<<]>
+>[>> ]>>-]+ <---- ---- [>-<[ <+>-]] <[>+ <-]> +++++++ +>[<<<<[<<]>->[ >>]>>-] +<<<< [<<]>] +>[>>
]>------>[>>]>>[> >]>>- ]+<<< <[<<]< <[<<]> >-]< [<+> -]]+>[[ >>]>>[>>]+>>[-] <<[<<]<<[<<]>>-]< [<+>-] ]+>[[ >>]
>>[>>]+<<-<<[<<] <<[<< ]>>-]<[<+> -]] +>[[>> ]>>[ >>]> .<<<[<< ]<<[<<]> >-] <[<+>-]]+>[[>>] >>[>>] >-<<< [<<
]<<[<<]>>-]<[<+>-]]+>[[>>]>>[>>]>,<<<[<<]<<[<<]>>-]<[<+>-]]+>[[>>]>>[>>]>+<<<[<<]<<[<<]>>-]<[<+>-]]<[>+<-]>>[<<<<[<<]<->>>[>>]>>-]<<+[<<]<][-]>+<[<-[+<+<++]]
#cmacro(add;
int i;
int nb = atoi(argv[0]);
if(nb < 0) {
for(i = 0; i < -nb; ++i) {
push("-");
}
} else {
for(i = 0; i < nb; ++i) {
push("+");
}
}
)
#macro(moveTo; v1; v2;;
=v1; [=v2; + =v1; -]
)
#macro(copy; v1; v2; temp;;
=v1; [=v2; + =temp; + =v1; -]
=temp; [ =v1; + =temp; -]
)
#variables(PreProg; continue; zero; bracketDepth; firstFlag)
#variables(ProgDec; continue; instr; zero1; zero2; d0; d1; d2; d3; d4; d5; d6; d7; d8; input; counter; nflag)
#variables(ProgDecFinal; continue; instr; zero1; zero2; input; counter)
#variables(Prog; flag; instr; nflag)
#variables(Mem; flag; m; nflag)
#_ ! + , - . < > [ ]
#_ 33 43 44 45 46 60 62 91 93
#_ 0 1 2 3 4 5 6 7 8
#_ 33 10 1 1 1 14 2 29 2
#_ d8 d7 d6 d5 d4 d3 d2 d1 d0
#_ ---------------------------------------------------------
#_ ---------------------PROGRAM DECODER---------------------
#_ ---------------------------------------------------------
@PreProg@continue;
=firstFlag;
@ProgDec@continue;
+[[-]+
#_ Initialization
=zero2; + =d0; ++ =d1; - =d2; ++ =d3; - =d4; + =d5; + =d6; + =d8; +++
=input; +++++ [=d1; +++ +++ =d3; +++ =d7; ++ =d8; +++ +++ =input; -]
=nflag; + =input; , [
=nflag; -
_moveTo(input; counter)
=input;
] _moveTo(counter; input)
=nflag; [
=d8; [<]
@ProgDec@zero1;
=continue; -
=zero2; [>]
@ProgDec@input;
=nflag; -
]
=counter; _add(9)
#_ Loop
[
#_ input -= d8
=d8;
[=input; - =d8; -]
#_ nflag = !input
=nflag; +
=input;
[
=nflag; -
_moveTo(input; d8)
=input;
]
_moveTo(d8; input)
#_ if(nflag) zero2 -> zero1
=nflag; [ -
=d7;
[<] @ProgDec@zero1;
_moveTo(zero2; zero1)
=d0;
[>] @ProgDec@d8;
=nflag;
]
#_ instr++
=d7;
[<] @ProgDec@zero1;
=instr; +
=zero2;
[>] @ProgDec@d8;
#_ Shift
_moveTo(input; d8)
_moveTo(counter; input)
=counter; <-
]
@ProgDecFinal@counter;
#_ instr zero1 zero2 input
#_ if +-,.[]<> -> n n 0 n continue = n
#_ if ! -> 0 n 0 n continue = 0
#_ if other -> n 0 n n don't shift
#_ continue = instr, don't shift = zero2, clear input & zero1
=input; [-]+
=zero1; [-]
#_ if(don't shift)
=zero2; [
=input;-
=instr;[-]
=zero2;[-]
]
#_ else
=input; [
=input; [-]
=zero2;[-]
_copy(instr; zero1; input) #_ zero1 = the new continue
=input;
>>
]
=continue;
]
#_ Add the terminate instruction (0) and go to PreProg
+ < < [<<]
@PreProg@zero;
##
#macro(instrToMem;;
=flag; >>[>>]>>[>>] @Mem@flag;
)
#macro(memToInstr;;
=flag;<<[<<]<<[<<] @Prog@flag;
)
#macro(instrToPreprog;;
=flag;<<[<<] @PreProg@zero;
)
#macro(preprogToInstr;;
=firstFlag;[>>] @Prog@flag;
)
#_ ---------------------------------------------------------
#_ --------------------PROGRAM EXECUTION--------------------
#_ ---------------------------------------------------------
#_ Set up PreProg, set the first instruction's flag, start the execution loop
=firstFlag; - =bracketDepth; + =continue; + [
#_ Move to the current instruction
_preprogToInstr()
#_ Switch(instr), use next instruction's flag as not-flag
=instr; [
#_ instr > 0
- [
#_ instr > 1
- [
#_ instr > 2
- [
#_ instr > 3
- [
#_ instr > 4
- [
#_ instr > 5
- [
#_ instr > 6
- [
#_ instr > 7 (assume instr == 8) : ']'
_instrToMem()
=m; [
#_ m != 0
_memToInstr()
=instr; _add(7)
_instrToPreprog()
=bracketDepth; [
_preprogToInstr()
=flag; +<<-
=instr; ----- -- [
=nflag; -
_moveTo(instr; flag)
]
_moveTo(flag; instr)
=instr; +++++ ++
=nflag; [
#_ instr == '['
_instrToPreprog()
=bracketDepth; -
_preprogToInstr()
=nflag;
-
] +
=instr; ----- --- [
=nflag; -
_moveTo(instr; flag)
]
_moveTo(flag; instr)
=instr; +++++ +++
=nflag; [
#_ instr == ']'
_instrToPreprog()
=bracketDepth; +
_preprogToInstr()
=nflag;
-
] +
_instrToPreprog()
=bracketDepth;
] +
_preprogToInstr()
=instr; _add(-7)
_instrToMem()
_moveTo(m; flag)
=m;
]
_moveTo(flag; m)
_memToInstr()
_moveTo(instr; flag) =nflag; - =instr;
] + =nflag; [
#_ instr == 7 : '['
_instrToMem()
=nflag; [-]+
=m; [
=nflag; -
_moveTo(m; flag)
=m;
]
_moveTo(flag; m)
=nflag; [
#_ m == 0
_memToInstr()
=instr; _add(6)
_instrToPreprog()
=bracketDepth; [
_preprogToInstr()
=flag; +>>-
=instr; ----- -- [
=nflag; -
_moveTo(instr; flag)
]
_moveTo(flag; instr)
=instr; +++++ ++
=nflag; [
#_ instr == '['
_instrToPreprog()
=bracketDepth; +
_preprogToInstr()
=nflag;
-
] +
=instr; ----- --- [
=nflag; -
_moveTo(instr; flag)
]
_moveTo(flag; instr)
=instr; +++++ +++
=nflag; [
#_ instr == ']'
_instrToPreprog()
=bracketDepth; -
_preprogToInstr()
=nflag;
-
] +
_instrToPreprog()
=bracketDepth;
] +
_preprogToInstr()
=instr; _add(-6)
_instrToMem()
=nflag; -
] +
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 6 : '>'
_instrToMem()
=flag; +
>> [-]
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 5 : '<'
_instrToMem()
=flag; +
<< -
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 4 : '.'
_instrToMem()
=m; .
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 3 : '-'
_instrToMem()
=m; -
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 2 : ','
_instrToMem()
=m; ,
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
] + =nflag; [
#_ instr == 1 : '+'
_instrToMem()
=m; +
_memToInstr()
=nflag; -
] _moveTo(instr; flag) =instr;
]
_moveTo(flag; instr)
=nflag; [
#_ instr = 0 : '!'
_instrToPreprog()
=continue; -
_preprogToInstr()
=nflag; -
] +
#_ End of switch, increment position
=flag; +>>-
_instrToPreprog()
=continue;
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment