Last active
May 8, 2018 17:39
-
-
Save z-rui/05107484a563b1ac180bf1662cc2d545 to your computer and use it in GitHub Desktop.
Brainf*** interpreter in TeX
This file contains hidden or 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
% Brainf*** interpreter | |
% Usage: | |
% | |
% tex bf <file> | |
% | |
% Be aware that this interpreter is very slow... | |
\newcount\memptr \newcount\maxptr \newcount\minptr | |
\newcount\memval \newcount\maxval \newcount\minval | |
\minptr=0 \maxptr=65535 | |
\minval=0 \maxval=255 | |
\let\inbuf=\empty \let\outbuf=\empty | |
\catcode`\@=11 | |
% Plain old TeX does not have a good (read: expandable) way | |
% to convert from an ASCII codepoint to the actual character... | |
% If using XeTeX/LuaTeX, we could use \Uchar | |
\newtoks\xchar | |
\begingroup\catcode`\^^@=12 | |
\gdef\setxchar{\begingroup\afterassignment\setxch@r\lccode`^^@} | |
\gdef\setxch@r{\lowercase{\global\xchar{^^@}}\endgroup} | |
\endgroup | |
% the machine | |
\newif\ifdirty \newif\ifvalid | |
\def\getmemloc{% | |
\xdef\memloc{\expandafter\noexpand\csname mem\the\memptr\endcsname}% | |
\expandafter\ifx\memloc\relax | |
\expandafter\global | |
\expandafter\chardef\memloc\z@ | |
\fi} | |
\def\readmem{\global\memval\memloc\relax \global\validtrue} | |
\def\maybefetch{\ifvalid\else \getmemloc \readmem \fi} | |
\def\writemem{% | |
\expandafter\global | |
\expandafter\chardef\memloc\memval | |
\global\dirtyfalse} | |
\def\moveptr#1{\ifdirty \ifvalid\else \getmemloc\fi \writemem \fi | |
\checkadvance \memptr #1\minptr \maxptr | |
\global\validfalse} | |
\def\addval#1{\maybefetch | |
\checkadvance \memval #1\minval \maxval | |
\global\dirtytrue} | |
\def\checkadvance#1#2#3#4{% register delta min max | |
\global\advance#1#2\relax | |
\ifnum#1<#3% | |
%\wlog{\string#1 underflow! wrapped to \number#3^^J}% | |
\global#1=#4% | |
\else\ifnum#1>#4% | |
%\wlog{\string#1 overflow! wrapped to \number#2^^J}% | |
\global#1=#3% | |
\fi\fi} | |
\def\gettok#1{\expandafter\gettok@\expandafter#1#1\relax} | |
\def\gettok@#1#2#3\relax{\memval=`#2\relax\xdef#1{#3}} | |
\def\puttok#1{\setxchar=\memval \xdef#1{#1\the\xchar}} | |
\def\morein{\maybeflush \global\read\sixt@@n to\inbuf} | |
\def\flushout{\immediate\write\sixt@@n{\outbuf}% | |
\global\let\outbuf\empty} | |
\def\maybeflush{\relax\ifx\outbuf\empty\else \flushout \fi} | |
% brainf*** commands | |
\def\setcatcode{% | |
\catcode`[\@ne | |
\catcode`]\tw@ | |
\catcode`<\active | |
\catcode`>\active | |
\catcode`+\active | |
\catcode`-\active | |
\catcode`,\active | |
\catcode`.\active} | |
{\setcatcode | |
\gdef<{\moveptr\m@ne} | |
\gdef>{\moveptr\@ne} | |
\gdef+{\addval\@ne} | |
\gdef-{\addval\m@ne} | |
\gdef,{\ifx\inbuf\empty \morein \fi | |
\gettok\inbuf \global\dirtytrue} | |
\gdef.{\maybefetch | |
\ifnum\memval=`\^^J\flushout \else \puttok\outbuf \fi} | |
\gdef\setzero{-} | |
\gdef\bfloop#1{\def\body{#1}% | |
\ifx\body\setzero \expandafter\bfclear % [-] optimization | |
\else \expandafter\bfiterate \fi \dobf} | |
\gdef\bfclear{\ifvalid\else \getmemloc\fi | |
\global\memval\z@ \writemem} | |
\gdef\bfiterate{\maybefetch | |
\ifnum\memval=\z@ \else {\expandafter\dobf\body}\expandafter\bfiterate \fi}} | |
% stream scanner | |
\def\dobf{\futurelet\next\dobf@} | |
\def\dobf@{% | |
\ifcat\noexpand\next\bgroup | |
\let\next\bfloop % let TeX scan a group (balanced [...]) | |
\else\ifcat\noexpand\next\egroup | |
\let\next\relax % we're done | |
\else | |
\let\next\dobf@@ | |
\fi\fi | |
\next}% | |
\def\dobf@@#1{\ifcat\noexpand#1\noexpand~#1\fi \dobf} | |
\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials\do\^^M} | |
\def\readbf#1 {\uncatcodespecials \setcatcode | |
%\loggingall | |
{\expandafter\dobf\input#1 }\maybeflush\end} | |
\expandafter\readbf |
This file contains hidden or 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
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++.. | |
+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment