Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1111 lines (797 sloc) 47.5 KB
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Bootstrapping a Language</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="title" content="Bootstrapping a Language"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2012-06-27T11:40-0400"/>
<meta name="author" content="Aaron Bedra"/>
<meta name="description" content=""/>
<meta name="keywords" content=""/>
<link rel="stylesheet" type="text/css" href="common.css" />
<link rel="stylesheet" type="text/css" href="screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="projection.css" media="projection" />
<link rel="stylesheet" type="text/css" href="presenter.css" media="presenter" />
</head>
<body>
<div id="preamble">
</div>
<div id="content">
<h1 class="title">Bootstrapping a Language</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 Bootstrapping A Language</a></li>
<li><a href="#sec-2">2 Once upon a time there was a REPL</a></li>
<li><a href="#sec-3">3 But that REPL didn't do much</a></li>
<li><a href="#sec-4">4 This is the true story&hellip; of several lines of code&hellip; picked to live in a REPL&hellip; to work together and have their lines executed&hellip; find out what happens when code stops being polite&hellip; and starts getting real&hellip;</a></li>
<li><a href="#sec-5">5 Everyone should write a language</a></li>
<li><a href="#sec-6">6 :slide:</a></li>
<li><a href="#sec-7">7 Peter Norvig</a></li>
<li><a href="#sec-8">8 The basics</a></li>
<li><a href="#sec-9">9 Let's start turning our REPL into a real language</a></li>
<li><a href="#sec-10">10 Turning the lisp source into tokens (Read)</a></li>
<li><a href="#sec-11">11 What it looks like</a></li>
<li><a href="#sec-12">12 Basic Evaluation</a></li>
<li><a href="#sec-13">13 Did we take a step back?</a></li>
<li><a href="#sec-14">14 We need a way to keep track of things so we can refer to them later</a></li>
<li><a href="#sec-15">15 Update eval to accept an env and repl to initialize an env</a></li>
<li><a href="#sec-16">16 Give it a try</a></li>
<li><a href="#sec-17">17 But our language still doesn't really know how to do anything&hellip;</a></li>
<li><a href="#sec-18">18 Define the basic primitives</a></li>
<li><a href="#sec-19">19 Now we're cooking</a></li>
<li><a href="#sec-20">20 Bootstrapping more basic functions</a></li>
<li><a href="#sec-21">21 Try it out</a></li>
<li><a href="#sec-22">22 We're almost there! Let's round things out</a></li>
<li><a href="#sec-23">23 Take in your new awesomeness</a></li>
<li><a href="#sec-24">24 We now have the basics of a language</a></li>
<li><a href="#sec-25">25 But we are missing a lot</a></li>
<li><a href="#sec-26">26 In case Lisp isn't your thing&hellip;</a></li>
<li><a href="#sec-27">27 Let's look at another toy language</a></li>
<li><a href="#sec-28">28 LLVM</a></li>
<li><a href="#sec-29">29 ???</a></li>
<li><a href="#sec-30">30 Tokenization</a></li>
<li><a href="#sec-31">31 &hellip;</a></li>
<li><a href="#sec-32">32 AST</a></li>
<li><a href="#sec-33">33 &hellip;</a></li>
<li><a href="#sec-34">34 &hellip;</a></li>
<li><a href="#sec-35">35 Parsing</a></li>
<li><a href="#sec-36">36 Codegen</a></li>
<li><a href="#sec-37">37 Handlers</a></li>
<li><a href="#sec-38">38 Interactive shell</a></li>
<li><a href="#sec-39">39 Putting it all together</a></li>
<li><a href="#sec-40">40 Giving it a spin</a></li>
<li><a href="#sec-41">41 &hellip;</a></li>
<li><a href="#sec-42">42 THIS IS FUN!</a></li>
<li><a href="#sec-43">43 You can learn a so much by doing this!</a></li>
<li><a href="#sec-44">44 You will think more about how your programming language does this!</a></li>
<li><a href="#sec-45">45 You might even explore the implementation of your language to see how it works!</a></li>
<li><a href="#sec-46">46 References</a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-2">
<h2 id="sec-1"><span class="section-number-2">1</span> Bootstrapping A Language &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span>&nbsp;<span class="title">title</span></span></h2>
<div class="outline-text-2" id="text-1">
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="sec-2"><span class="section-number-2">2</span> Once upon a time there was a REPL &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-2">
<pre class="src src-ruby"><span style="color: #b22222;">#</span><span style="color: #b22222;">!/usr/bin/env ruby</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">repl</span>
<span style="color: #7f007f;">while</span> <span style="color: #a0522d;">true</span>
<span style="color: #8b2252;">"geeklisp&gt; "</span>.display
p(gets)
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
repl
</pre>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="sec-3"><span class="section-number-2">3</span> But that REPL didn't do much &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-3">
<pre class="src src-sh">$ ./geeklisp
</pre>
<pre class="src src-scheme">geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">foo</span> 2)
(<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">foo</span> 2)
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">bar</span> 5)
(<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">bar</span> 5)
geeklisp&gt; (+ foo bar)
(+ foo bar)
geeklisp&gt;
</pre>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="sec-4"><span class="section-number-2">4</span> This is the true story&hellip; of several lines of code&hellip; picked to live in a REPL&hellip; to work together and have their lines executed&hellip; find out what happens when code stops being polite&hellip; and starts getting real&hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-4">
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h2 id="sec-5"><span class="section-number-2">5</span> Everyone should write a language &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-5">
</div>
</div>
<div id="outline-container-6" class="outline-2">
<h2 id="sec-6"><span class="section-number-2">6</span> &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-6">
<p><img src="lisplogo.png" alt="lisplogo.png" />
</p></div>
</div>
<div id="outline-container-7" class="outline-2">
<h2 id="sec-7"><span class="section-number-2">7</span> Peter Norvig &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-7">
<p><img src="norvig.jpg" alt="norvig.jpg" />
</p></div>
</div>
<div id="outline-container-8" class="outline-2">
<h2 id="sec-8"><span class="section-number-2">8</span> The basics &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-8">
<table border="2" cellspacing="0" cellpadding="6" rules="all" frame="border" align="center">
<caption></caption>
<colgroup><col class="left" /><col class="left" /><col class="left" />
</colgroup>
<thead>
<tr><th scope="col" class="left">Form</th><th scope="col" class="left">Syntax</th><th scope="col" class="left">Example</th></tr>
</thead>
<tbody>
<tr><td class="left">variable reference</td><td class="left"><code>var</code></td><td class="left"><code>x</code></td></tr>
<tr><td class="left">constant literal</td><td class="left"><code>number</code></td><td class="left"><code>12</code></td></tr>
<tr><td class="left">quotation</td><td class="left"><code>(quote exp)</code></td><td class="left"><code>(quote (1 2 3))</code></td></tr>
<tr><td class="left">conditional</td><td class="left"><code>(if test conseq alt)</code></td><td class="left"><code>(if (&lt; 10 20) #t #f)</code></td></tr>
<tr><td class="left">assignment</td><td class="left"><code>(set! var exp)</code></td><td class="left"><code>(set! x (* x x))</code></td></tr>
<tr><td class="left">definition</td><td class="left"><code>(define var exp)</code></td><td class="left"><code>(define r 3)</code></td></tr>
<tr><td class="left">procedure</td><td class="left"><code>(lambda (var...) exp)</code></td><td class="left"><code>(lambda (r) (* r r)))</code></td></tr>
<tr><td class="left">sequencing</td><td class="left"><code>(begin exp)</code></td><td class="left"><code>(begin (set! x 1) (* x 2))</code></td></tr>
<tr><td class="left">procedure call</td><td class="left"><code>(proc exp)</code></td><td class="left"><code>(square 12)</code></td></tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-9" class="outline-2">
<h2 id="sec-9"><span class="section-number-2">9</span> Let's start turning our REPL into a real language &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-9">
</div>
</div>
<div id="outline-container-10" class="outline-2">
<h2 id="sec-10"><span class="section-number-2">10</span> Turning the lisp source into tokens (Read) &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-10">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">to_atom</span>(src)
<span style="color: #7f007f;">return</span> <span style="color: #8b2252;">"["</span> <span style="color: #7f007f;">if</span> src ==<span style="color: #8b2252;">'('</span>
<span style="color: #7f007f;">return</span> <span style="color: #8b2252;">"]"</span> <span style="color: #7f007f;">if</span> src ==<span style="color: #8b2252;">')'</span>
<span style="color: #7f007f;">return</span> src <span style="color: #7f007f;">if</span> src =~ <span style="color: #8b2252;">/^-?\d+$/</span> || src =~ <span style="color: #8b2252;">/^-?\d*\.\d+$/</span>
<span style="color: #8b2252;">':'</span> + src
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">read</span>(src)
tokens = src.gsub(<span style="color: #8b2252;">'('</span>, <span style="color: #8b2252;">' ( '</span>).gsub(<span style="color: #8b2252;">')'</span>, <span style="color: #8b2252;">' ) '</span>).split
<span style="color: #228b22;">Kernel</span>.eval(tokens.map{|s| to_atom(s)}.join(<span style="color: #8b2252;">' '</span>).gsub(<span style="color: #8b2252;">' ]'</span>,<span style="color: #8b2252;">']'</span>).gsub(<span style="color: #8b2252;">/([^\[]) /</span>,<span style="color: #8b2252;">'\1, '</span>))
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">repl</span>
<span style="color: #7f007f;">while</span> <span style="color: #a0522d;">true</span>
<span style="color: #8b2252;">"geeklisp&gt; "</span>.display
p(read(gets))
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-11" class="outline-2">
<h2 id="sec-11"><span class="section-number-2">11</span> What it looks like &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-11">
<pre class="src src-scheme">$ ./geeklisp
geeklisp&gt; (+ 2 3)
[<span style="color: #483d8b;">:+</span>, 2, 3]
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">sqr</span> (<span style="color: #7f007f;">lambda</span> (x) (* x x)))
[<span style="color: #483d8b;">:define</span>, <span style="color: #483d8b;">:sqr</span>, [<span style="color: #483d8b;">:lambda</span>, [<span style="color: #483d8b;">:x</span>], [<span style="color: #483d8b;">:*</span>, <span style="color: #483d8b;">:x</span>, <span style="color: #483d8b;">:x</span>]]]
geeklisp&gt; sqr
<span style="color: #483d8b;">:sqr</span>
geeklisp&gt; (sqr 2)
[<span style="color: #483d8b;">:sqr</span>, 2]
</pre>
</div>
</div>
<div id="outline-container-12" class="outline-2">
<h2 id="sec-12"><span class="section-number-2">12</span> Basic Evaluation &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-12">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">eval</span>(x)
<span style="color: #7f007f;">return</span> x <span style="color: #7f007f;">if</span> !x.is_a? <span style="color: #228b22;">Array</span>
<span style="color: #7f007f;">case</span> x[0]
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:quote</span> <span style="color: #7f007f;">then</span> x[1..-1]
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">repl</span>
<span style="color: #7f007f;">while</span> <span style="color: #a0522d;">true</span>
<span style="color: #8b2252;">"geeklisp&gt; "</span>.display
p(eval(read(gets)))
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-13" class="outline-2">
<h2 id="sec-13"><span class="section-number-2">13</span> Did we take a step back? &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-13">
<pre class="src src-scheme">$ ./geeklisp
geeklisp&gt; (+ 2 3)
nil
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">sqr</span> (<span style="color: #7f007f;">lambda</span> (x) (* x x)))
nil
geeklisp&gt; (sqr 4)
nil
geeklisp&gt; (quote (1 2 3 4))
[[1, 2, 3, 4]]
</pre>
</div>
</div>
<div id="outline-container-14" class="outline-2">
<h2 id="sec-14"><span class="section-number-2">14</span> We need a way to keep track of things so we can refer to them later &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-14">
<pre class="src src-ruby"><span style="color: #7f007f;">class</span> <span style="color: #228b22;">Env</span> &lt; <span style="color: #228b22;">Hash</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">initialize</span>(keys=[], vals=[], outer=<span style="color: #a0522d;">nil</span>)
<span style="color: #a0522d;">@outer</span> = outer
keys.zip(vals).each{|p| store(*p)}
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">[]</span> (name)
<span style="color: #7f007f;">super</span>(name) || <span style="color: #a0522d;">@outer</span>[name]
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">set</span>(name, value)
key?(name) ? store(name, value) : <span style="color: #a0522d;">@outer</span>.set(name, value)
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-15" class="outline-2">
<h2 id="sec-15"><span class="section-number-2">15</span> Update eval to accept an env and repl to initialize an env &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-15">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">eval</span>(symbol, env)
<span style="color: #7f007f;">return</span> env[symbol] <span style="color: #7f007f;">if</span> symbol.is_a? <span style="color: #228b22;">Symbol</span>
<span style="color: #7f007f;">return</span> symbol <span style="color: #7f007f;">if</span> !symbol.is_a? <span style="color: #228b22;">Array</span>
<span style="color: #7f007f;">case</span> symbol[0]
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:quote</span> <span style="color: #7f007f;">then</span> symbol[1..-1]
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:define</span> <span style="color: #7f007f;">then</span> env[symbol[1]] = eval(symbol[2], env)
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:set!</span> <span style="color: #7f007f;">then</span> env.set(symbol[1], eval(symbol[2], env))
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:env</span> <span style="color: #7f007f;">then</span> env
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">repl</span>
env = <span style="color: #228b22;">Env</span>.new
<span style="color: #7f007f;">while</span> <span style="color: #a0522d;">true</span>
<span style="color: #8b2252;">"geeklisp&gt; "</span>.display
p(eval(read(gets), env))
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-16" class="outline-2">
<h2 id="sec-16"><span class="section-number-2">16</span> Give it a try &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-16">
<pre class="src src-scheme">./geeklisp
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">foo</span> 5)
5
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">sqr</span> (<span style="color: #7f007f;">lambda</span> (x) (* x x)))
nil
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">bar</span> 27)
27
geeklisp&gt; foo
5
geeklisp&gt; bar
27
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">baz</span> (quote (1 2 3)))
[[1, 2, 3]]
geeklisp&gt; (env)
{<span style="color: #483d8b;">:foo=&gt;5</span>, <span style="color: #483d8b;">:sqr=&gt;nil</span>, <span style="color: #483d8b;">:bar=&gt;27</span>, <span style="color: #483d8b;">:baz=&gt;</span>[[1, 2, 3]]}
</pre>
</div>
</div>
<div id="outline-container-17" class="outline-2">
<h2 id="sec-17"><span class="section-number-2">17</span> But our language still doesn't really know how to do anything&hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-17">
<pre class="src src-scheme">$ ./geeklisp
geeklisp&gt; (+ 2 3)
nil
geeklisp&gt; (car (1 2 3))
nil
geeklisp&gt; (cdr (1 2 3))
nil
geeklisp&gt; (+ (* 3 4) 5)
nil
</pre>
</div>
</div>
<div id="outline-container-18" class="outline-2">
<h2 id="sec-18"><span class="section-number-2">18</span> Define the basic primitives &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-18">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">init</span>(env)
[<span style="color: #008b8b;">:+</span>, <span style="color: #008b8b;">:-</span>, <span style="color: #008b8b;">:*</span>, <span style="color: #008b8b;">:/</span>, <span style="color: #008b8b;">:&gt;</span>, <span style="color: #008b8b;">:&lt;</span>, <span style="color: #008b8b;">:&gt;=</span>, <span style="color: #008b8b;">:&lt;=</span>, <span style="color: #008b8b;">:==</span>].each <span style="color: #7f007f;">do</span> |op|
env[op] = lambda{|a, b| a.send(op, b)}
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">repl</span>
env = init(<span style="color: #228b22;">Env</span>.new)
<span style="color: #7f007f;">while</span> <span style="color: #a0522d;">true</span>
<span style="color: #8b2252;">"geeklisp&gt; "</span>.display
p(eval(read(gets), env))
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">def</span> <span style="color: #0000ff;">eval</span>(x, env)
...
<span style="color: #7f007f;">else</span>
exps = x.map{|exp| eval(exp, env)}
exps[0].call(*exps[1..-1])
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-19" class="outline-2">
<h2 id="sec-19"><span class="section-number-2">19</span> Now we're cooking &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-19">
<pre class="src src-scheme">$ ./geeklisp
geeklisp&gt; (* 2 3)
6
geeklisp&gt; (&gt; 2 3)
false
geeklisp&gt; (&lt; 2 3)
true
geeklisp&gt; (/ 4 12)
0
geeklisp&gt; (/ 12 4)
3
geeklisp&gt; (- 5 6)
-1
geeklisp&gt; (== 5 5)
true
</pre>
</div>
</div>
<div id="outline-container-20" class="outline-2">
<h2 id="sec-20"><span class="section-number-2">20</span> Bootstrapping more basic functions &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-20">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">init</span>(env)
[<span style="color: #008b8b;">:+</span>, <span style="color: #008b8b;">:-</span>, <span style="color: #008b8b;">:*</span>, <span style="color: #008b8b;">:/</span>, <span style="color: #008b8b;">:&gt;</span>, <span style="color: #008b8b;">:&lt;</span>, <span style="color: #008b8b;">:&gt;=</span>, <span style="color: #008b8b;">:&lt;=</span>, <span style="color: #008b8b;">:==</span>].each <span style="color: #7f007f;">do</span> |op|
env[op] = lambda{|a, b| a.send(op, b)}
<span style="color: #7f007f;">end</span>
env.update({<span style="color: #008b8b;">:length</span> =&gt; lambda{|x| x.length},
<span style="color: #008b8b;">:cons</span> =&gt; lambda{|x,y| [x] + y},
<span style="color: #008b8b;">:car</span> =&gt; lambda{|x| x[0]},
<span style="color: #008b8b;">:cdr</span> =&gt; lambda{|x| x[1..-1]},
<span style="color: #008b8b;">:append</span> =&gt; lambda{|x,y| x + y},
<span style="color: #008b8b;">:list</span> =&gt; lambda{|*xs| xs},
<span style="color: #008b8b;">:list?</span> =&gt; lambda{|x| x.is_a? <span style="color: #228b22;">Array</span>},
<span style="color: #008b8b;">:symbol?</span> =&gt; lambda{|x| x.is_a? <span style="color: #228b22;">Symbol</span>},
<span style="color: #008b8b;">:not</span> =&gt; lambda{|x| !x},
<span style="color: #008b8b;">:display</span> =&gt; lambda{|x| p x}})
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-21" class="outline-2">
<h2 id="sec-21"><span class="section-number-2">21</span> Try it out &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-21">
<pre class="src src-scheme">(<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">foo</span> (list 1 2 3))
[1, 2, 3]
geeklisp&gt; (car foo)
1
geeklisp&gt; (cdr foo)
[2, 3]
geeklisp&gt; (cons 4 foo)
[4, 1, 2, 3]
geeklisp&gt; (list? foo)
true
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">bar</span> 5)
5
geeklisp&gt; (list? 5)
false
</pre>
</div>
</div>
<div id="outline-container-22" class="outline-2">
<h2 id="sec-22"><span class="section-number-2">22</span> We're almost there! Let's round things out &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-22">
<pre class="src src-ruby"><span style="color: #7f007f;">def</span> <span style="color: #0000ff;">eval</span>(symbol, env)
...
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:if</span>
_, test, conseq, alt = symbol
eval(eval(test, env) ? conseq : alt, env)
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:lambda</span>
_, vars, exp = symbol
<span style="color: #228b22;">Proc</span>.new{|*args| eval(exp, <span style="color: #228b22;">Env</span>.new(vars, args, env))}
<span style="color: #7f007f;">when</span> <span style="color: #008b8b;">:begin</span>
symbol[1..-1].reduce([<span style="color: #a0522d;">nil</span>, env]){|val_env, exp| [eval(exp, val_env[1]), val_env[1]]}[0]
<span style="color: #7f007f;">else</span>
exps = symbol.map{|exp| eval(exp, env)}
exps[0].call(*exps[1..-1])
<span style="color: #7f007f;">end</span>
<span style="color: #7f007f;">end</span>
</pre>
</div>
</div>
<div id="outline-container-23" class="outline-2">
<h2 id="sec-23"><span class="section-number-2">23</span> Take in your new awesomeness &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-23">
<pre class="src src-scheme">$ ./geeklisp
geeklisp&gt; (<span style="color: #7f007f;">if</span> (&lt; 3 5) 10 20)
10
geeklisp&gt; (<span style="color: #7f007f;">if</span> (&gt; 3 5) 10 20)
20
geeklisp&gt; (<span style="color: #7f007f;">define</span> <span style="color: #0000ff;">square</span> (<span style="color: #7f007f;">lambda</span> (x) (* x x)))
#&lt;Proc:0x00000001001b7aa0@./geeklisp:41&gt;
geeklisp&gt; (square 12)
144
geeklisp&gt; (<span style="color: #7f007f;">begin</span> (set! x 1) (set! x (+ x 1)) (* x 2))
4
</pre>
</div>
</div>
<div id="outline-container-24" class="outline-2">
<h2 id="sec-24"><span class="section-number-2">24</span> We now have the basics of a language &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-24">
</div>
</div>
<div id="outline-container-25" class="outline-2">
<h2 id="sec-25"><span class="section-number-2">25</span> But we are missing a lot &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-25">
<ul>
<li>No error handling
</li>
<li>Not a complete implementation of the scheme spec
</li>
<li>No ability to load a file and run it
</li>
<li>No core after the bootstrap (stdlib)
</li>
<li>No callcc/tail recursion
</li>
<li>No save-world
</li>
</ul>
</div>
</div>
<div id="outline-container-26" class="outline-2">
<h2 id="sec-26"><span class="section-number-2">26</span> In case Lisp isn't your thing&hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-26">
</div>
</div>
<div id="outline-container-27" class="outline-2">
<h2 id="sec-27"><span class="section-number-2">27</span> Let's look at another toy language &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-27">
</div>
</div>
<div id="outline-container-28" class="outline-2">
<h2 id="sec-28"><span class="section-number-2">28</span> LLVM &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-28">
<p><img src="llvm.png" alt="llvm.png" />
</p></div>
</div>
<div id="outline-container-29" class="outline-2">
<h2 id="sec-29"><span class="section-number-2">29</span> ??? &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-29">
<ul>
<li>LLVM (formerly Low Level Virtual Machine) is compiler infrastructure written in C++
</li>
<li>It is designed for compile-time, link-time, run-time, and "idle-time" optimization of programs written in arbitrary programming languages.
</li>
<li>Originally implemented for C and C++, the language-agnostic design (and the success) of LLVM has since spawned a wide variety of front ends
</li>
<li>Languages with compilers which use LLVM include Objective-C, Fortran, Ada, Haskell, Java bytecode, Python, Ruby, ActionScript, GLSL, and Rust.
</li>
</ul>
</div>
</div>
<div id="outline-container-30" class="outline-2">
<h2 id="sec-30"><span class="section-number-2">30</span> Tokenization &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-30">
<pre class="src src-c++"><span style="color: #7f007f;">static</span> <span style="color: #228b22;">int</span> <span style="color: #0000ff;">gettok</span>() {
<span style="color: #7f007f;">static</span> <span style="color: #228b22;">int</span> <span style="color: #a0522d;">LastChar</span> = <span style="color: #8b2252;">' '</span>;
<span style="color: #7f007f;">while</span> (isspace(LastChar))
LastChar = getchar();
<span style="color: #7f007f;">if</span> (isalpha(LastChar)) {
IdentifierStr = LastChar;
<span style="color: #7f007f;">while</span> (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
<span style="color: #7f007f;">if</span> (IdentifierStr == <span style="color: #8b2252;">"def"</span>) <span style="color: #7f007f;">return</span> tok_def;
<span style="color: #7f007f;">if</span> (IdentifierStr == <span style="color: #8b2252;">"extern"</span>) <span style="color: #7f007f;">return</span> tok_extern;
<span style="color: #7f007f;">return</span> tok_identifier;
}
</pre>
</div>
</div>
<div id="outline-container-31" class="outline-2">
<h2 id="sec-31"><span class="section-number-2">31</span> &hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-31">
<pre class="src src-c++"><span style="color: #7f007f;">if</span> (isdigit(LastChar) || LastChar == <span style="color: #8b2252;">'.'</span>) {
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> <span style="color: #a0522d;">NumStr</span>;
<span style="color: #7f007f;">do</span> {
NumStr += LastChar;
LastChar = getchar();
} <span style="color: #7f007f;">while</span> (isdigit(LastChar) || LastChar == <span style="color: #8b2252;">'.'</span>);
NumVal = strtod(NumStr.c_str(), 0);
<span style="color: #7f007f;">return</span> tok_number;
}
<span style="color: #7f007f;">if</span> (LastChar == <span style="color: #8b2252;">'#'</span>) {
<span style="color: #7f007f;">do</span> LastChar = getchar();
<span style="color: #7f007f;">while</span> (LastChar != EOF &amp;&amp; LastChar != <span style="color: #8b2252;">'\n'</span> &amp;&amp; LastChar != <span style="color: #8b2252;">'\r'</span>);
<span style="color: #7f007f;">if</span> (LastChar != EOF)
<span style="color: #7f007f;">return</span> gettok();
}
</pre>
</div>
</div>
<div id="outline-container-32" class="outline-2">
<h2 id="sec-32"><span class="section-number-2">32</span> AST &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-32">
<pre class="src src-c++"><span style="color: #7f007f;">class</span> <span style="color: #228b22;">ExprAST</span> {
<span style="color: #7f007f;">public</span>:
<span style="color: #7f007f;">virtual</span> ~<span style="color: #0000ff;">ExprAST</span>() {}
<span style="color: #7f007f;">virtual</span> <span style="color: #228b22;">Value</span> *<span style="color: #0000ff;">Codegen</span>() = 0;
};
<span style="color: #7f007f;">class</span> <span style="color: #228b22;">NumberExprAST</span> : <span style="color: #7f007f;">public</span> <span style="color: #228b22;">ExprAST</span> {
<span style="color: #228b22;">double</span> <span style="color: #a0522d;">Val</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">NumberExprAST</span>(<span style="color: #228b22;">double</span> <span style="color: #a0522d;">val</span>) : Val(val) {}
<span style="color: #7f007f;">virtual</span> <span style="color: #228b22;">Value</span> *<span style="color: #0000ff;">Codegen</span>();
};
<span style="color: #7f007f;">class</span> <span style="color: #228b22;">VariableExprAST</span> : <span style="color: #7f007f;">public</span> <span style="color: #228b22;">ExprAST</span> {
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> <span style="color: #a0522d;">Name</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">VariableExprAST</span>(<span style="color: #7f007f;">const</span> <span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> &amp;<span style="color: #a0522d;">name</span>) : Name(name) {}
<span style="color: #7f007f;">virtual</span> <span style="color: #228b22;">Value</span> *<span style="color: #0000ff;">Codegen</span>();
};
</pre>
</div>
</div>
<div id="outline-container-33" class="outline-2">
<h2 id="sec-33"><span class="section-number-2">33</span> &hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-33">
<pre class="src src-c++"><span style="color: #7f007f;">class</span> <span style="color: #228b22;">BinaryExprAST</span> : <span style="color: #7f007f;">public</span> <span style="color: #228b22;">ExprAST</span> {
<span style="color: #228b22;">char</span> <span style="color: #a0522d;">Op</span>;
<span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">LHS</span>, *<span style="color: #a0522d;">RHS</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">BinaryExprAST</span>(<span style="color: #228b22;">char</span> <span style="color: #a0522d;">op</span>, <span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">lhs</span>, <span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">rhs</span>)
: Op(op), LHS(lhs), RHS(rhs) {}
<span style="color: #7f007f;">virtual</span> <span style="color: #228b22;">Value</span> *<span style="color: #0000ff;">Codegen</span>();
};
<span style="color: #7f007f;">class</span> <span style="color: #228b22;">CallExprAST</span> : <span style="color: #7f007f;">public</span> <span style="color: #228b22;">ExprAST</span> {
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> <span style="color: #a0522d;">Callee</span>;
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">vector</span>&lt;<span style="color: #228b22;">ExprAST</span>*&gt; <span style="color: #a0522d;">Args</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">CallExprAST</span>(<span style="color: #7f007f;">const</span> <span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> &amp;<span style="color: #a0522d;">callee</span>, <span style="color: #008b8b;">std</span>::<span style="color: #228b22;">vector</span>&lt;<span style="color: #228b22;">ExprAST</span>*&gt; &amp;<span style="color: #a0522d;">args</span>)
: Callee(callee), Args(args) {}
<span style="color: #7f007f;">virtual</span> <span style="color: #228b22;">Value</span> *<span style="color: #0000ff;">Codegen</span>();
};
</pre>
</div>
</div>
<div id="outline-container-34" class="outline-2">
<h2 id="sec-34"><span class="section-number-2">34</span> &hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-34">
<pre class="src src-c++"><span style="color: #7f007f;">class</span> <span style="color: #228b22;">PrototypeAST</span> {
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> <span style="color: #a0522d;">Name</span>;
<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">vector</span>&lt;<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span>&gt; <span style="color: #a0522d;">Args</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">PrototypeAST</span>(<span style="color: #7f007f;">const</span> <span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span> &amp;<span style="color: #a0522d;">name</span>, <span style="color: #7f007f;">const</span> <span style="color: #008b8b;">std</span>::<span style="color: #228b22;">vector</span>&lt;<span style="color: #008b8b;">std</span>::<span style="color: #228b22;">string</span>&gt; &amp;<span style="color: #a0522d;">args</span>)
: Name(name), <span style="color: #0000ff;">Args</span>(args) {}
Function *Codegen();
};
<span style="color: #7f007f;">class</span> <span style="color: #228b22;">FunctionAST</span> {
<span style="color: #228b22;">PrototypeAST</span> *<span style="color: #a0522d;">Proto</span>;
<span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">Body</span>;
<span style="color: #7f007f;">public</span>:
<span style="color: #0000ff;">FunctionAST</span>(<span style="color: #228b22;">PrototypeAST</span> *<span style="color: #a0522d;">proto</span>, <span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">body</span>)
: Proto(proto), <span style="color: #0000ff;">Body</span>(body) {}
Function *Codegen();
};
</pre>
</div>
</div>
<div id="outline-container-35" class="outline-2">
<h2 id="sec-35"><span class="section-number-2">35</span> Parsing &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-35">
<pre class="src src-c++"><span style="color: #7f007f;">static</span> <span style="color: #228b22;">ExprAST</span> *<span style="color: #0000ff;">ParseBinOpRHS</span>(<span style="color: #228b22;">int</span> <span style="color: #a0522d;">ExprPrec</span>, <span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">LHS</span>) {
<span style="color: #7f007f;">while</span> (1) {
<span style="color: #228b22;">int</span> <span style="color: #a0522d;">TokPrec</span> = GetTokPrecedence();
<span style="color: #228b22;">int</span> <span style="color: #a0522d;">BinOp</span> = CurTok;
<span style="color: #7f007f;">if</span> (TokPrec &lt; ExprPrec) <span style="color: #7f007f;">return</span> LHS;
getNextToken();
<span style="color: #228b22;">ExprAST</span> *<span style="color: #a0522d;">RHS</span> = ParsePrimary();
<span style="color: #7f007f;">if</span> (!RHS) <span style="color: #7f007f;">return</span> 0;
<span style="color: #228b22;">int</span> <span style="color: #a0522d;">NextPrec</span> = GetTokPrecedence();
<span style="color: #7f007f;">if</span> (TokPrec &lt; NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, RHS);
<span style="color: #7f007f;">if</span> (RHS == 0) <span style="color: #7f007f;">return</span> 0;
}
LHS = <span style="color: #7f007f;">new</span> <span style="color: #228b22;">BinaryExprAST</span>(BinOp, LHS, RHS);
}
}
</pre>
</div>
</div>
<div id="outline-container-36" class="outline-2">
<h2 id="sec-36"><span class="section-number-2">36</span> Codegen &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-36">
<pre class="src src-c++"><span style="color: #228b22;">Function</span> *<span style="color: #008b8b;">FunctionAST</span>::<span style="color: #0000ff;">Codegen</span>() {
NamedValues.clear();
<span style="color: #228b22;">Function</span> *<span style="color: #a0522d;">TheFunction</span> = Proto-&gt;Codegen();
<span style="color: #7f007f;">if</span> (TheFunction == 0) <span style="color: #7f007f;">return</span> 0;
<span style="color: #228b22;">BasicBlock</span> *<span style="color: #a0522d;">BB</span> = <span style="color: #008b8b;">BasicBlock</span>::Create(getGlobalContext(), <span style="color: #8b2252;">"entry"</span>, TheFunction);
Builder.SetInsertPoint(BB);
<span style="color: #7f007f;">if</span> (<span style="color: #228b22;">Value</span> *<span style="color: #a0522d;">RetVal</span> = Body-&gt;Codegen()) {
Builder.CreateRet(RetVal);
verifyFunction(*TheFunction);
<span style="color: #7f007f;">return</span> TheFunction;
}
TheFunction-&gt;eraseFromParent();
<span style="color: #7f007f;">return</span> 0;
}
</pre>
</div>
</div>
<div id="outline-container-37" class="outline-2">
<h2 id="sec-37"><span class="section-number-2">37</span> Handlers &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-37">
<pre class="src src-c++"><span style="color: #7f007f;">static</span> <span style="color: #228b22;">void</span> <span style="color: #0000ff;">HandleDefinition</span>() {
<span style="color: #7f007f;">if</span> (<span style="color: #228b22;">FunctionAST</span> *<span style="color: #a0522d;">F</span> = ParseDefinition()) {
<span style="color: #7f007f;">if</span> (<span style="color: #228b22;">Function</span> *<span style="color: #a0522d;">LF</span> = F-&gt;Codegen()) {
fprintf(stderr, <span style="color: #8b2252;">"Read function definition:"</span>);
LF-&gt;dump();
}
} <span style="color: #7f007f;">else</span> {
getNextToken();
}
}
<span style="color: #7f007f;">static</span> <span style="color: #228b22;">void</span> <span style="color: #0000ff;">HandleExtern</span>() {
<span style="color: #7f007f;">if</span> (<span style="color: #228b22;">PrototypeAST</span> *<span style="color: #a0522d;">P</span> = ParseExtern()) {
<span style="color: #7f007f;">if</span> (<span style="color: #228b22;">Function</span> *<span style="color: #a0522d;">F</span> = P-&gt;Codegen()) {
fprintf(stderr, <span style="color: #8b2252;">"Read extern: "</span>);
F-&gt;dump();
}
} <span style="color: #7f007f;">else</span> {
getNextToken();
}
}
</pre>
</div>
</div>
<div id="outline-container-38" class="outline-2">
<h2 id="sec-38"><span class="section-number-2">38</span> Interactive shell &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-38">
<pre class="src src-c++"><span style="color: #7f007f;">static</span> <span style="color: #228b22;">void</span> <span style="color: #0000ff;">MainLoop</span>() {
<span style="color: #7f007f;">while</span> (1) {
fprintf(stderr, <span style="color: #8b2252;">"pon&gt; "</span>);
<span style="color: #7f007f;">switch</span> (CurTok) {
<span style="color: #7f007f;">case</span> tok_eof: <span style="color: #7f007f;">return</span>;
<span style="color: #7f007f;">case</span> <span style="color: #8b2252;">';'</span>: getNextToken(); <span style="color: #7f007f;">break</span>;
<span style="color: #7f007f;">case</span> tok_def: HandleDefinition(); <span style="color: #7f007f;">break</span>;
<span style="color: #7f007f;">case</span> tok_extern: HandleExtern(); <span style="color: #7f007f;">break</span>;
<span style="color: #7f007f;">default</span>: HandleTopLevelExpression(); <span style="color: #7f007f;">break</span>;
}
}
}
</pre>
</div>
</div>
<div id="outline-container-39" class="outline-2">
<h2 id="sec-39"><span class="section-number-2">39</span> Putting it all together &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-39">
<pre class="src src-c++"><span style="color: #228b22;">int</span> <span style="color: #0000ff;">main</span>() {
<span style="color: #228b22;">LLVMContext</span> &amp;<span style="color: #a0522d;">Context</span> = getGlobalContext();
BinopPrecedence[<span style="color: #8b2252;">'&lt;'</span>] = 10;
BinopPrecedence[<span style="color: #8b2252;">'+'</span>] = 20;
BinopPrecedence[<span style="color: #8b2252;">'-'</span>] = 20;
BinopPrecedence[<span style="color: #8b2252;">'*'</span>] = 40;
fprintf(stderr, <span style="color: #8b2252;">"pon&gt; "</span>);
getNextToken();
TheModule = <span style="color: #7f007f;">new</span> <span style="color: #228b22;">Module</span>(<span style="color: #8b2252;">"Pon JIT"</span>, Context);
MainLoop();
TheModule-&gt;dump();
<span style="color: #7f007f;">return</span> 0;
}
</pre>
</div>
</div>
<div id="outline-container-40" class="outline-2">
<h2 id="sec-40"><span class="section-number-2">40</span> Giving it a spin &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-40">
<pre class="src src-sh">clang++ -g -O3 pon.cpp <span style="color: #ff00ff;">`llvm-config --cppflags --ldflags --libs core`</span> -o pon
</pre>
<pre class="src src-python">pon&gt; 4+5;
pon&gt; Read top-level expression:
define double @0() {
entry:
ret double 9.000000e+00
}
pon&gt; <span style="color: #7f007f;">def</span> <span style="color: #0000ff;">foo</span>(a b) a*a + 2*a*b + b*b;
pon&gt; Read function definition:
define double @foo(double %a, double %b) {
entry:
%multmp = fmul double %a, %a
%multmp1 = fmul double 2.000000e+00, %a
%multmp2 = fmul double %multmp1, %b
%addtmp = fadd double %multmp, %multmp2
%multmp3 = fmul double %b, %b
%addtmp4 = fadd double %addtmp, %multmp3
ret double %addtmp4
}
</pre>
</div>
</div>
<div id="outline-container-41" class="outline-2">
<h2 id="sec-41"><span class="section-number-2">41</span> &hellip; &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-41">
<pre class="src src-python">pon&gt; <span style="color: #7f007f;">def</span> <span style="color: #0000ff;">bar</span>(a) foo(a, 4.0) + bar(31337);
pon&gt; Read function definition:
define double @bar(double %a) {
entry:
%calltmp = call double @foo(double %a, double 4.000000e+00)
%calltmp1 = call double @bar(double 3.133700e+04)
%addtmp = fadd double %calltmp, %calltmp1
ret double %addtmp
}
pon&gt; extern cos(x);
pon&gt; Read extern:
declare double @cos(double)
pon&gt; cos(1.234);
pon&gt; Read top-level expression:
define double @1() {
entry:
%calltmp = call double @cos(double 1.234000e+00)
ret double %calltmp
}
</pre>
</div>
</div>
<div id="outline-container-42" class="outline-2">
<h2 id="sec-42"><span class="section-number-2">42</span> THIS IS FUN! &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-42">
</div>
</div>
<div id="outline-container-43" class="outline-2">
<h2 id="sec-43"><span class="section-number-2">43</span> You can learn a so much by doing this! &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-43">
</div>
</div>
<div id="outline-container-44" class="outline-2">
<h2 id="sec-44"><span class="section-number-2">44</span> You will think more about how your programming language does this! &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-44">
</div>
</div>
<div id="outline-container-45" class="outline-2">
<h2 id="sec-45"><span class="section-number-2">45</span> You might even explore the implementation of your language to see how it works! &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-45">
</div>
</div>
<div id="outline-container-46" class="outline-2">
<h2 id="sec-46"><span class="section-number-2">46</span> References &nbsp;&nbsp;&nbsp;<span class="tag"><span class="slide">slide</span></span></h2>
<div class="outline-text-2" id="text-46">
<ul>
<li>This presentation <a href="https://github.com/abedra/bootstrapping-a-language">github.com/abedra/bootstrapping-a-language</a>
</li>
<li>(How to Write a (Lisp) Interpreter (in Python)) <a href="http://norvig.com/lispy.html">norvig.com/lispy.html</a>
</li>
<li>SICP <a href="http://mitpress.mit.edu/sicp/">mitpress.mit.edu/sicp/</a>
</li>
<li>Scheme Specification <a href="http://www.schemers.org/Documents/Standards/R5RS/">www.schemers.org/Documents/Standards/R5RS/</a>
</li>
<li>LLVM <a href="http://llvm.org/">llvm.org/</a>
</li>
</ul>
<script type="text/javascript" src="org-html-slideshow.js"></script>
</div>
</div>
</div>
<div id="postamble">
<p class="date">Date: 2012-06-27T11:40-0400</p>
<p class="author">Author: Aaron Bedra</p>
<p class="creator"><a href="http://orgmode.org">Org</a> version 7.8.10 with <a href="http://www.gnu.org/software/emacs/">Emacs</a> version 24</p>
<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
</div>
</body>
</html>