<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Turning air to gold</title>
	<atom:link href="http://bernhardkausler.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bernhardkausler.wordpress.com</link>
	<description>Exploring the thermo-dynamic miracle.</description>
	<lastBuildDate>Sat, 28 Nov 2009 22:14:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='bernhardkausler.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Turning air to gold</title>
		<link>http://bernhardkausler.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://bernhardkausler.wordpress.com/osd.xml" title="Turning air to gold" />
	<atom:link rel='hub' href='http://bernhardkausler.wordpress.com/?pushpress=hub'/>
		<item>
		<title>SinC — The Tiniest LISP Compiler (to Python)</title>
		<link>http://bernhardkausler.wordpress.com/2009/11/28/sinc-%e2%80%94-the-tiniest-lisp-compiler-to-python/</link>
		<comments>http://bernhardkausler.wordpress.com/2009/11/28/sinc-%e2%80%94-the-tiniest-lisp-compiler-to-python/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 21:34:41 +0000</pubDate>
		<dc:creator>Bernhard</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://bernhardkausler.wordpress.com/?p=39</guid>
		<description><![CDATA[Tim Lopez published an elegant and tiny LISP interpreter for Python on his blog. Inspired by Norvig&#8217;s Paradigms of Artificial Intelligence Programming. I developed an interpreter as well as a compiler for LISP in Python. Hence the interpreter is quite similar to Tim Lopez&#8217; implementation, I will present sinC, the s-expression input compiler. SinC compiles [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bernhardkausler.wordpress.com&amp;blog=6994544&amp;post=39&amp;subd=bernhardkausler&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Tim Lopez <a href="http://www.brool.com/index.php/the-tiniest-lisp-in-python">published</a> an elegant and tiny LISP interpreter for Python on his blog. Inspired by Norvig&#8217;s <a href="http://norvig.com/paip.html"><em>Paradigms of Artificial Intelligence Programming</em></a>. I developed an interpreter as well as a <em>compiler</em> for LISP in Python. Hence the interpreter is quite similar to Tim Lopez&#8217; implementation, I will present <strong>sinC</strong>, the <em>s-expression input compiler</em>. <strong>SinC compiles my own proprietary LISP dialect to Python source code.</strong></p>
<p><strong><a href="http://xkcd.com/224/"><img class="alignnone size-full wp-image-49" title="We lost the documentation on quantum mechanics.  You'll have to decode the regexes yourself." src="http://bernhardkausler.files.wordpress.com/2009/11/lisp.jpg?w=500&#038;h=148" alt="We lost the documentation on quantum mechanics.  You'll have to decode the regexes yourself." width="500" height="148" /></a><br />
</strong></p>
<h2>The reader</h2>
<p><pre class="brush: python;">
def read(sexpr):
    grammar = r&quot;(\()|(\))|([^()\s]+)|(\s+)&quot;

    def sequenceBuilder(match):
        leftbracket, rightbracket, atom, whitespace = match.groups()
        if(leftbracket): return '['
        elif(rightbracket): return ']'
        elif(atom): return '&quot;' + atom + '&quot;'
        elif(whitespace): return ','
    return eval(re.sub(grammar, sequenceBuilder, sexpr), None, None)
</pre></p>
<p>The reader converts a s-expression in a corresponding Python list representing the syntax tree. For example:</p>
<pre>(print (+ 1 2)) -&gt; ["print", ["+", "1", "2"]]</pre>
<p>Only alphanumeric characters are allowed in symbols. Especially no strings or brackets. They would break the reader.</p>
<h2>The evaluator</h2>
<p><pre class="brush: python;">
def comp(tree):
    if(type(tree) == list):
        if(tree[0] in specialForms):
            return specialForms.get(tree[0])(tree[1:])
        else:
            args = map(lambda x: comp(x), tree[1:])
            return tree[0] + &quot;(&quot; + &quot;,&quot;.join(args) + &quot;)&quot;
    else:
        return tree
</pre></p>
<p>The evaluator parses the syntax tree recursively. The first symbol in a list is always interpreted as a function and the remaining symbols as its paramters. If the symbol representing the function is found in <em>specialForms</em>, a Python function is called, returning the generated Python source code as a string.</p>
<p><strong>My dialect has the following special forms</strong>:</p>
<pre>set, first, rest, cons, quote, eq, cond</pre>
<p>Additionally, I implemented the algebraic operators &#8216;+&#8217;, &#8216;-&#8217;, &#8216;*&#8217; and &#8216;/&#8217; as special forms for convenience reasons.</p>
<p>Except for the <em>set</em> function, every special form is side effect-free and can be written as a Python lambda-expression. In particular, the evaluator is just nesting calls to pure Python functions.</p>
<h2>The transcription step and the <em>set</em> function</h2>
<p><pre class="brush: python;">
def set(rest):
    if(len(rest) == 2): # a variable
        globalScope.append((comp(rest[0]), comp(rest[1])))
    else: # a function
        globalScope.append((comp(rest[0]), &quot;lambda &quot; + comp(rest[1]).strip(&quot;[]&quot;) +&quot;: &quot; + comp(rest[2])))
    return &quot;None&quot;
</pre></p>
<p>The <em>set</em> function takes care of global variable and function bindings. In Python, such a binding is not possible in a lambda expression. So we evaluate this function to <em>None</em> and store the binding for later use in a <em>globalScope</em>. After parsing the syntax tree, we first generate Python code for the global Scope to establish the bindings and after that append the function calls generated by the comp function.</p>
<p>The whole compiler looks like this:</p>
<p><pre class="brush: python; collapse: true; light: false; toolbar: true;">
#!/usr/bin/env python

import re
import sys

errfile = &quot;&lt;sinc&gt;&quot;

def read(sexpr):
    grammar = r&quot;(\()|(\))|([^()\s]+)|(\s+)&quot;

    def sequenceBuilder(match):
        leftbracket, rightbracket, atom, whitespace = match.groups()
        if(leftbracket): return '['
        elif(rightbracket): return ']'
        elif(atom): return '&quot;' + atom + '&quot;'
        elif(whitespace): return ','
    return eval(re.sub(grammar, sequenceBuilder, sexpr), None, None)

def set(rest):
    if(len(rest) == 2): # a variable
        globalScope.append((comp(rest[0]), comp(rest[1])))
    else: # a function
        globalScope.append((comp(rest[0]), &quot;lambda &quot; + comp(rest[1]).strip(&quot;[]&quot;) +&quot;: &quot; + comp(rest[2])))
    return &quot;None&quot;

specialForms = {
    &quot;set&quot;: set,
    &quot;first&quot;: lambda rest: &quot;(&quot; + comp(rest[0]) + &quot;)[0]&quot;,
    &quot;rest&quot;: lambda rest: &quot;(&quot; + comp(rest[0]) + &quot;)[1:]&quot;,
    &quot;cons&quot;: lambda rest: &quot;[&quot; + comp(rest[0])+&quot;] + &quot; + comp(rest[1]),
    &quot;quote&quot;: lambda rest: &quot;[&quot; + &quot;, &quot;.join(map(lambda x: comp(x), rest)) + &quot;]&quot;,
    &quot;eq&quot;: lambda rest: &quot;(&quot;+comp(rest[0])+&quot; == &quot;+comp(rest[1])+&quot;)&quot;,
    &quot;cond&quot;: lambda rest: &quot;(&quot;+comp(rest[1])+&quot; if &quot;+comp(rest[0])+&quot; else &quot;+comp(rest[2])+&quot;)&quot;,
    &quot;+&quot;: lambda rest: comp(rest[0])+&quot; + &quot;+comp(rest[1]),
    &quot;-&quot;: lambda rest: comp(rest[0])+&quot; - &quot;+comp(rest[1]),
    &quot;*&quot;: lambda rest: &quot;(&quot;+comp(rest[0])+&quot;) * (&quot;+comp(rest[1])+&quot;)&quot;,
    &quot;/&quot;: lambda rest: &quot;(&quot;+comp(rest[0])+&quot;) / (&quot;+comp(rest[1])+&quot;)&quot;
}

globalScope = []
def comp(tree):
    if(type(tree) == list):
        if(tree[0] in specialForms):
            return specialForms.get(tree[0])(tree[1:])
        else:
            args = map(lambda x: comp(x), tree[1:])
            return tree[0] + &quot;(&quot; + &quot;,&quot;.join(args) + &quot;)&quot;
    else:
        return tree

def transcribe(sexpr):
    tree = read(sexpr)
    if(type(tree) == tuple):
        transcripts = []
        for node in tree:
            transcripts.append(comp(node))
        transcript = &quot;\n&quot;.join(transcripts)
    else:
        transcript = comp(tree)

    initCode = []
    for expr in globalScope:
        initCode.append(str(expr[0]) + &quot; = &quot; + str(expr[1]) + &quot;\n&quot;)
    return &quot;&quot;.join(initCode) + transcript

def sinc(sexpr):
    transcript = transcribe(sexpr)
    print transcript

def repl():
    while(True):
        print &quot;sinC&gt; &quot;,
        sys.stdout.flush()
        line = sys.stdin.readline().lstrip(&quot;&gt;&quot;).strip()
        try:
            sinc(line)
        except:
            print &quot;???&quot;

if __name__ == &quot;__main__&quot;:
    if(len(sys.argv) == 2):
        f = open(sys.argv[1])
        sinc(f.read())
        f.close()

    else:
        print &quot;This is sinC-alpha. Interactice LISP to Python compiler.&quot;
        print
        repl()
</pre></p>
<p>Call it with a sourcefile as argument or with no arguments to compile s-expressions interactively (used this a lot for testing).</p>
<h2>Demo program: Series summation</h2>
<p>As a little demo we calculate the series summation of a range and print the result:</p>
<p><pre class="brush: plain;">
(set sum x (cond (eq x 0) 0 (+ (sum (- x 1)) x)))

(set range (quote begin end) (cond (eq begin end) (quote) (cons begin (range (+ begin 1) end))))
(set len list (cond (eq list (quote)) 0 (+ 1 (len (rest list)))))
(set map (quote fun list) (cond (eq list (quote)) (quote) (cons (fun (first list)) (map fun (rest list)))))

(set testrange (range 1 8))

(print (len testrange))
(print testrange)
(print (map sum testrange))
</pre></p>
<p>Call it</p>
<pre>$ ./sinc sum.sinc  | python
7
[1, 2, 3, 4, 5, 6, 7]
[1, 3, 6, 10, 15, 21, 28]</pre>
<p>and <strong>it works</strong>! The generated code looks like this:</p>
<p><pre class="brush: python;">
sum = lambda x: (0 if (x == 0) else sum(x - 1) + x)
range = lambda begin, end: ([] if (begin == end) else [begin] + range(begin + 1,end))
len = lambda list: (0 if (list == []) else 1 + len((list)[1:]))
map = lambda fun, list: ([] if (list == []) else [fun((list)[0])] + map(fun,(list)[1:]))
testrange = range(1,8)
None
None
None
None
None
print(len(testrange))
print(testrange)
print(map(sum,testrange))
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bernhardkausler.wordpress.com/39/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bernhardkausler.wordpress.com/39/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bernhardkausler.wordpress.com/39/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bernhardkausler.wordpress.com&amp;blog=6994544&amp;post=39&amp;subd=bernhardkausler&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bernhardkausler.wordpress.com/2009/11/28/sinc-%e2%80%94-the-tiniest-lisp-compiler-to-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5736f812a96ba3fe8792be56e7186667?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bernhard</media:title>
		</media:content>

		<media:content url="http://bernhardkausler.files.wordpress.com/2009/11/lisp.jpg" medium="image">
			<media:title type="html">We lost the documentation on quantum mechanics.  You'll have to decode the regexes yourself.</media:title>
		</media:content>
	</item>
		<item>
		<title>Turning air to gold</title>
		<link>http://bernhardkausler.wordpress.com/2009/06/20/turning-air-to-gold/</link>
		<comments>http://bernhardkausler.wordpress.com/2009/06/20/turning-air-to-gold/#comments</comments>
		<pubDate>Sat, 20 Jun 2009 12:34:03 +0000</pubDate>
		<dc:creator>tantelore</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bernhardkausler.wordpress.com/?p=22</guid>
		<description><![CDATA[So, a new blog is born. Since I started my diploma thesis, I&#8217;m reading more and more of these scientific blogs. Most of them are written by PhD students. They are a great way to stay in touch with other fields and their communities and learn new things not only about science. So, over the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bernhardkausler.wordpress.com&amp;blog=6994544&amp;post=22&amp;subd=bernhardkausler&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So, a new blog is born.</p>
<p>Since I started my diploma thesis, I&#8217;m reading more and more of these scientific blogs. Most of them are written by PhD students.</p>
<p>They are a great way to stay in touch with other fields and their communities and learn new things not only about science. So, over the last months, I developed the desire to write my own one.</p>
<p>I&#8217;m more and more dragged into science and I believe, that this is, what I want to do the next years. Furthermore, I have the feeling, that I am in a position now to contribute my own view to the blogosphere.</p>
<p>So, let&#8217;s start this! I will not write about what I&#8217;m planning to say here etc., because in  my experience, I will deviate from these plans anyway. Just follow the flow!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bernhardkausler.wordpress.com/22/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bernhardkausler.wordpress.com/22/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bernhardkausler.wordpress.com/22/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bernhardkausler.wordpress.com&amp;blog=6994544&amp;post=22&amp;subd=bernhardkausler&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://bernhardkausler.wordpress.com/2009/06/20/turning-air-to-gold/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/309d2b9a6a7a222a52f50dd10f16726e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Bernhard</media:title>
		</media:content>
	</item>
	</channel>
</rss>
