Created
July 15, 2013 17:41
-
-
Save TWal/6001872 to your computer and use it in GitHub Desktop.
Brainfuck interpreter in brainfuck
(si means "self-interpreter")
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
>> | |
>+[[-]+>>>+>++>- >++> ->+>+>+>>+++>+++ ++[<<< < | |
<<<<++ ++++> >+ ++>>>>++>++++++>-] >>+<<, [>> | |
-<<[> +<-]] >[<+>- ]>[<< <[<]<< ->> | |
>[>] >>-]< +++++ ++++[ <<[ | |
>-<- ]>>>+ <<[> >-<<[<+>- ]]<[>+<-]>>> [-<<< <[< ]>[<+>-] >[>]> >>]< <<<[ <]<+>>[>]>[<+>- ]>[<+ >-]<- ]<[ | |
-]+< <[-]> [>-<<<[-]>>[-]]>[ [-]<[ -]<< [>+>>+<<<-]>>> [<<<+>> >-]> >]<< <<]+<<[<<]>>-<+<< +[>>> [>>]> [-[ | |
-[-[-[-[-[-[> [>>]>> [>>]>[ <<<[ <<]< <[<<]>+++++++<< <[<<]>[>[>>] +<-- ---- -<->[>- <[<+> -]]<[ >+<-] >++ | |
++++ +>[<< <<[<< ]>->[ >>]>> -]+< ----- ---[> -<[<+>-]]<[> +<-] >+++ +++++> [<<<<[ <<]>+ >[> | |
>]>> -]+<< <<[<< ]>]+>[>>]>-- ---- ->[> >]>> [>>]>[< +>-] ]<[> +<-]< <[<<]<<[<<] >[< | |
+>-] >-<]+ >[[>> ]>>[ >>]>>[ -]+< [>-< [<+> -]]<[ >+<- ]>>[ <<<<[ <<]<<[<<]>+ + | |
++++ <<<[< <]>[> [>>] +>>-> ---- ---[ >-<[ <+>-] ]<[>+ <-]>+ ++++++ >[<<<< [<<]> | |
+>[>> ]>>-]+ <---- ---- [>-<[ <+>-]] <[>+ <-]> +++++++ +>[<<<<[<<]>->[ >>]>>-] +<<<< [<<]>] +>[>> | |
]>------>[>>]>>[> >]>>- ]+<<< <[<<]< <[<<]> >-]< [<+> -]]+>[[ >>]>>[>>]+>>[-] <<[<<]<<[<<]>>-]< [<+>-] ]+>[[ >>] | |
>>[>>]+<<-<<[<<] <<[<< ]>>-]<[<+> -]] +>[[>> ]>>[ >>]> .<<<[<< ]<<[<<]> >-] <[<+>-]]+>[[>>] >>[>>] >-<<< [<< | |
]<<[<<]>>-]<[<+>-]]+>[[>>]>>[>>]>,<<<[<<]<<[<<]>>-]<[<+>-]]+>[[>>]>>[>>]>+<<<[<<]<<[<<]>>-]<[<+>-]]<[>+<-]>>[<<<<[<<]<->>>[>>]>>-]<<+[<<]<][-]>+<[<-[+<+<++]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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