<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LAMBDAPHONE &#187; MonadTransformers</title>
	<atom:link href="http://coder.bsimmons.name/blog/tag/monadtransformers/feed/" rel="self" type="application/rss+xml" />
	<link>http://coder.bsimmons.name/blog</link>
	<description>fragmentary ideas  ䷿  intellectual what-nots  ䷷  and haskell programming  ䷴</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:58:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Befunge-93 Interpreter on Hackage</title>
		<link>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/</link>
		<comments>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/#comments</comments>
		<pubDate>Thu, 20 May 2010 18:36:42 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[hackage]]></category>
		<category><![CDATA[MonadTransformers]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=413</guid>
		<description><![CDATA[<p>I&#8217;ve fixed a bug related to upgrading GHC to version 6.12 (thanks to Cale and the folks on haskell-cafe who helped me with the issue) and got my <a href="http://en.wikipedia.org/wiki/Befunge">Befunge-93</a> interpreter up on hackage. The program is written in haskell&#8230; <a href="http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve fixed a bug related to upgrading GHC to version 6.12 (thanks to Cale and the folks on haskell-cafe who helped me with the issue) and got my <a href="http://en.wikipedia.org/wiki/Befunge">Befunge-93</a> interpreter up on hackage. The program is written in haskell (as usual). You should be able to get it soon with a:</p>
<blockquote><pre>$> cabal install Befunge93</pre>
</blockquote>
<p>If you want to read about how I designed it you can check out the source above, or take a look at my <a href="http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/">previous blog post</a>.</p>
<p>Please report any bugs to me, and I&#8217;m also very interested in patches or suggestions for performance improvements if anyone ends up being interested in this program.</p>
<p><strong>EDIT</strong>: Here is the package page: <a href="http://hackage.haskell.org/package/Befunge93">http://hackage.haskell.org/package/Befunge93</a></p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Befunge-93 Interpreter</title>
		<link>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/</link>
		<comments>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 21:13:50 +0000</pubDate>
		<dc:creator>jberryman</dc:creator>
				<category><![CDATA[haskell]]></category>
		<category><![CDATA[Array]]></category>
		<category><![CDATA[EsotericLanguages]]></category>
		<category><![CDATA[MonadTransformers]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[state]]></category>

		<guid isPermaLink="false">http://coder.bsimmons.name/blog/?p=302</guid>
		<description><![CDATA[<p><em>I just finished an initial release of an interpreter for the <a href="http://en.wikipedia.org/wiki/Befunge">befunge</a> programming language, based on the <a href="http://catseye.tc/projects/befunge93/">&#8216;93 spec</a>. The project was quite fun! My goal was to produce a well-designed program with performance that didn&#8217;t suck too</em>&#8230; <a href="http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/" class="read_more">   [ R E A D &#124; M O R E ]</a></p>]]></description>
			<content:encoded><![CDATA[<p><em>I just finished an initial release of an interpreter for the <a href="http://en.wikipedia.org/wiki/Befunge">befunge</a> programming language, based on the <a href="http://catseye.tc/projects/befunge93/">&#8216;93 spec</a>. The project was quite fun! My goal was to produce a well-designed program with performance that didn&#8217;t suck too bad. Here are some highlights:</em></p>
<h2>Design</h2>
<p>I found that writing the core functionality of the interpreter took almost no time, once I settled on the approach I would take. I used a monad transformer for the first time, <code>StateT</code>: </p>
<p><blockquote class="vimblock"><br />
<span class="Type">type</span>&nbsp;REPL&nbsp;a&nbsp;<span class="Statement">=</span>&nbsp;StateT&nbsp;ProgramState&nbsp;<span class="Type">IO</span>&nbsp;a<br />
<br /></blockquote></p>
<p>This let me pass around the state of the computation in the <code>State</code> monad while doing IO actions. This made some potentially-awkward befunge commands really easy to implement.<br />
<span id="more-302"></span><br />
Here is an excerpt from the function <code>execute :: Char -> REPL ()</code> which reads the befunge character at our position and returns the code to execute:</p>
<p><blockquote class="vimblock"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Pop value and output as an integer. funge-98 spec calls for</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- integer to be followed by a space, so we'll do that too:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'.'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;i&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liftIO&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">putStr</span>&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">show</span>&nbsp;i&nbsp;<span class="Statement">++</span><span class="Constant">&quot; &quot;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- Pop value and output as ASCII character</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">','</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;i&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; liftIO&nbsp;<span class="Statement">$</span>&nbsp;<span class="Identifier">putChar</span>&nbsp;<span class="Statement">$</span>&nbsp;chr&nbsp;i<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'</span><span class="Special">\\</span><span class="Constant">'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;(a,b)&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop2<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;a<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;b<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">':'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Statement">do</span>&nbsp;a&nbsp;<span class="Statement">&lt;-</span>&nbsp;pop<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; replicateM_&nbsp;<span class="Constant">2</span>&nbsp;(push&nbsp;a)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;<span class="Comment">-- program flow commands: --</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">' '</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;<span class="Identifier">return</span>&nbsp;()&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'&gt;'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;right<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'&lt;'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;left&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'^'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;up<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'v'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;setDirection&nbsp;down<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Constant">'?'</span>&nbsp;<span class="Statement">-&gt;</span>&nbsp;getRandomDirection&nbsp;<span class="Statement">&gt;&gt;=</span>&nbsp;setDirection&nbsp;<br />
<br /></blockquote></p>
<p>And here is the program state that gets passed in the monad:</p>
<p><blockquote class="vimblock"><br />
<span class="Type">data</span>&nbsp;ProgramState&nbsp;<span class="Statement">=</span>&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;ES&nbsp;{&nbsp;<span class="Comment">-- state of the code and stack:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; code&nbsp;<span class="Statement">::</span>&nbsp;Code,&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack&nbsp;<span class="Statement">::</span>&nbsp;Stack,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- state of program flow:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; position&nbsp;<span class="Statement">::</span>&nbsp;Position,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; direction&nbsp;<span class="Statement">::</span>&nbsp;Direction,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; haltBit&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Bool</span>,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- random generator:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; randGen&nbsp;<span class="Statement">::</span>&nbsp;StdGen,&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- errors or other messages we collect:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; messages&nbsp;<span class="Statement">::</span>&nbsp;[<span class="Type">String</span>],<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- should we announce messages and warnings?:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; verbose&nbsp;<span class="Statement">::</span>&nbsp;<span class="Type">Bool</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />
<br /></blockquote></p>
<p>I only use the accessor functions (as opposed to pattern matching) to reach into the state in my code, so it was easy to add another state parameter if I wanted to extend the functionality somewhere.</p>
<p>Finally here is the evaluation loop that ties the core of the interpreter together:</p>
<p><blockquote class="vimblock"><br />
evalLoop&nbsp;<span class="Statement">::</span>&nbsp;REPL&nbsp;()<br />
evalLoop&nbsp;<span class="Statement">=</span>&nbsp;<span class="Statement">do</span><br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- extract the command at our position &amp; execute it:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;getCmd&nbsp;<span class="Statement">&gt;&gt;=</span>&nbsp;execute<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- print messages in the queue (unless quiet), and clear it:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;printMessages<br />
&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">-- halt if @ command issued, else move and recurse:</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;halting&nbsp;<span class="Statement">&lt;-</span>&nbsp;gets&nbsp;haltBit<br />
&nbsp;&nbsp;&nbsp;&nbsp;unless&nbsp;halting&nbsp;(move&nbsp;<span class="Statement">&gt;&gt;</span>&nbsp;evalLoop)&nbsp;<br />
<br /></blockquote></p>
<p>I found the most time-consuming parts of this project were in the design decisions and behaviour tweaks related to holes in the &#8216;93 spec, and tracking down a few silly bugs that came from wrong assumptions about the spec. </p>
<p>Vital in debugging were the <a href="http://users.tkk.fi/~mniemenm/befunge/ccbi.html">CCBI interpreter</a> as well as the <a href="http://mearie.org/projects/pyfunge/">pyfunge interpreter.</a> It&#8217;s difficult to debug an interpreter when you don&#8217;t whether the befunge code you are testing on is buggy or whether your interpreter is!</p>
<p>One last detail that I am proud of is the test suite that I have integrated into my darcs repo. Darcs automatically runs the befunge-93 portion of the amazing <a href="http://iki.fi/matti.niemenmaa/befunge/mycology.html">mycology test suite</a> by Matti Niemenmaa on each commit, as well as two smaller <a href="http://www.phlamethrower.co.uk/befunge/#files">test befunge programs</a> from phlamethrower, testing that the interpreter hasn&#8217;t changed behavior.</p>
<h2>Play With It</h2>
<p>You can check out the full source for the program <a href="http://coder.bsimmons.name/code/Befunge/Befunge.hs">here</a>, or get my whole darcs repository with:</p>
<blockquote><p>
<code>$ darcs get --tag=v0.2 http://coder.bsimmons.name/code/Befunge</code>
</p></blockquote>
<p>And here are a few nice programs to try out, written by folks cleverer than I, and stolen from vsync&#8217;s funge stuff <a href="http://quadium.net/funge/downloads/bef93src/">here</a>.</p>
<p><em>aturley.bf</em> by Andrew Turley:</p>
<blockquote><pre>
>84*>:#v_55+"ude.ub@yelruta">:#,_@>188*+>\02p\12p\:22p#v_$    55+,1-         v
    ^  0 v +1\                   _^#-+*<>22g02g*"_@"*-!1- #v_v>
       >:>::3g: ,\188                  ^^               -1\g21\g22
<p3 \"_":<
________________________________@_________________________________^  p3\"@":<
</pre>
</p3></pre>
</blockquote>
<p><em>life.bf</em> by Dmitry M Litvinov:</p>
<blockquote><pre>
v>>31g> ::51gg:2v++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9p BXY|-+<v3 *89<%+ *                                                      *   +
21 >98 *7^>+\-0|< + *                                                     *    +
*5 ^:+ 1pg15\,:< + *                                                     ***  +
10^  <>$25*,51g1v+                                                            +
-^ p< | -*46p15:+<+                                                            +
> 31^> 151p>92*4v+                                                            +
 ^_ ".",   ^ vp1< +                                                            +
>v >41p      >0 v+                                                            +
:5! vg-1g15-1g14< +                                                            +
+1-+>+41g1-51gg+v+                                                            +
1p-1vg+1g15-1g14< +                                                            +
g61g>+41g51g1-g+v+                                                            +
14*1v4+g+1g15g14< +                           * *                              +
5>^4>1g1+51g1-g+v+                           * *                              +
^ _^v4+gg15+1g14< +                           ***                              +
>v! >1g1+51g1+g+v+                                                            +
g8-v14/*25-*4*88< +                                                            +
19+>g51gg" "- v  +                                                            +
4*5  v< v-2:_3v+                                                            +
 >^   |!-3_$  v< -+                                                            +
^    < <      <|<+                                                         ***+
>g51gp ^ >51gp^>v+                                                            +
^14"+"< ^g14"!"<++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
</pre>
<p></v3></pre>
</blockquote>
<p><em>prime.bf</em> by Kalyna Zazelenchuk:</p>
<blockquote><pre>
222p35*89+*11p>133p                   >33g1+33p   22g33g- v>22g33g%#v_v
 o                                                        >|
  2                             v,,,,, ,,,,,.g22"is prime."< 1                            >    v^                             < ^_@#-g11g22p22+1g22,*25<,,,,,,,,,,,,,.g22"is not prime."<
</pre>
</pre>
</blockquote>
<p>There is still a lot that could be done, but I think I&#8217;m done with it for now. Thanks for looking!</p>
]]></content:encoded>
			<wfw:commentRss>http://coder.bsimmons.name/blog/2010/01/a-befunge-93-interpreter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
