[www-releases] r368037 - Add 8.0.1 LLVM docs
Tom Stellard via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 6 06:51:06 PDT 2019
Added: www-releases/trunk/8.0.1/docs/tutorial/LangImpl08.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/LangImpl08.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/LangImpl08.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/LangImpl08.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,1545 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>8. Kaleidoscope: Compiling to Object Code — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="9. Kaleidoscope: Adding Debug Information" href="LangImpl09.html" />
+ <link rel="prev" title="7. Kaleidoscope: Extending the Language: Mutable Variables" href="LangImpl07.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="LangImpl09.html" title="9. Kaleidoscope: Adding Debug Information"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl07.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-compiling-to-object-code">
+<h1>8. Kaleidoscope: Compiling to Object Code<a class="headerlink" href="#kaleidoscope-compiling-to-object-code" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-8-introduction" id="id1">Chapter 8 Introduction</a></li>
+<li><a class="reference internal" href="#choosing-a-target" id="id2">Choosing a target</a></li>
+<li><a class="reference internal" href="#target-machine" id="id3">Target Machine</a></li>
+<li><a class="reference internal" href="#configuring-the-module" id="id4">Configuring the Module</a></li>
+<li><a class="reference internal" href="#emit-object-code" id="id5">Emit Object Code</a></li>
+<li><a class="reference internal" href="#putting-it-all-together" id="id6">Putting It All Together</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id7">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-8-introduction">
+<h2><a class="toc-backref" href="#id1">8.1. Chapter 8 Introduction</a><a class="headerlink" href="#chapter-8-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 8 of the â<a class="reference external" href="index.html">Implementing a language with LLVM</a>â tutorial. This chapter describes how to compile our
+language down to object files.</p>
+</div>
+<div class="section" id="choosing-a-target">
+<h2><a class="toc-backref" href="#id2">8.2. Choosing a target</a><a class="headerlink" href="#choosing-a-target" title="Permalink to this headline">¶</a></h2>
+<p>LLVM has native support for cross-compilation. You can compile to the
+architecture of your current machine, or just as easily compile for
+other architectures. In this tutorial, weâll target the current
+machine.</p>
+<p>To specify the architecture that you want to target, we use a string
+called a âtarget tripleâ. This takes the form
+<code class="docutils literal notranslate"><span class="pre"><arch><sub>-<vendor>-<sys>-<abi></span></code> (see the <a class="reference external" href="http://clang.llvm.org/docs/CrossCompilation.html#target-triple">cross compilation docs</a>).</p>
+<p>As an example, we can see what clang thinks is our current target
+triple:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ clang --version | grep Target
+Target: x86_64-unknown-linux-gnu
+</pre></div>
+</div>
+<p>Running this command may show something different on your machine as
+you might be using a different architecture or operating system to me.</p>
+<p>Fortunately, we donât need to hard-code a target triple to target the
+current machine. LLVM provides <code class="docutils literal notranslate"><span class="pre">sys::getDefaultTargetTriple</span></code>, which
+returns the target triple of the current machine.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">auto</span> <span class="n">TargetTriple</span> <span class="o">=</span> <span class="n">sys</span><span class="o">::</span><span class="n">getDefaultTargetTriple</span><span class="p">();</span>
+</pre></div>
+</div>
+<p>LLVM doesnât require us to link in all the target
+functionality. For example, if weâre just using the JIT, we donât need
+the assembly printers. Similarly, if weâre only targeting certain
+architectures, we can only link in the functionality for those
+architectures.</p>
+<p>For this example, weâll initialize all the targets for emitting object
+code.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">InitializeAllTargetInfos</span><span class="p">();</span>
+<span class="n">InitializeAllTargets</span><span class="p">();</span>
+<span class="n">InitializeAllTargetMCs</span><span class="p">();</span>
+<span class="n">InitializeAllAsmParsers</span><span class="p">();</span>
+<span class="n">InitializeAllAsmPrinters</span><span class="p">();</span>
+</pre></div>
+</div>
+<p>We can now use our target triple to get a <code class="docutils literal notranslate"><span class="pre">Target</span></code>:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Error</span><span class="p">;</span>
+<span class="k">auto</span> <span class="n">Target</span> <span class="o">=</span> <span class="n">TargetRegistry</span><span class="o">::</span><span class="n">lookupTarget</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">,</span> <span class="n">Error</span><span class="p">);</span>
+
+<span class="c1">// Print an error and exit if we couldn't find the requested target.</span>
+<span class="c1">// This generally occurs if we've forgotten to initialise the</span>
+<span class="c1">// TargetRegistry or we have a bogus target triple.</span>
+<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Target</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="n">Error</span><span class="p">;</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="target-machine">
+<h2><a class="toc-backref" href="#id3">8.3. Target Machine</a><a class="headerlink" href="#target-machine" title="Permalink to this headline">¶</a></h2>
+<p>We will also need a <code class="docutils literal notranslate"><span class="pre">TargetMachine</span></code>. This class provides a complete
+machine description of the machine weâre targeting. If we want to
+target a specific feature (such as SSE) or a specific CPU (such as
+Intelâs Sandylake), we do so now.</p>
+<p>To see which features and CPUs that LLVM knows about, we can use
+<code class="docutils literal notranslate"><span class="pre">llc</span></code>. For example, letâs look at x86:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ llvm-as < /dev/null | llc -march=x86 -mattr=help
+Available CPUs for this target:
+
+ amdfam10 - Select the amdfam10 processor.
+ athlon - Select the athlon processor.
+ athlon-4 - Select the athlon-4 processor.
+ ...
+
+Available features for this target:
+
+ 16bit-mode - 16-bit mode (i8086).
+ 32bit-mode - 32-bit mode (80386).
+ 3dnow - Enable 3DNow! instructions.
+ 3dnowa - Enable 3DNow! Athlon instructions.
+ ...
+</pre></div>
+</div>
+<p>For our example, weâll use the generic CPU without any additional
+features, options or relocation model.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">auto</span> <span class="n">CPU</span> <span class="o">=</span> <span class="s">"generic"</span><span class="p">;</span>
+<span class="k">auto</span> <span class="n">Features</span> <span class="o">=</span> <span class="s">""</span><span class="p">;</span>
+
+<span class="n">TargetOptions</span> <span class="n">opt</span><span class="p">;</span>
+<span class="k">auto</span> <span class="n">RM</span> <span class="o">=</span> <span class="n">Optional</span><span class="o"><</span><span class="n">Reloc</span><span class="o">::</span><span class="n">Model</span><span class="o">></span><span class="p">();</span>
+<span class="k">auto</span> <span class="n">TargetMachine</span> <span class="o">=</span> <span class="n">Target</span><span class="o">-></span><span class="n">createTargetMachine</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">,</span> <span class="n">CPU</span><span class="p">,</span> <span class="n">Features</span><span class="p">,</span> <span class="n">opt</span><span class="p">,</span> <span class="n">RM</span><span class="p">);</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="configuring-the-module">
+<h2><a class="toc-backref" href="#id4">8.4. Configuring the Module</a><a class="headerlink" href="#configuring-the-module" title="Permalink to this headline">¶</a></h2>
+<p>Weâre now ready to configure our module, to specify the target and
+data layout. This isnât strictly necessary, but the <a class="reference external" href="../Frontend/PerformanceTips.html">frontend
+performance guide</a> recommends
+this. Optimizations benefit from knowing about the target and data
+layout.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">TheModule</span><span class="o">-></span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TargetMachine</span><span class="o">-></span><span class="n">createDataLayout</span><span class="p">());</span>
+<span class="n">TheModule</span><span class="o">-></span><span class="n">setTargetTriple</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">);</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="emit-object-code">
+<h2><a class="toc-backref" href="#id5">8.5. Emit Object Code</a><a class="headerlink" href="#emit-object-code" title="Permalink to this headline">¶</a></h2>
+<p>Weâre ready to emit object code! Letâs define where we want to write
+our file to:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">auto</span> <span class="n">Filename</span> <span class="o">=</span> <span class="s">"output.o"</span><span class="p">;</span>
+<span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="n">EC</span><span class="p">;</span>
+<span class="n">raw_fd_ostream</span> <span class="nf">dest</span><span class="p">(</span><span class="n">Filename</span><span class="p">,</span> <span class="n">EC</span><span class="p">,</span> <span class="n">sys</span><span class="o">::</span><span class="n">fs</span><span class="o">::</span><span class="n">F_None</span><span class="p">);</span>
+
+<span class="k">if</span> <span class="p">(</span><span class="n">EC</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"Could not open file: "</span> <span class="o"><<</span> <span class="n">EC</span><span class="p">.</span><span class="n">message</span><span class="p">();</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Finally, we define a pass that emits object code, then we run that
+pass:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">legacy</span><span class="o">::</span><span class="n">PassManager</span> <span class="n">pass</span><span class="p">;</span>
+<span class="k">auto</span> <span class="n">FileType</span> <span class="o">=</span> <span class="n">TargetMachine</span><span class="o">::</span><span class="n">CGFT_ObjectFile</span><span class="p">;</span>
+
+<span class="k">if</span> <span class="p">(</span><span class="n">TargetMachine</span><span class="o">-></span><span class="n">addPassesToEmitFile</span><span class="p">(</span><span class="n">pass</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">FileType</span><span class="p">))</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"TargetMachine can't emit a file of this type"</span><span class="p">;</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">pass</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="o">*</span><span class="n">TheModule</span><span class="p">);</span>
+<span class="n">dest</span><span class="p">.</span><span class="n">flush</span><span class="p">();</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="putting-it-all-together">
+<h2><a class="toc-backref" href="#id6">8.6. Putting It All Together</a><a class="headerlink" href="#putting-it-all-together" title="Permalink to this headline">¶</a></h2>
+<p>Does it work? Letâs give it a try. We need to compile our code, but
+note that the arguments to <code class="docutils literal notranslate"><span class="pre">llvm-config</span></code> are different to the previous chapters.</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ clang++ -g -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs all` -o toy
+</pre></div>
+</div>
+<p>Letâs run it, and define a simple <code class="docutils literal notranslate"><span class="pre">average</span></code> function. Press Ctrl-D
+when youâre done.</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ ./toy
+ready> def average(x y) (x + y) * 0.5;
+^D
+Wrote output.o
+</pre></div>
+</div>
+<p>We have an object file! To test it, letâs write a simple program and
+link it with our output. Hereâs the source code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><iostream></span><span class="cp"></span>
+
+<span class="k">extern</span> <span class="s">"C"</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">average</span><span class="p">(</span><span class="kt">double</span><span class="p">,</span> <span class="kt">double</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"average of 3.0 and 4.0: "</span> <span class="o"><<</span> <span class="n">average</span><span class="p">(</span><span class="mf">3.0</span><span class="p">,</span> <span class="mf">4.0</span><span class="p">)</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>We link our program to output.o and check the result is what we
+expected:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ clang++ main.cpp output.o -o main
+$ ./main
+average of 3.0 and 4.0: 3.5
+</pre></div>
+</div>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id7">8.7. Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">"llvm/ADT/APFloat.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/ADT/Optional.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/ADT/STLExtras.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/BasicBlock.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Constants.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/DerivedTypes.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Function.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Instructions.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/IRBuilder.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LLVMContext.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LegacyPassManager.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Module.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Type.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Verifier.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/FileSystem.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/Host.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/raw_ostream.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/TargetRegistry.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/TargetSelect.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Target/TargetMachine.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Target/TargetOptions.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><algorithm></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cassert></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cctype></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdio></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdlib></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><map></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><memory></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><system_error></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><utility></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
+
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="p">;</span>
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="o">::</span><span class="n">sys</span><span class="p">;</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Lexer</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span><span class="p">,</span>
+
+ <span class="c1">// control</span>
+ <span class="n">tok_if</span> <span class="o">=</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span>
+ <span class="n">tok_then</span> <span class="o">=</span> <span class="o">-</span><span class="mi">7</span><span class="p">,</span>
+ <span class="n">tok_else</span> <span class="o">=</span> <span class="o">-</span><span class="mi">8</span><span class="p">,</span>
+ <span class="n">tok_for</span> <span class="o">=</span> <span class="o">-</span><span class="mi">9</span><span class="p">,</span>
+ <span class="n">tok_in</span> <span class="o">=</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span>
+
+ <span class="c1">// operators</span>
+ <span class="n">tok_binary</span> <span class="o">=</span> <span class="o">-</span><span class="mi">11</span><span class="p">,</span>
+ <span class="n">tok_unary</span> <span class="o">=</span> <span class="o">-</span><span class="mi">12</span><span class="p">,</span>
+
+ <span class="c1">// var definition</span>
+ <span class="n">tok_var</span> <span class="o">=</span> <span class="o">-</span><span class="mi">13</span>
+<span class="p">};</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+
+<span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"if"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_if</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"then"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_then</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"else"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_else</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"for"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_for</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"in"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_in</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"binary"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_binary</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"unary"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_unary</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"var"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_var</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">namespace</span> <span class="p">{</span>
+
+<span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
+
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="nf">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span> <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// UnaryExprAST - Expression class for a unary operator.</span>
+<span class="k">class</span> <span class="nc">UnaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Opcode</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Operand</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">UnaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Opcode</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Operand</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Opcode</span><span class="p">(</span><span class="n">Opcode</span><span class="p">),</span> <span class="n">Operand</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Operand</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Op</span><span class="p">(</span><span class="n">Op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// IfExprAST - Expression class for if/then/else.</span>
+<span class="k">class</span> <span class="nc">IfExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Cond</span><span class="p">,</span> <span class="n">Then</span><span class="p">,</span> <span class="n">Else</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">IfExprAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Cond</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Then</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Else</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Cond</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Cond</span><span class="p">)),</span> <span class="n">Then</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Then</span><span class="p">)),</span> <span class="n">Else</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Else</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// ForExprAST - Expression class for for/in.</span>
+<span class="k">class</span> <span class="nc">ForExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">VarName</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Start</span><span class="p">,</span> <span class="n">End</span><span class="p">,</span> <span class="n">Step</span><span class="p">,</span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">ForExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Start</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">End</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Step</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">VarName</span><span class="p">(</span><span class="n">VarName</span><span class="p">),</span> <span class="n">Start</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Start</span><span class="p">)),</span> <span class="n">End</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">End</span><span class="p">)),</span>
+ <span class="n">Step</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Step</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// VarExprAST - Expression class for var/in</span>
+<span class="k">class</span> <span class="nc">VarExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VarExprAST</span><span class="p">(</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">VarNames</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">VarNames</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes), as well as if it is an operator.</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="kt">bool</span> <span class="n">IsOperator</span><span class="p">;</span>
+ <span class="kt">unsigned</span> <span class="n">Precedence</span><span class="p">;</span> <span class="c1">// Precedence if a binary op.</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">,</span>
+ <span class="kt">bool</span> <span class="n">IsOperator</span> <span class="o">=</span> <span class="nb">false</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="n">Prec</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">)),</span> <span class="n">IsOperator</span><span class="p">(</span><span class="n">IsOperator</span><span class="p">),</span>
+ <span class="n">Precedence</span><span class="p">(</span><span class="n">Prec</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+
+ <span class="kt">bool</span> <span class="n">isUnaryOp</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">IsOperator</span> <span class="o">&&</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span>
+ <span class="kt">bool</span> <span class="n">isBinaryOp</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">IsOperator</span> <span class="o">&&</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">;</span> <span class="p">}</span>
+
+ <span class="kt">char</span> <span class="n">getOperatorName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">isUnaryOp</span><span class="p">()</span> <span class="o">||</span> <span class="n">isBinaryOp</span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">Name</span><span class="p">[</span><span class="n">Name</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
+ <span class="p">}</span>
+
+ <span class="kt">unsigned</span> <span class="n">getBinaryPrecedence</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Precedence</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+<span class="p">};</span>
+
+<span class="p">}</span> <span class="c1">// end anonymous namespace</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Parser</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span> <span class="p">}</span>
+
+<span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">();</span>
+
+<span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// ifexpr ::= 'if' expression 'then' expression 'else' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIfExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the if.</span>
+
+ <span class="c1">// condition.</span>
+ <span class="k">auto</span> <span class="n">Cond</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Cond</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_then</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected then"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the then</span>
+
+ <span class="k">auto</span> <span class="n">Then</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Then</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_else</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected else"</span><span class="p">);</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">auto</span> <span class="n">Else</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Else</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">IfExprAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Cond</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Then</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Else</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseForExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the for.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier after for"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'='</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected '=' after for"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat '='.</span>
+
+ <span class="k">auto</span> <span class="n">Start</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Start</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ',' after for start value"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">auto</span> <span class="n">End</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">End</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// The step value is optional.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Step</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">','</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="n">Step</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Step</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_in</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected 'in' after for"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat 'in'.</span>
+
+ <span class="k">auto</span> <span class="n">Body</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">ForExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Start</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">End</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Step</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// varexpr ::= 'var' identifier ('=' expression)?</span>
+<span class="c1">// (',' identifier ('=' expression)?)* 'in' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseVarExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the var.</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">;</span>
+
+ <span class="c1">// At least one variable name is required.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier after var"</span><span class="p">);</span>
+
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="c1">// Read the optional initializer.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Init</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">'='</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the '='.</span>
+
+ <span class="n">Init</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Init</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">VarNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Init</span><span class="p">)));</span>
+
+ <span class="c1">// End of var list, exit loop.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the ','.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier list after var"</span><span class="p">);</span>
+ <span class="p">}</span>
+
+ <span class="c1">// At this point, we have to have 'in'.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_in</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected 'in' keyword after 'var'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat 'in'.</span>
+
+ <span class="k">auto</span> <span class="n">Body</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VarExprAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">VarNames</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="c1">/// ::= ifexpr</span>
+<span class="c1">/// ::= forexpr</span>
+<span class="c1">/// ::= varexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_if</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIfExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_for</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseForExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_var</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseVarExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// unary</span>
+<span class="c1">/// ::= primary</span>
+<span class="c1">/// ::= '!' unary</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseUnary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// If the current token is not an operator, it must be a primary expr.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="o">||</span> <span class="n">CurTok</span> <span class="o">==</span> <span class="sc">'('</span> <span class="o">||</span> <span class="n">CurTok</span> <span class="o">==</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+
+ <span class="c1">// If this is a unary operator, read it.</span>
+ <span class="kt">int</span> <span class="n">Opc</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Operand</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">UnaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">Opc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Operand</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' unary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+
+ <span class="c1">// Okay, we know this is a binop.</span>
+ <span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+ <span class="c1">// Parse the unary expression after the binary operator.</span>
+ <span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span>
+ <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// expression</span>
+<span class="c1">/// ::= unary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="c1">/// ::= binary LETTER number? (id, id)</span>
+<span class="c1">/// ::= unary LETTER (id)</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span><span class="p">;</span>
+
+ <span class="kt">unsigned</span> <span class="n">Kind</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// 0 = identifier, 1 = unary, 2 = binary.</span>
+ <span class="kt">unsigned</span> <span class="n">BinaryPrecedence</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_unary</span><span class="p">:</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected unary operator"</span><span class="p">);</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="s">"unary"</span><span class="p">;</span>
+ <span class="n">FnName</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_binary</span><span class="p">:</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected binary operator"</span><span class="p">);</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="s">"binary"</span><span class="p">;</span>
+ <span class="n">FnName</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="c1">// Read the precedence if present.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="n">tok_number</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">NumVal</span> <span class="o"><</span> <span class="mi">1</span> <span class="o">||</span> <span class="n">NumVal</span> <span class="o">></span> <span class="mi">100</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Invalid precedence: must be 1..100"</span><span class="p">);</span>
+ <span class="n">BinaryPrecedence</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span><span class="p">)</span><span class="n">NumVal</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="c1">// Verify right number of names for operator.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Kind</span> <span class="o">&&</span> <span class="n">ArgNames</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Kind</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Invalid number of operands for operator"</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnName</span><span class="p">,</span> <span class="n">ArgNames</span><span class="p">,</span> <span class="n">Kind</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">BinaryPrecedence</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Code Generation</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="n">LLVMContext</span> <span class="n">TheContext</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">Builder</span><span class="p">(</span><span class="n">TheContext</span><span class="p">);</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">Module</span><span class="o">></span> <span class="n">TheModule</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">AllocaInst</span> <span class="o">*></span> <span class="n">NamedValues</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">>></span> <span class="n">FunctionProtos</span><span class="p">;</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="nf">LogErrorV</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="nf">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// First, see if the function has already been added to the current module.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Name</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+
+ <span class="c1">// If not, check whether we can codegen the declaration from some existing</span>
+ <span class="c1">// prototype.</span>
+ <span class="k">auto</span> <span class="n">FI</span> <span class="o">=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">Name</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FI</span> <span class="o">!=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">FI</span><span class="o">-></span><span class="n">second</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="c1">// If no existing prototype exists, return null.</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of</span>
+<span class="c1">/// the function. This is used for mutable variables etc.</span>
+<span class="k">static</span> <span class="n">AllocaInst</span> <span class="o">*</span><span class="nf">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span><span class="p">,</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">TmpB</span><span class="p">(</span><span class="o">&</span><span class="n">TheFunction</span><span class="o">-></span><span class="n">getEntryBlock</span><span class="p">(),</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getEntryBlock</span><span class="p">().</span><span class="n">begin</span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">TmpB</span><span class="p">.</span><span class="n">CreateAlloca</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="k">nullptr</span><span class="p">,</span> <span class="n">VarName</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">NumberExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="n">Val</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VariableExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look this variable up in the function.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">V</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">Name</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+
+ <span class="c1">// Load the value.</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateLoad</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">Name</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">UnaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">OperandV</span> <span class="o">=</span> <span class="n">Operand</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">OperandV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"unary"</span><span class="p">)</span> <span class="o">+</span> <span class="n">Opcode</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">F</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown unary operator"</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">OperandV</span><span class="p">,</span> <span class="s">"unop"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">BinaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Special case '=' because we don't want to emit the LHS as an expression.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Op</span> <span class="o">==</span> <span class="sc">'='</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Assignment requires the LHS to be an identifier.</span>
+ <span class="c1">// This assume we're building without RTTI because LLVM builds that way by</span>
+ <span class="c1">// default. If you build LLVM with RTTI this can be changed to a</span>
+ <span class="c1">// dynamic_cast for automatic error checking.</span>
+ <span class="n">VariableExprAST</span> <span class="o">*</span><span class="n">LHSE</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o"><</span><span class="n">VariableExprAST</span> <span class="o">*></span><span class="p">(</span><span class="n">LHS</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHSE</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"destination of '=' must be a variable"</span><span class="p">);</span>
+ <span class="c1">// Codegen the RHS.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Val</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Val</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Look up the name.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Variable</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">LHSE</span><span class="o">-></span><span class="n">getName</span><span class="p">()];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Variable</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">Val</span><span class="p">,</span> <span class="n">Variable</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">Val</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">L</span> <span class="o">=</span> <span class="n">LHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">R</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">L</span> <span class="o">||</span> <span class="o">!</span><span class="n">R</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Op</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="sc">'+'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"addtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'-'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFSub</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"subtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'*'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFMul</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"multmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'<'</span><span class="o">:</span>
+ <span class="n">L</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpULT</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"cmptmp"</span><span class="p">);</span>
+ <span class="c1">// Convert bool 0/1 to double 0.0 or 1.0</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateUIToFP</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="s">"booltmp"</span><span class="p">);</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// If it wasn't a builtin binary operator, it must be a user defined one. Emit</span>
+ <span class="c1">// a call to it.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"binary"</span><span class="p">)</span> <span class="o">+</span> <span class="n">Op</span><span class="p">);</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">F</span> <span class="o">&&</span> <span class="s">"binary operator not found!"</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Ops</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">};</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">Ops</span><span class="p">,</span> <span class="s">"binop"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CalleeF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown function referenced"</span><span class="p">);</span>
+
+ <span class="c1">// If argument mismatch error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CalleeF</span><span class="o">-></span><span class="n">arg_size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Incorrect # arguments passed"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Value</span> <span class="o">*></span> <span class="n">ArgsV</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">ArgsV</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">codegen</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ArgsV</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">CalleeF</span><span class="p">,</span> <span class="n">ArgsV</span><span class="p">,</span> <span class="s">"calltmp"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">IfExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">CondV</span> <span class="o">=</span> <span class="n">Cond</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CondV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Convert condition to a bool by comparing non-equal to 0.0.</span>
+ <span class="n">CondV</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpONE</span><span class="p">(</span>
+ <span class="n">CondV</span><span class="p">,</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)),</span> <span class="s">"ifcond"</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Create blocks for the then and else cases. Insert the 'then' block at the</span>
+ <span class="c1">// end of the function.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">ThenBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"then"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">ElseBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"else"</span><span class="p">);</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">MergeBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"ifcont"</span><span class="p">);</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCondBr</span><span class="p">(</span><span class="n">CondV</span><span class="p">,</span> <span class="n">ThenBB</span><span class="p">,</span> <span class="n">ElseBB</span><span class="p">);</span>
+
+ <span class="c1">// Emit then value.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">ThenBB</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">ThenV</span> <span class="o">=</span> <span class="n">Then</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ThenV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="c1">// Codegen of 'Then' can change the current block, update ThenBB for the PHI.</span>
+ <span class="n">ThenBB</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">();</span>
+
+ <span class="c1">// Emit else block.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getBasicBlockList</span><span class="p">().</span><span class="n">push_back</span><span class="p">(</span><span class="n">ElseBB</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">ElseBB</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">ElseV</span> <span class="o">=</span> <span class="n">Else</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ElseV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="c1">// Codegen of 'Else' can change the current block, update ElseBB for the PHI.</span>
+ <span class="n">ElseBB</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">();</span>
+
+ <span class="c1">// Emit merge block.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getBasicBlockList</span><span class="p">().</span><span class="n">push_back</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="n">PHINode</span> <span class="o">*</span><span class="n">PN</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreatePHI</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="mi">2</span><span class="p">,</span> <span class="s">"iftmp"</span><span class="p">);</span>
+
+ <span class="n">PN</span><span class="o">-></span><span class="n">addIncoming</span><span class="p">(</span><span class="n">ThenV</span><span class="p">,</span> <span class="n">ThenBB</span><span class="p">);</span>
+ <span class="n">PN</span><span class="o">-></span><span class="n">addIncoming</span><span class="p">(</span><span class="n">ElseV</span><span class="p">,</span> <span class="n">ElseBB</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">PN</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">// Output for-loop as:</span>
+<span class="c1">// var = alloca double</span>
+<span class="c1">// ...</span>
+<span class="c1">// start = startexpr</span>
+<span class="c1">// store start -> var</span>
+<span class="c1">// goto loop</span>
+<span class="c1">// loop:</span>
+<span class="c1">// ...</span>
+<span class="c1">// bodyexpr</span>
+<span class="c1">// ...</span>
+<span class="c1">// loopend:</span>
+<span class="c1">// step = stepexpr</span>
+<span class="c1">// endcond = endexpr</span>
+<span class="c1">//</span>
+<span class="c1">// curvar = load var</span>
+<span class="c1">// nextvar = curvar + step</span>
+<span class="c1">// store nextvar -> var</span>
+<span class="c1">// br endcond, loop, endloop</span>
+<span class="c1">// outloop:</span>
+<span class="n">Value</span> <span class="o">*</span><span class="n">ForExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Create an alloca for the variable in the entry block.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">VarName</span><span class="p">);</span>
+
+ <span class="c1">// Emit the start code first, without 'variable' in scope.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">StartVal</span> <span class="o">=</span> <span class="n">Start</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">StartVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Store the value into the alloca.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">StartVal</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Make the new basic block for the loop header, inserting after current</span>
+ <span class="c1">// block.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">LoopBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"loop"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Insert an explicit fall through from the current block to the LoopBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">LoopBB</span><span class="p">);</span>
+
+ <span class="c1">// Start insertion in LoopBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">LoopBB</span><span class="p">);</span>
+
+ <span class="c1">// Within the loop, the variable is defined equal to the PHI node. If it</span>
+ <span class="c1">// shadows an existing variable, we have to restore it, so save it now.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">OldVal</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">];</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+
+ <span class="c1">// Emit the body of the loop. This, like any other expr, can change the</span>
+ <span class="c1">// current BB. Note that we ignore the value computed by the body, but don't</span>
+ <span class="c1">// allow an error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Emit the step value.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">StepVal</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Step</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">StepVal</span> <span class="o">=</span> <span class="n">Step</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">StepVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// If not specified, use 1.0.</span>
+ <span class="n">StepVal</span> <span class="o">=</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">1.0</span><span class="p">));</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Compute the end condition.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">EndCond</span> <span class="o">=</span> <span class="n">End</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">EndCond</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Reload, increment, and restore the alloca. This handles the case where</span>
+ <span class="c1">// the body of the loop mutates the variable.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">CurVar</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateLoad</span><span class="p">(</span><span class="n">Alloca</span><span class="p">,</span> <span class="n">VarName</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">NextVar</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">CurVar</span><span class="p">,</span> <span class="n">StepVal</span><span class="p">,</span> <span class="s">"nextvar"</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">NextVar</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Convert condition to a bool by comparing non-equal to 0.0.</span>
+ <span class="n">EndCond</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpONE</span><span class="p">(</span>
+ <span class="n">EndCond</span><span class="p">,</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)),</span> <span class="s">"loopcond"</span><span class="p">);</span>
+
+ <span class="c1">// Create the "after loop" block and insert it.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">AfterBB</span> <span class="o">=</span>
+ <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"afterloop"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Insert the conditional branch into the end of LoopEndBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCondBr</span><span class="p">(</span><span class="n">EndCond</span><span class="p">,</span> <span class="n">LoopBB</span><span class="p">,</span> <span class="n">AfterBB</span><span class="p">);</span>
+
+ <span class="c1">// Any new code will be inserted in AfterBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">AfterBB</span><span class="p">);</span>
+
+ <span class="c1">// Restore the unshadowed variable.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">OldVal</span><span class="p">)</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">OldVal</span><span class="p">;</span>
+ <span class="k">else</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">VarName</span><span class="p">);</span>
+
+ <span class="c1">// for expr always returns 0.0.</span>
+ <span class="k">return</span> <span class="n">Constant</span><span class="o">::</span><span class="n">getNullValue</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VarExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">AllocaInst</span> <span class="o">*></span> <span class="n">OldBindings</span><span class="p">;</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Register all variables and emit their initializer.</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">;</span>
+ <span class="n">ExprAST</span> <span class="o">*</span><span class="n">Init</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">second</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
+
+ <span class="c1">// Emit the initializer before adding the variable to scope, this prevents</span>
+ <span class="c1">// the initializer from referencing the variable itself, and permits stuff</span>
+ <span class="c1">// like this:</span>
+ <span class="c1">// var a = 1 in</span>
+ <span class="c1">// var a = a in ... # refers to outer 'a'.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">InitVal</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Init</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">InitVal</span> <span class="o">=</span> <span class="n">Init</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">InitVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// If not specified, use 0.0.</span>
+ <span class="n">InitVal</span> <span class="o">=</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">));</span>
+ <span class="p">}</span>
+
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">VarName</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">InitVal</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Remember the old variable binding so that we can restore the binding when</span>
+ <span class="c1">// we unrecurse.</span>
+ <span class="n">OldBindings</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]);</span>
+
+ <span class="c1">// Remember this binding.</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Codegen the body, now that all vars are in scope.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">BodyVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">BodyVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Pop all our variables from scope.</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">]</span> <span class="o">=</span> <span class="n">OldBindings</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
+
+ <span class="c1">// Return the body computation.</span>
+ <span class="k">return</span> <span class="n">BodyVal</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">PrototypeAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Make the function type: double(double,double) etc.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Type</span> <span class="o">*></span> <span class="n">Doubles</span><span class="p">(</span><span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+ <span class="n">FunctionType</span> <span class="o">*</span><span class="n">FT</span> <span class="o">=</span>
+ <span class="n">FunctionType</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="n">Doubles</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span>
+ <span class="n">Function</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">FT</span><span class="p">,</span> <span class="n">Function</span><span class="o">::</span><span class="n">ExternalLinkage</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Set names for all arguments.</span>
+ <span class="kt">unsigned</span> <span class="n">Idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">Arg</span><span class="p">.</span><span class="n">setName</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">Idx</span><span class="o">++</span><span class="p">]);</span>
+
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Transfer ownership of the prototype to the FunctionProtos map, but keep a</span>
+ <span class="c1">// reference to it for use below.</span>
+ <span class="k">auto</span> <span class="o">&</span><span class="n">P</span> <span class="o">=</span> <span class="o">*</span><span class="n">Proto</span><span class="p">;</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">);</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If this is an operator, install it.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">isBinaryOp</span><span class="p">())</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">P</span><span class="p">.</span><span class="n">getOperatorName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">P</span><span class="p">.</span><span class="n">getBinaryPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// Create a new basic block to start insertion into.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">BB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"entry"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
+
+ <span class="c1">// Record the function arguments in the NamedValues map.</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Create an alloca for this variable.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+
+ <span class="c1">// Store the initial value into the alloca.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="o">&</span><span class="n">Arg</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Add arguments to variable symbol table.</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Error reading body, remove function.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">eraseFromParent</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">isBinaryOp</span><span class="p">())</span>
+ <span class="n">BinopPrecedence</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">getOperatorName</span><span class="p">());</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Top-Level parsing and JIT Driver</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">InitializeModuleAndPassManager</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Open a new module.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read function definition:"</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ProtoAST</span> <span class="o">=</span> <span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">ProtoAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read extern: "</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">ProtoAST</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ProtoAST</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="n">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// "Library" functions that can be "extern'd" from user code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="cp">#ifdef _WIN32</span>
+<span class="cp">#define DLLEXPORT __declspec(dllexport)</span>
+<span class="cp">#else</span>
+<span class="cp">#define DLLEXPORT</span>
+<span class="cp">#endif</span>
+
+<span class="c1">/// putchard - putchar that takes a double and returns 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fputc</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// printd - printf that takes a double prints it as "%f\n", returning 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">printd</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Main driver code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="c1">// Initialize the target registry etc.</span>
+ <span class="n">InitializeAllTargetInfos</span><span class="p">();</span>
+ <span class="n">InitializeAllTargets</span><span class="p">();</span>
+ <span class="n">InitializeAllTargetMCs</span><span class="p">();</span>
+ <span class="n">InitializeAllAsmParsers</span><span class="p">();</span>
+ <span class="n">InitializeAllAsmPrinters</span><span class="p">();</span>
+
+ <span class="k">auto</span> <span class="n">TargetTriple</span> <span class="o">=</span> <span class="n">sys</span><span class="o">::</span><span class="n">getDefaultTargetTriple</span><span class="p">();</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">setTargetTriple</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Error</span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">Target</span> <span class="o">=</span> <span class="n">TargetRegistry</span><span class="o">::</span><span class="n">lookupTarget</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">,</span> <span class="n">Error</span><span class="p">);</span>
+
+ <span class="c1">// Print an error and exit if we couldn't find the requested target.</span>
+ <span class="c1">// This generally occurs if we've forgotten to initialise the</span>
+ <span class="c1">// TargetRegistry or we have a bogus target triple.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Target</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="n">Error</span><span class="p">;</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">auto</span> <span class="n">CPU</span> <span class="o">=</span> <span class="s">"generic"</span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">Features</span> <span class="o">=</span> <span class="s">""</span><span class="p">;</span>
+
+ <span class="n">TargetOptions</span> <span class="n">opt</span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">RM</span> <span class="o">=</span> <span class="n">Optional</span><span class="o"><</span><span class="n">Reloc</span><span class="o">::</span><span class="n">Model</span><span class="o">></span><span class="p">();</span>
+ <span class="k">auto</span> <span class="n">TheTargetMachine</span> <span class="o">=</span>
+ <span class="n">Target</span><span class="o">-></span><span class="n">createTargetMachine</span><span class="p">(</span><span class="n">TargetTriple</span><span class="p">,</span> <span class="n">CPU</span><span class="p">,</span> <span class="n">Features</span><span class="p">,</span> <span class="n">opt</span><span class="p">,</span> <span class="n">RM</span><span class="p">);</span>
+
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TheTargetMachine</span><span class="o">-></span><span class="n">createDataLayout</span><span class="p">());</span>
+
+ <span class="k">auto</span> <span class="n">Filename</span> <span class="o">=</span> <span class="s">"output.o"</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">error_code</span> <span class="n">EC</span><span class="p">;</span>
+ <span class="n">raw_fd_ostream</span> <span class="nf">dest</span><span class="p">(</span><span class="n">Filename</span><span class="p">,</span> <span class="n">EC</span><span class="p">,</span> <span class="n">sys</span><span class="o">::</span><span class="n">fs</span><span class="o">::</span><span class="n">F_None</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">EC</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"Could not open file: "</span> <span class="o"><<</span> <span class="n">EC</span><span class="p">.</span><span class="n">message</span><span class="p">();</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">legacy</span><span class="o">::</span><span class="n">PassManager</span> <span class="n">pass</span><span class="p">;</span>
+ <span class="k">auto</span> <span class="n">FileType</span> <span class="o">=</span> <span class="n">TargetMachine</span><span class="o">::</span><span class="n">CGFT_ObjectFile</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">TheTargetMachine</span><span class="o">-></span><span class="n">addPassesToEmitFile</span><span class="p">(</span><span class="n">pass</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="k">nullptr</span><span class="p">,</span> <span class="n">FileType</span><span class="p">))</span> <span class="p">{</span>
+ <span class="n">errs</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"TheTargetMachine can't emit a file of this type"</span><span class="p">;</span>
+ <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">pass</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="o">*</span><span class="n">TheModule</span><span class="p">);</span>
+ <span class="n">dest</span><span class="p">.</span><span class="n">flush</span><span class="p">();</span>
+
+ <span class="n">outs</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"Wrote "</span> <span class="o"><<</span> <span class="n">Filename</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><a class="reference external" href="LangImpl09.html">Next: Adding Debug Information</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="LangImpl09.html" title="9. Kaleidoscope: Adding Debug Information"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl07.html" title="7. Kaleidoscope: Extending the Language: Mutable Variables"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-08-05.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/LangImpl09.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/LangImpl09.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/LangImpl09.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/LangImpl09.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,1946 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>9. Kaleidoscope: Adding Debug Information — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="10. Kaleidoscope: Conclusion and other useful LLVM tidbits" href="LangImpl10.html" />
+ <link rel="prev" title="8. Kaleidoscope: Compiling to Object Code" href="LangImpl08.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="LangImpl10.html" title="10. Kaleidoscope: Conclusion and other useful LLVM tidbits"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl08.html" title="8. Kaleidoscope: Compiling to Object Code"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-adding-debug-information">
+<h1>9. Kaleidoscope: Adding Debug Information<a class="headerlink" href="#kaleidoscope-adding-debug-information" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-9-introduction" id="id1">Chapter 9 Introduction</a></li>
+<li><a class="reference internal" href="#why-is-this-a-hard-problem" id="id2">Why is this a hard problem?</a></li>
+<li><a class="reference internal" href="#ahead-of-time-compilation-mode" id="id3">Ahead-of-Time Compilation Mode</a></li>
+<li><a class="reference internal" href="#compile-unit" id="id4">Compile Unit</a></li>
+<li><a class="reference internal" href="#dwarf-emission-setup" id="id5">DWARF Emission Setup</a></li>
+<li><a class="reference internal" href="#functions" id="id6">Functions</a></li>
+<li><a class="reference internal" href="#source-locations" id="id7">Source Locations</a></li>
+<li><a class="reference internal" href="#variables" id="id8">Variables</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id9">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-9-introduction">
+<h2><a class="toc-backref" href="#id1">9.1. Chapter 9 Introduction</a><a class="headerlink" href="#chapter-9-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 9 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. In chapters 1 through 8, weâve built a
+decent little programming language with functions and variables.
+What happens if something goes wrong though, how do you debug your
+program?</p>
+<p>Source level debugging uses formatted data that helps a debugger
+translate from binary and the state of the machine back to the
+source that the programmer wrote. In LLVM we generally use a format
+called <a class="reference external" href="http://dwarfstd.org">DWARF</a>. DWARF is a compact encoding
+that represents types, source locations, and variable locations.</p>
+<p>The short summary of this chapter is that weâll go through the
+various things you have to add to a programming language to
+support debug info, and how you translate that into DWARF.</p>
+<p>Caveat: For now we canât debug via the JIT, so weâll need to compile
+our program down to something small and standalone. As part of this
+weâll make a few modifications to the running of the language and
+how programs are compiled. This means that weâll have a source file
+with a simple program written in Kaleidoscope rather than the
+interactive JIT. It does involve a limitation that we can only
+have one âtop levelâ command at a time to reduce the number of
+changes necessary.</p>
+<p>Hereâs the sample program weâll be compiling:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x</span> <span class="o"><</span> <span class="mi">3</span> <span class="n">then</span>
+ <span class="mi">1</span>
+ <span class="k">else</span>
+ <span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">2</span><span class="p">);</span>
+
+<span class="n">fib</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="why-is-this-a-hard-problem">
+<h2><a class="toc-backref" href="#id2">9.2. Why is this a hard problem?</a><a class="headerlink" href="#why-is-this-a-hard-problem" title="Permalink to this headline">¶</a></h2>
+<p>Debug information is a hard problem for a few different reasons - mostly
+centered around optimized code. First, optimization makes keeping source
+locations more difficult. In LLVM IR we keep the original source location
+for each IR level instruction on the instruction. Optimization passes
+should keep the source locations for newly created instructions, but merged
+instructions only get to keep a single location - this can cause jumping
+around when stepping through optimized programs. Secondly, optimization
+can move variables in ways that are either optimized out, shared in memory
+with other variables, or difficult to track. For the purposes of this
+tutorial weâre going to avoid optimization (as youâll see with one of the
+next sets of patches).</p>
+</div>
+<div class="section" id="ahead-of-time-compilation-mode">
+<h2><a class="toc-backref" href="#id3">9.3. Ahead-of-Time Compilation Mode</a><a class="headerlink" href="#ahead-of-time-compilation-mode" title="Permalink to this headline">¶</a></h2>
+<p>To highlight only the aspects of adding debug information to a source
+language without needing to worry about the complexities of JIT debugging
+weâre going to make a few changes to Kaleidoscope to support compiling
+the IR emitted by the front end into a simple standalone program that
+you can execute, debug, and see results.</p>
+<p>First we make our anonymous function that contains our top level
+statement be our âmainâ:</p>
+<div class="highlight-udiff notranslate"><div class="highlight"><pre><span></span><span class="gd">- auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());</span>
+<span class="gi">+ auto Proto = llvm::make_unique<PrototypeAST>("main", std::vector<std::string>());</span>
+</pre></div>
+</div>
+<p>just with the simple change of giving it a name.</p>
+<p>Then weâre going to remove the command line code wherever it exists:</p>
+<div class="highlight-udiff notranslate"><div class="highlight"><pre><span></span><span class="gu">@@ -1129,7 +1129,6 @@ static void HandleTopLevelExpression() {</span>
+ /// top ::= definition | external | expression | ';'
+ static void MainLoop() {
+ while (1) {
+<span class="gd">- fprintf(stderr, "ready> ");</span>
+ switch (CurTok) {
+ case tok_eof:
+ return;
+<span class="gu">@@ -1184,7 +1183,6 @@ int main() {</span>
+ BinopPrecedence['*'] = 40; // highest.
+
+ // Prime the first token.
+<span class="gd">- fprintf(stderr, "ready> ");</span>
+ getNextToken();
+</pre></div>
+</div>
+<p>Lastly weâre going to disable all of the optimization passes and the JIT so
+that the only thing that happens after weâre done parsing and generating
+code is that the LLVM IR goes to standard error:</p>
+<div class="highlight-udiff notranslate"><div class="highlight"><pre><span></span><span class="gu">@@ -1108,17 +1108,8 @@ static void HandleExtern() {</span>
+ static void HandleTopLevelExpression() {
+ // Evaluate a top-level expression into an anonymous function.
+ if (auto FnAST = ParseTopLevelExpr()) {
+<span class="gd">- if (auto *FnIR = FnAST->codegen()) {</span>
+<span class="gd">- // We're just doing this to make sure it executes.</span>
+<span class="gd">- TheExecutionEngine->finalizeObject();</span>
+<span class="gd">- // JIT the function, returning a function pointer.</span>
+<span class="gd">- void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);</span>
+<span class="gd">-</span>
+<span class="gd">- // Cast it to the right type (takes no arguments, returns a double) so we</span>
+<span class="gd">- // can call it as a native function.</span>
+<span class="gd">- double (*FP)() = (double (*)())(intptr_t)FPtr;</span>
+<span class="gd">- // Ignore the return value for this.</span>
+<span class="gd">- (void)FP;</span>
+<span class="gi">+ if (!F->codegen()) {</span>
+<span class="gi">+ fprintf(stderr, "Error generating code for top level expr");</span>
+ }
+ } else {
+ // Skip token for error recovery.
+<span class="gu">@@ -1439,11 +1459,11 @@ int main() {</span>
+ // target lays out data structures.
+ TheModule->setDataLayout(TheExecutionEngine->getDataLayout());
+ OurFPM.add(new DataLayoutPass());
+<span class="gi">+#if 0</span>
+ OurFPM.add(createBasicAliasAnalysisPass());
+ // Promote allocas to registers.
+ OurFPM.add(createPromoteMemoryToRegisterPass());
+<span class="gu">@@ -1218,7 +1210,7 @@ int main() {</span>
+ OurFPM.add(createGVNPass());
+ // Simplify the control flow graph (deleting unreachable blocks, etc).
+ OurFPM.add(createCFGSimplificationPass());
+<span class="gd">-</span>
+<span class="gi">+ #endif</span>
+ OurFPM.doInitialization();
+
+ // Set the global so the code gen can use this.
+</pre></div>
+</div>
+<p>This relatively small set of changes get us to the point that we can compile
+our piece of Kaleidoscope language down to an executable program via this
+command line:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>Kaleidoscope-Ch9 < fib.ks <span class="p">|</span> <span class="p">&</span> clang -x ir -
+</pre></div>
+</div>
+<p>which gives an a.out/a.exe in the current working directory.</p>
+</div>
+<div class="section" id="compile-unit">
+<h2><a class="toc-backref" href="#id4">9.4. Compile Unit</a><a class="headerlink" href="#compile-unit" title="Permalink to this headline">¶</a></h2>
+<p>The top level container for a section of code in DWARF is a compile unit.
+This contains the type and function data for an individual translation unit
+(read: one file of source code). So the first thing we need to do is
+construct one for our fib.ks file.</p>
+</div>
+<div class="section" id="dwarf-emission-setup">
+<h2><a class="toc-backref" href="#id5">9.5. DWARF Emission Setup</a><a class="headerlink" href="#dwarf-emission-setup" title="Permalink to this headline">¶</a></h2>
+<p>Similar to the <code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> class we have a
+<a class="reference external" href="http://llvm.org/doxygen/classllvm_1_1DIBuilder.html">DIBuilder</a> class
+that helps in constructing debug metadata for an LLVM IR file. It
+corresponds 1:1 similarly to <code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> and LLVM IR, but with nicer names.
+Using it does require that you be more familiar with DWARF terminology than
+you needed to be with <code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> and <code class="docutils literal notranslate"><span class="pre">Instruction</span></code> names, but if you
+read through the general documentation on the
+<a class="reference external" href="http://llvm.org/docs/SourceLevelDebugging.html">Metadata Format</a> it
+should be a little more clear. Weâll be using this class to construct all
+of our IR level descriptions. Construction for it takes a module so we
+need to construct it shortly after we construct our module. Weâve left it
+as a global static variable to make it a bit easier to use.</p>
+<p>Next weâre going to create a small container to cache some of our frequent
+data. The first will be our compile unit, but weâll also write a bit of
+code for our one type since we wonât have to worry about multiple typed
+expressions:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">DIBuilder</span> <span class="o">*</span><span class="n">DBuilder</span><span class="p">;</span>
+
+<span class="k">struct</span> <span class="n">DebugInfo</span> <span class="p">{</span>
+ <span class="n">DICompileUnit</span> <span class="o">*</span><span class="n">TheCU</span><span class="p">;</span>
+ <span class="n">DIType</span> <span class="o">*</span><span class="n">DblTy</span><span class="p">;</span>
+
+ <span class="n">DIType</span> <span class="o">*</span><span class="nf">getDoubleTy</span><span class="p">();</span>
+<span class="p">}</span> <span class="n">KSDbgInfo</span><span class="p">;</span>
+
+<span class="n">DIType</span> <span class="o">*</span><span class="n">DebugInfo</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">DblTy</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DblTy</span><span class="p">;</span>
+
+ <span class="n">DblTy</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createBasicType</span><span class="p">(</span><span class="s">"double"</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="n">dwarf</span><span class="o">::</span><span class="n">DW_ATE_float</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">DblTy</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>And then later on in <code class="docutils literal notranslate"><span class="pre">main</span></code> when weâre constructing our module:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">DBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">DIBuilder</span><span class="p">(</span><span class="o">*</span><span class="n">TheModule</span><span class="p">);</span>
+
+<span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createCompileUnit</span><span class="p">(</span>
+ <span class="n">dwarf</span><span class="o">::</span><span class="n">DW_LANG_C</span><span class="p">,</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFile</span><span class="p">(</span><span class="s">"fib.ks"</span><span class="p">,</span> <span class="s">"."</span><span class="p">),</span>
+ <span class="s">"Kaleidoscope Compiler"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>There are a couple of things to note here. First, while weâre producing a
+compile unit for a language called Kaleidoscope we used the language
+constant for C. This is because a debugger wouldnât necessarily understand
+the calling conventions or default ABI for a language it doesnât recognize
+and we follow the C ABI in our LLVM code generation so itâs the closest
+thing to accurate. This ensures we can actually call functions from the
+debugger and have them execute. Secondly, youâll see the âfib.ksâ in the
+call to <code class="docutils literal notranslate"><span class="pre">createCompileUnit</span></code>. This is a default hard coded value since
+weâre using shell redirection to put our source into the Kaleidoscope
+compiler. In a usual front end youâd have an input file name and it would
+go there.</p>
+<p>One last thing as part of emitting debug information via DIBuilder is that
+we need to âfinalizeâ the debug information. The reasons are part of the
+underlying API for DIBuilder, but make sure you do this near the end of
+main:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">DBuilder</span><span class="o">-></span><span class="n">finalize</span><span class="p">();</span>
+</pre></div>
+</div>
+<p>before you dump out the module.</p>
+</div>
+<div class="section" id="functions">
+<h2><a class="toc-backref" href="#id6">9.6. Functions</a><a class="headerlink" href="#functions" title="Permalink to this headline">¶</a></h2>
+<p>Now that we have our <code class="docutils literal notranslate"><span class="pre">Compile</span> <span class="pre">Unit</span></code> and our source locations, we can add
+function definitions to the debug info. So in <code class="docutils literal notranslate"><span class="pre">PrototypeAST::codegen()</span></code> we
+add a few lines of code to describe a context for our subprogram, in this
+case the âFileâ, and the actual definition of the function itself.</p>
+<p>So the context:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">DIFile</span> <span class="o">*</span><span class="n">Unit</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFile</span><span class="p">(</span><span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span><span class="p">.</span><span class="n">getFilename</span><span class="p">(),</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span><span class="p">.</span><span class="n">getDirectory</span><span class="p">());</span>
+</pre></div>
+</div>
+<p>giving us an DIFile and asking the <code class="docutils literal notranslate"><span class="pre">Compile</span> <span class="pre">Unit</span></code> we created above for the
+directory and filename where we are currently. Then, for now, we use some
+source locations of 0 (since our AST doesnât currently have source location
+information) and construct our function definition:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">DIScope</span> <span class="o">*</span><span class="n">FContext</span> <span class="o">=</span> <span class="n">Unit</span><span class="p">;</span>
+<span class="kt">unsigned</span> <span class="n">LineNo</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="kt">unsigned</span> <span class="n">ScopeLine</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="n">DISubprogram</span> <span class="o">*</span><span class="n">SP</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFunction</span><span class="p">(</span>
+ <span class="n">FContext</span><span class="p">,</span> <span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span> <span class="n">StringRef</span><span class="p">(),</span> <span class="n">Unit</span><span class="p">,</span> <span class="n">LineNo</span><span class="p">,</span>
+ <span class="n">CreateFunctionType</span><span class="p">(</span><span class="n">TheFunction</span><span class="o">-></span><span class="n">arg_size</span><span class="p">(),</span> <span class="n">Unit</span><span class="p">),</span>
+ <span class="nb">false</span> <span class="cm">/* internal linkage */</span><span class="p">,</span> <span class="nb">true</span> <span class="cm">/* definition */</span><span class="p">,</span> <span class="n">ScopeLine</span><span class="p">,</span>
+ <span class="n">DINode</span><span class="o">::</span><span class="n">FlagPrototyped</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+<span class="n">TheFunction</span><span class="o">-></span><span class="n">setSubprogram</span><span class="p">(</span><span class="n">SP</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>and we now have an DISubprogram that contains a reference to all of our
+metadata for the function.</p>
+</div>
+<div class="section" id="source-locations">
+<h2><a class="toc-backref" href="#id7">9.7. Source Locations</a><a class="headerlink" href="#source-locations" title="Permalink to this headline">¶</a></h2>
+<p>The most important thing for debug information is accurate source location -
+this makes it possible to map your source code back. We have a problem though,
+Kaleidoscope really doesnât have any source location information in the lexer
+or parser so weâll need to add it.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span> <span class="n">SourceLocation</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">Line</span><span class="p">;</span>
+ <span class="kt">int</span> <span class="n">Col</span><span class="p">;</span>
+<span class="p">};</span>
+<span class="k">static</span> <span class="n">SourceLocation</span> <span class="n">CurLoc</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">SourceLocation</span> <span class="n">LexLoc</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
+
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">advance</span><span class="p">()</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'\n'</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'\r'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Line</span><span class="o">++</span><span class="p">;</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Col</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Col</span><span class="o">++</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">LastChar</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In this set of code weâve added some functionality on how to keep track of the
+line and column of the âsource fileâ. As we lex every token we set our current
+current âlexical locationâ to the assorted line and column for the beginning
+of the token. We do this by overriding all of the previous calls to
+<code class="docutils literal notranslate"><span class="pre">getchar()</span></code> with our new <code class="docutils literal notranslate"><span class="pre">advance()</span></code> that keeps track of the information
+and then we have added to all of our AST classes a source location:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+ <span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">;</span>
+
+ <span class="k">public</span><span class="o">:</span>
+ <span class="n">ExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">)</span> <span class="o">:</span> <span class="n">Loc</span><span class="p">(</span><span class="n">Loc</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="n">Value</span><span class="o">*</span> <span class="n">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="kt">int</span> <span class="nf">getLine</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Loc</span><span class="p">.</span><span class="n">Line</span><span class="p">;</span> <span class="p">}</span>
+ <span class="kt">int</span> <span class="nf">getCol</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Loc</span><span class="p">.</span><span class="n">Col</span><span class="p">;</span> <span class="p">}</span>
+ <span class="k">virtual</span> <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">out</span> <span class="o"><<</span> <span class="sc">':'</span> <span class="o"><<</span> <span class="n">getLine</span><span class="p">()</span> <span class="o"><<</span> <span class="sc">':'</span> <span class="o"><<</span> <span class="n">getCol</span><span class="p">()</span> <span class="o"><<</span> <span class="sc">'\n'</span><span class="p">;</span>
+ <span class="p">}</span>
+</pre></div>
+</div>
+<p>that we pass down through when we create a new expression:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinLoc</span><span class="p">,</span> <span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+</pre></div>
+</div>
+<p>giving us locations for each of our expressions and variables.</p>
+<p>To make sure that every instruction gets proper source location information,
+we have to tell <code class="docutils literal notranslate"><span class="pre">Builder</span></code> whenever weâre at a new source location.
+We use a small helper function for this:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="n">DebugInfo</span><span class="o">::</span><span class="n">emitLocation</span><span class="p">(</span><span class="n">ExprAST</span> <span class="o">*</span><span class="n">AST</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">DIScope</span> <span class="o">*</span><span class="n">Scope</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
+ <span class="n">Scope</span> <span class="o">=</span> <span class="n">TheCU</span><span class="p">;</span>
+ <span class="k">else</span>
+ <span class="n">Scope</span> <span class="o">=</span> <span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetCurrentDebugLocation</span><span class="p">(</span>
+ <span class="n">DebugLoc</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">AST</span><span class="o">-></span><span class="n">getLine</span><span class="p">(),</span> <span class="n">AST</span><span class="o">-></span><span class="n">getCol</span><span class="p">(),</span> <span class="n">Scope</span><span class="p">));</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This both tells the main <code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> where we are, but also what scope
+weâre in. The scope can either be on compile-unit level or be the nearest
+enclosing lexical block like the current function.
+To represent this we create a stack of scopes:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">DIScope</span> <span class="o">*></span> <span class="n">LexicalBlocks</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>and push the scope (function) to the top of the stack when we start
+generating the code for each function:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">SP</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>Also, we may not forget to pop the scope back off of the scope stack at the
+end of the code generation for the function:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Pop off the lexical block for the function since we added it</span>
+<span class="c1">// unconditionally.</span>
+<span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
+</pre></div>
+</div>
+<p>Then we make sure to emit the location every time we start to generate code
+for a new AST object:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="variables">
+<h2><a class="toc-backref" href="#id8">9.8. Variables</a><a class="headerlink" href="#variables" title="Permalink to this headline">¶</a></h2>
+<p>Now that we have functions, we need to be able to print out the variables
+we have in scope. Letâs get our function arguments set up so we can get
+decent backtraces and see how our functions are being called. It isnât
+a lot of code, and we generally handle it when weâre creating the
+argument allocas in <code class="docutils literal notranslate"><span class="pre">FunctionAST::codegen</span></code>.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Record the function arguments in the NamedValues map.</span>
+<span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+<span class="kt">unsigned</span> <span class="n">ArgIdx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Create an alloca for this variable.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+
+ <span class="c1">// Create a debug descriptor for the variable.</span>
+ <span class="n">DILocalVariable</span> <span class="o">*</span><span class="n">D</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createParameterVariable</span><span class="p">(</span>
+ <span class="n">SP</span><span class="p">,</span> <span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span> <span class="o">++</span><span class="n">ArgIdx</span><span class="p">,</span> <span class="n">Unit</span><span class="p">,</span> <span class="n">LineNo</span><span class="p">,</span> <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">getDoubleTy</span><span class="p">(),</span>
+ <span class="nb">true</span><span class="p">);</span>
+
+ <span class="n">DBuilder</span><span class="o">-></span><span class="n">insertDeclare</span><span class="p">(</span><span class="n">Alloca</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createExpression</span><span class="p">(),</span>
+ <span class="n">DebugLoc</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">LineNo</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SP</span><span class="p">),</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">());</span>
+
+ <span class="c1">// Store the initial value into the alloca.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="o">&</span><span class="n">Arg</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Add arguments to variable symbol table.</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Here weâre first creating the variable, giving it the scope (<code class="docutils literal notranslate"><span class="pre">SP</span></code>),
+the name, source location, type, and since itâs an argument, the argument
+index. Next, we create an <code class="docutils literal notranslate"><span class="pre">lvm.dbg.declare</span></code> call to indicate at the IR
+level that weâve got a variable in an alloca (and it gives a starting
+location for the variable), and setting a source location for the
+beginning of the scope on the declare.</p>
+<p>One interesting thing to note at this point is that various debuggers have
+assumptions based on how code and debug information was generated for them
+in the past. In this case we need to do a little bit of a hack to avoid
+generating line information for the function prologue so that the debugger
+knows to skip over those instructions when setting a breakpoint. So in
+<code class="docutils literal notranslate"><span class="pre">FunctionAST::CodeGen</span></code> we add some more lines:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Unset the location for the prologue emission (leading instructions with no</span>
+<span class="c1">// location in a function are considered part of the prologue and the debugger</span>
+<span class="c1">// will run past them when breaking on a function)</span>
+<span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">nullptr</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>and then emit a new location when we actually start generating code for the
+body of the function:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="n">Body</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+</pre></div>
+</div>
+<p>With this we have enough debug information to set breakpoints in functions,
+print out argument variables, and call functions. Not too bad for just a
+few simple lines of code!</p>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id9">9.9. Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+debug information. To build this example, use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+clang++ -g toy.cpp <span class="sb">`</span>llvm-config --cxxflags --ldflags --system-libs --libs core mcjit native<span class="sb">`</span> -O3 -o toy
+<span class="c1"># Run</span>
+./toy
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">"llvm/ADT/STLExtras.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Analysis/BasicAliasAnalysis.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Analysis/Passes.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/DIBuilder.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/IRBuilder.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LLVMContext.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LegacyPassManager.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Module.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Verifier.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/TargetSelect.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Transforms/Scalar.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cctype></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdio></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><map></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"../include/KaleidoscopeJIT.h"</span><span class="cp"></span>
+
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="p">;</span>
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="o">::</span><span class="n">orc</span><span class="p">;</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Lexer</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span><span class="p">,</span>
+
+ <span class="c1">// control</span>
+ <span class="n">tok_if</span> <span class="o">=</span> <span class="o">-</span><span class="mi">6</span><span class="p">,</span>
+ <span class="n">tok_then</span> <span class="o">=</span> <span class="o">-</span><span class="mi">7</span><span class="p">,</span>
+ <span class="n">tok_else</span> <span class="o">=</span> <span class="o">-</span><span class="mi">8</span><span class="p">,</span>
+ <span class="n">tok_for</span> <span class="o">=</span> <span class="o">-</span><span class="mi">9</span><span class="p">,</span>
+ <span class="n">tok_in</span> <span class="o">=</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span>
+
+ <span class="c1">// operators</span>
+ <span class="n">tok_binary</span> <span class="o">=</span> <span class="o">-</span><span class="mi">11</span><span class="p">,</span>
+ <span class="n">tok_unary</span> <span class="o">=</span> <span class="o">-</span><span class="mi">12</span><span class="p">,</span>
+
+ <span class="c1">// var definition</span>
+ <span class="n">tok_var</span> <span class="o">=</span> <span class="o">-</span><span class="mi">13</span>
+<span class="p">};</span>
+
+<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">getTokName</span><span class="p">(</span><span class="kt">int</span> <span class="n">Tok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Tok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"eof"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"def"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"extern"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"identifier"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"number"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_if</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"if"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_then</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"then"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_else</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"else"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_for</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"for"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_in</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"in"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_binary</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"binary"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_unary</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"unary"</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_var</span><span class="p">:</span>
+ <span class="k">return</span> <span class="s">"var"</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">Tok</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="k">namespace</span> <span class="p">{</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span><span class="p">;</span>
+<span class="k">class</span> <span class="nc">ExprAST</span><span class="p">;</span>
+<span class="p">}</span>
+<span class="k">static</span> <span class="n">LLVMContext</span> <span class="n">TheContext</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">Builder</span><span class="p">(</span><span class="n">TheContext</span><span class="p">);</span>
+<span class="k">struct</span> <span class="n">DebugInfo</span> <span class="p">{</span>
+ <span class="n">DICompileUnit</span> <span class="o">*</span><span class="n">TheCU</span><span class="p">;</span>
+ <span class="n">DIType</span> <span class="o">*</span><span class="n">DblTy</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">DIScope</span> <span class="o">*></span> <span class="n">LexicalBlocks</span><span class="p">;</span>
+
+ <span class="kt">void</span> <span class="nf">emitLocation</span><span class="p">(</span><span class="n">ExprAST</span> <span class="o">*</span><span class="n">AST</span><span class="p">);</span>
+ <span class="n">DIType</span> <span class="o">*</span><span class="nf">getDoubleTy</span><span class="p">();</span>
+<span class="p">}</span> <span class="n">KSDbgInfo</span><span class="p">;</span>
+
+<span class="k">struct</span> <span class="n">SourceLocation</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">Line</span><span class="p">;</span>
+ <span class="kt">int</span> <span class="n">Col</span><span class="p">;</span>
+<span class="p">};</span>
+<span class="k">static</span> <span class="n">SourceLocation</span> <span class="n">CurLoc</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">SourceLocation</span> <span class="n">LexLoc</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span>
+
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">advance</span><span class="p">()</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'\n'</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'\r'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Line</span><span class="o">++</span><span class="p">;</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Col</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span>
+ <span class="n">LexLoc</span><span class="p">.</span><span class="n">Col</span><span class="o">++</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">LastChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+
+<span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">advance</span><span class="p">();</span>
+
+ <span class="n">CurLoc</span> <span class="o">=</span> <span class="n">LexLoc</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">advance</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"if"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_if</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"then"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_then</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"else"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_else</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"for"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_for</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"in"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_in</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"binary"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_binary</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"unary"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_unary</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"var"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_var</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">advance</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">advance</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">advance</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="k">namespace</span> <span class="p">{</span>
+
+<span class="n">raw_ostream</span> <span class="o">&</span><span class="n">indent</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">O</span><span class="p">,</span> <span class="kt">int</span> <span class="n">size</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">O</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="sc">' '</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+ <span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">ExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">)</span> <span class="o">:</span> <span class="n">Loc</span><span class="p">(</span><span class="n">Loc</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="kt">int</span> <span class="nf">getLine</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Loc</span><span class="p">.</span><span class="n">Line</span><span class="p">;</span> <span class="p">}</span>
+ <span class="kt">int</span> <span class="nf">getCol</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Loc</span><span class="p">.</span><span class="n">Col</span><span class="p">;</span> <span class="p">}</span>
+ <span class="k">virtual</span> <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">out</span> <span class="o"><<</span> <span class="sc">':'</span> <span class="o"><<</span> <span class="n">getLine</span><span class="p">()</span> <span class="o"><<</span> <span class="sc">':'</span> <span class="o"><<</span> <span class="n">getCol</span><span class="p">()</span> <span class="o"><<</span> <span class="sc">'\n'</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="n">Val</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">ExprAST</span><span class="p">(</span><span class="n">Loc</span><span class="p">),</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="n">Name</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// UnaryExprAST - Expression class for a unary operator.</span>
+<span class="k">class</span> <span class="nc">UnaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Opcode</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Operand</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">UnaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Opcode</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Operand</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Opcode</span><span class="p">(</span><span class="n">Opcode</span><span class="p">),</span> <span class="n">Operand</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Operand</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"unary"</span> <span class="o"><<</span> <span class="n">Opcode</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="n">Operand</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">,</span> <span class="kt">char</span> <span class="n">Op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">ExprAST</span><span class="p">(</span><span class="n">Loc</span><span class="p">),</span> <span class="n">Op</span><span class="p">(</span><span class="n">Op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"binary"</span> <span class="o"><<</span> <span class="n">Op</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="n">LHS</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"LHS:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">RHS</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"RHS:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">ExprAST</span><span class="p">(</span><span class="n">Loc</span><span class="p">),</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"call "</span> <span class="o"><<</span> <span class="n">Callee</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">Args</span><span class="p">)</span>
+ <span class="n">Arg</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// IfExprAST - Expression class for if/then/else.</span>
+<span class="k">class</span> <span class="nc">IfExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Cond</span><span class="p">,</span> <span class="n">Then</span><span class="p">,</span> <span class="n">Else</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">IfExprAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Cond</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Then</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Else</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">ExprAST</span><span class="p">(</span><span class="n">Loc</span><span class="p">),</span> <span class="n">Cond</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Cond</span><span class="p">)),</span> <span class="n">Then</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Then</span><span class="p">)),</span>
+ <span class="n">Else</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Else</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"if"</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="n">Cond</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Cond:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">Then</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Then:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">Else</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Else:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// ForExprAST - Expression class for for/in.</span>
+<span class="k">class</span> <span class="nc">ForExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">VarName</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Start</span><span class="p">,</span> <span class="n">End</span><span class="p">,</span> <span class="n">Step</span><span class="p">,</span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">ForExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Start</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">End</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Step</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">VarName</span><span class="p">(</span><span class="n">VarName</span><span class="p">),</span> <span class="n">Start</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Start</span><span class="p">)),</span> <span class="n">End</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">End</span><span class="p">)),</span>
+ <span class="n">Step</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Step</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"for"</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="n">Start</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Cond:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">End</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"End:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">Step</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Step:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">Body</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Body:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// VarExprAST - Expression class for var/in</span>
+<span class="k">class</span> <span class="nc">VarExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VarExprAST</span><span class="p">(</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">VarNames</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">VarNames</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="k">override</span> <span class="p">{</span>
+ <span class="n">ExprAST</span><span class="o">::</span><span class="n">dump</span><span class="p">(</span><span class="n">out</span> <span class="o"><<</span> <span class="s">"var"</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&</span><span class="nl">NamedVar</span> <span class="p">:</span> <span class="n">VarNames</span><span class="p">)</span>
+ <span class="n">NamedVar</span><span class="p">.</span><span class="n">second</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="n">NamedVar</span><span class="p">.</span><span class="n">first</span> <span class="o"><<</span> <span class="sc">':'</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="n">Body</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Body:"</span><span class="p">,</span> <span class="n">ind</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">out</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes), as well as if it is an operator.</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="kt">bool</span> <span class="n">IsOperator</span><span class="p">;</span>
+ <span class="kt">unsigned</span> <span class="n">Precedence</span><span class="p">;</span> <span class="c1">// Precedence if a binary op.</span>
+ <span class="kt">int</span> <span class="n">Line</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="n">SourceLocation</span> <span class="n">Loc</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">,</span> <span class="kt">bool</span> <span class="n">IsOperator</span> <span class="o">=</span> <span class="nb">false</span><span class="p">,</span>
+ <span class="kt">unsigned</span> <span class="n">Prec</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">)),</span> <span class="n">IsOperator</span><span class="p">(</span><span class="n">IsOperator</span><span class="p">),</span>
+ <span class="n">Precedence</span><span class="p">(</span><span class="n">Prec</span><span class="p">),</span> <span class="n">Line</span><span class="p">(</span><span class="n">Loc</span><span class="p">.</span><span class="n">Line</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+
+ <span class="kt">bool</span> <span class="n">isUnaryOp</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">IsOperator</span> <span class="o">&&</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span>
+ <span class="kt">bool</span> <span class="n">isBinaryOp</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">IsOperator</span> <span class="o">&&</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">;</span> <span class="p">}</span>
+
+ <span class="kt">char</span> <span class="n">getOperatorName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">isUnaryOp</span><span class="p">()</span> <span class="o">||</span> <span class="n">isBinaryOp</span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">Name</span><span class="p">[</span><span class="n">Name</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">-</span> <span class="mi">1</span><span class="p">];</span>
+ <span class="p">}</span>
+
+ <span class="kt">unsigned</span> <span class="n">getBinaryPrecedence</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Precedence</span><span class="p">;</span> <span class="p">}</span>
+ <span class="kt">int</span> <span class="n">getLine</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Line</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">raw_ostream</span> <span class="o">&</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&</span><span class="n">out</span><span class="p">,</span> <span class="kt">int</span> <span class="n">ind</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"FunctionAST</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
+ <span class="o">++</span><span class="n">ind</span><span class="p">;</span>
+ <span class="n">indent</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o"><<</span> <span class="s">"Body:"</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">Body</span> <span class="o">?</span> <span class="n">Body</span><span class="o">-></span><span class="n">dump</span><span class="p">(</span><span class="n">out</span><span class="p">,</span> <span class="n">ind</span><span class="p">)</span> <span class="o">:</span> <span class="n">out</span> <span class="o"><<</span> <span class="s">"null</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
+ <span class="p">}</span>
+<span class="p">};</span>
+<span class="p">}</span> <span class="c1">// end anonymous namespace</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Parser</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span> <span class="p">}</span>
+
+<span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">();</span>
+
+<span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">SourceLocation</span> <span class="n">LitLoc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">LitLoc</span><span class="p">,</span> <span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">LitLoc</span><span class="p">,</span> <span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// ifexpr ::= 'if' expression 'then' expression 'else' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIfExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">SourceLocation</span> <span class="n">IfLoc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the if.</span>
+
+ <span class="c1">// condition.</span>
+ <span class="k">auto</span> <span class="n">Cond</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Cond</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_then</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected then"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the then</span>
+
+ <span class="k">auto</span> <span class="n">Then</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Then</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_else</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected else"</span><span class="p">);</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">auto</span> <span class="n">Else</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Else</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">IfExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IfLoc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Cond</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Then</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Else</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseForExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the for.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier after for"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'='</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected '=' after for"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat '='.</span>
+
+ <span class="k">auto</span> <span class="n">Start</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Start</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ',' after for start value"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">auto</span> <span class="n">End</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">End</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// The step value is optional.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Step</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">','</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="n">Step</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Step</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_in</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected 'in' after for"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat 'in'.</span>
+
+ <span class="k">auto</span> <span class="n">Body</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">ForExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Start</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">End</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Step</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// varexpr ::= 'var' identifier ('=' expression)?</span>
+<span class="c1">// (',' identifier ('=' expression)?)* 'in' expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseVarExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the var.</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>>></span> <span class="n">VarNames</span><span class="p">;</span>
+
+ <span class="c1">// At least one variable name is required.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier after var"</span><span class="p">);</span>
+
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="c1">// Read the optional initializer.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Init</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">'='</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the '='.</span>
+
+ <span class="n">Init</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Init</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">VarNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_pair</span><span class="p">(</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Init</span><span class="p">)));</span>
+
+ <span class="c1">// End of var list, exit loop.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the ','.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected identifier list after var"</span><span class="p">);</span>
+ <span class="p">}</span>
+
+ <span class="c1">// At this point, we have to have 'in'.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_in</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected 'in' keyword after 'var'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat 'in'.</span>
+
+ <span class="k">auto</span> <span class="n">Body</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VarExprAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">VarNames</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="c1">/// ::= ifexpr</span>
+<span class="c1">/// ::= forexpr</span>
+<span class="c1">/// ::= varexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_if</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIfExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_for</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseForExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_var</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseVarExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// unary</span>
+<span class="c1">/// ::= primary</span>
+<span class="c1">/// ::= '!' unary</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseUnary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// If the current token is not an operator, it must be a primary expr.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="o">||</span> <span class="n">CurTok</span> <span class="o">==</span> <span class="sc">'('</span> <span class="o">||</span> <span class="n">CurTok</span> <span class="o">==</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+
+ <span class="c1">// If this is a unary operator, read it.</span>
+ <span class="kt">int</span> <span class="n">Opc</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Operand</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">UnaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">Opc</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Operand</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' unary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+
+ <span class="c1">// Okay, we know this is a binop.</span>
+ <span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">SourceLocation</span> <span class="n">BinLoc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+ <span class="c1">// Parse the unary expression after the binary operator.</span>
+ <span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinLoc</span><span class="p">,</span> <span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// expression</span>
+<span class="c1">/// ::= unary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParseUnary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="c1">/// ::= binary LETTER number? (id, id)</span>
+<span class="c1">/// ::= unary LETTER (id)</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span><span class="p">;</span>
+
+ <span class="n">SourceLocation</span> <span class="n">FnLoc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">;</span>
+
+ <span class="kt">unsigned</span> <span class="n">Kind</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// 0 = identifier, 1 = unary, 2 = binary.</span>
+ <span class="kt">unsigned</span> <span class="n">BinaryPrecedence</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_unary</span><span class="p">:</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected unary operator"</span><span class="p">);</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="s">"unary"</span><span class="p">;</span>
+ <span class="n">FnName</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_binary</span><span class="p">:</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected binary operator"</span><span class="p">);</span>
+ <span class="n">FnName</span> <span class="o">=</span> <span class="s">"binary"</span><span class="p">;</span>
+ <span class="n">FnName</span> <span class="o">+=</span> <span class="p">(</span><span class="kt">char</span><span class="p">)</span><span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">Kind</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="c1">// Read the precedence if present.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="n">tok_number</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">NumVal</span> <span class="o"><</span> <span class="mi">1</span> <span class="o">||</span> <span class="n">NumVal</span> <span class="o">></span> <span class="mi">100</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Invalid precedence: must be 1..100"</span><span class="p">);</span>
+ <span class="n">BinaryPrecedence</span> <span class="o">=</span> <span class="p">(</span><span class="kt">unsigned</span><span class="p">)</span><span class="n">NumVal</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="c1">// Verify right number of names for operator.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Kind</span> <span class="o">&&</span> <span class="n">ArgNames</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Kind</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Invalid number of operands for operator"</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnLoc</span><span class="p">,</span> <span class="n">FnName</span><span class="p">,</span> <span class="n">ArgNames</span><span class="p">,</span> <span class="n">Kind</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span>
+ <span class="n">BinaryPrecedence</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">SourceLocation</span> <span class="n">FnLoc</span> <span class="o">=</span> <span class="n">CurLoc</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnLoc</span><span class="p">,</span> <span class="s">"__anon_expr"</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Debug Info Support</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">DIBuilder</span><span class="o">></span> <span class="n">DBuilder</span><span class="p">;</span>
+
+<span class="n">DIType</span> <span class="o">*</span><span class="n">DebugInfo</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">DblTy</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">DblTy</span><span class="p">;</span>
+
+ <span class="n">DblTy</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createBasicType</span><span class="p">(</span><span class="s">"double"</span><span class="p">,</span> <span class="mi">64</span><span class="p">,</span> <span class="n">dwarf</span><span class="o">::</span><span class="n">DW_ATE_float</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">DblTy</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="kt">void</span> <span class="n">DebugInfo</span><span class="o">::</span><span class="n">emitLocation</span><span class="p">(</span><span class="n">ExprAST</span> <span class="o">*</span><span class="n">AST</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">AST</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">SetCurrentDebugLocation</span><span class="p">(</span><span class="n">DebugLoc</span><span class="p">());</span>
+ <span class="n">DIScope</span> <span class="o">*</span><span class="n">Scope</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
+ <span class="n">Scope</span> <span class="o">=</span> <span class="n">TheCU</span><span class="p">;</span>
+ <span class="k">else</span>
+ <span class="n">Scope</span> <span class="o">=</span> <span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">back</span><span class="p">();</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetCurrentDebugLocation</span><span class="p">(</span>
+ <span class="n">DebugLoc</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">AST</span><span class="o">-></span><span class="n">getLine</span><span class="p">(),</span> <span class="n">AST</span><span class="o">-></span><span class="n">getCol</span><span class="p">(),</span> <span class="n">Scope</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">DISubroutineType</span> <span class="o">*</span><span class="n">CreateFunctionType</span><span class="p">(</span><span class="kt">unsigned</span> <span class="n">NumArgs</span><span class="p">,</span> <span class="n">DIFile</span> <span class="o">*</span><span class="n">Unit</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">SmallVector</span><span class="o"><</span><span class="n">Metadata</span> <span class="o">*</span><span class="p">,</span> <span class="mi">8</span><span class="o">></span> <span class="n">EltTys</span><span class="p">;</span>
+ <span class="n">DIType</span> <span class="o">*</span><span class="n">DblTy</span> <span class="o">=</span> <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">getDoubleTy</span><span class="p">();</span>
+
+ <span class="c1">// Add the result type.</span>
+ <span class="n">EltTys</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">DblTy</span><span class="p">);</span>
+
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">NumArgs</span><span class="p">;</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
+ <span class="n">EltTys</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">DblTy</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createSubroutineType</span><span class="p">(</span><span class="n">DBuilder</span><span class="o">-></span><span class="n">getOrCreateTypeArray</span><span class="p">(</span><span class="n">EltTys</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Code Generation</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">Module</span><span class="o">></span> <span class="n">TheModule</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">AllocaInst</span> <span class="o">*></span> <span class="n">NamedValues</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span> <span class="n">TheJIT</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">>></span> <span class="n">FunctionProtos</span><span class="p">;</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="nf">LogErrorV</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="nf">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// First, see if the function has already been added to the current module.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Name</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+
+ <span class="c1">// If not, check whether we can codegen the declaration from some existing</span>
+ <span class="c1">// prototype.</span>
+ <span class="k">auto</span> <span class="n">FI</span> <span class="o">=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">Name</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FI</span> <span class="o">!=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">FI</span><span class="o">-></span><span class="n">second</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="c1">// If no existing prototype exists, return null.</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of</span>
+<span class="c1">/// the function. This is used for mutable variables etc.</span>
+<span class="k">static</span> <span class="n">AllocaInst</span> <span class="o">*</span><span class="nf">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span><span class="p">,</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">TmpB</span><span class="p">(</span><span class="o">&</span><span class="n">TheFunction</span><span class="o">-></span><span class="n">getEntryBlock</span><span class="p">(),</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getEntryBlock</span><span class="p">().</span><span class="n">begin</span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">TmpB</span><span class="p">.</span><span class="n">CreateAlloca</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="k">nullptr</span><span class="p">,</span>
+ <span class="n">VarName</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">NumberExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="n">Val</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VariableExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look this variable up in the function.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">V</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">Name</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+ <span class="c1">// Load the value.</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateLoad</span><span class="p">(</span><span class="n">V</span><span class="p">,</span> <span class="n">Name</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">UnaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">OperandV</span> <span class="o">=</span> <span class="n">Operand</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">OperandV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"unary"</span><span class="p">)</span> <span class="o">+</span> <span class="n">Opcode</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">F</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown unary operator"</span><span class="p">);</span>
+
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">OperandV</span><span class="p">,</span> <span class="s">"unop"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">BinaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+
+ <span class="c1">// Special case '=' because we don't want to emit the LHS as an expression.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Op</span> <span class="o">==</span> <span class="sc">'='</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Assignment requires the LHS to be an identifier.</span>
+ <span class="c1">// This assume we're building without RTTI because LLVM builds that way by</span>
+ <span class="c1">// default. If you build LLVM with RTTI this can be changed to a</span>
+ <span class="c1">// dynamic_cast for automatic error checking.</span>
+ <span class="n">VariableExprAST</span> <span class="o">*</span><span class="n">LHSE</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o"><</span><span class="n">VariableExprAST</span> <span class="o">*></span><span class="p">(</span><span class="n">LHS</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHSE</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"destination of '=' must be a variable"</span><span class="p">);</span>
+ <span class="c1">// Codegen the RHS.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Val</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Val</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Look up the name.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Variable</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">LHSE</span><span class="o">-></span><span class="n">getName</span><span class="p">()];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Variable</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">Val</span><span class="p">,</span> <span class="n">Variable</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">Val</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">L</span> <span class="o">=</span> <span class="n">LHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">R</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">L</span> <span class="o">||</span> <span class="o">!</span><span class="n">R</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Op</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="sc">'+'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"addtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'-'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFSub</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"subtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'*'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFMul</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"multmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'<'</span><span class="o">:</span>
+ <span class="n">L</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpULT</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"cmptmp"</span><span class="p">);</span>
+ <span class="c1">// Convert bool 0/1 to double 0.0 or 1.0</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateUIToFP</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="s">"booltmp"</span><span class="p">);</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// If it wasn't a builtin binary operator, it must be a user defined one. Emit</span>
+ <span class="c1">// a call to it.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"binary"</span><span class="p">)</span> <span class="o">+</span> <span class="n">Op</span><span class="p">);</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">F</span> <span class="o">&&</span> <span class="s">"binary operator not found!"</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">Ops</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">};</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">Ops</span><span class="p">,</span> <span class="s">"binop"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CalleeF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown function referenced"</span><span class="p">);</span>
+
+ <span class="c1">// If argument mismatch error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CalleeF</span><span class="o">-></span><span class="n">arg_size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Incorrect # arguments passed"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Value</span> <span class="o">*></span> <span class="n">ArgsV</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">ArgsV</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">codegen</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ArgsV</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">CalleeF</span><span class="p">,</span> <span class="n">ArgsV</span><span class="p">,</span> <span class="s">"calltmp"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">IfExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">CondV</span> <span class="o">=</span> <span class="n">Cond</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CondV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Convert condition to a bool by comparing non-equal to 0.0.</span>
+ <span class="n">CondV</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpONE</span><span class="p">(</span>
+ <span class="n">CondV</span><span class="p">,</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)),</span> <span class="s">"ifcond"</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Create blocks for the then and else cases. Insert the 'then' block at the</span>
+ <span class="c1">// end of the function.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">ThenBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"then"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">ElseBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"else"</span><span class="p">);</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">MergeBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"ifcont"</span><span class="p">);</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCondBr</span><span class="p">(</span><span class="n">CondV</span><span class="p">,</span> <span class="n">ThenBB</span><span class="p">,</span> <span class="n">ElseBB</span><span class="p">);</span>
+
+ <span class="c1">// Emit then value.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">ThenBB</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">ThenV</span> <span class="o">=</span> <span class="n">Then</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ThenV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="c1">// Codegen of 'Then' can change the current block, update ThenBB for the PHI.</span>
+ <span class="n">ThenBB</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">();</span>
+
+ <span class="c1">// Emit else block.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getBasicBlockList</span><span class="p">().</span><span class="n">push_back</span><span class="p">(</span><span class="n">ElseBB</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">ElseBB</span><span class="p">);</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">ElseV</span> <span class="o">=</span> <span class="n">Else</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ElseV</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="c1">// Codegen of 'Else' can change the current block, update ElseBB for the PHI.</span>
+ <span class="n">ElseBB</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">();</span>
+
+ <span class="c1">// Emit merge block.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">getBasicBlockList</span><span class="p">().</span><span class="n">push_back</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">MergeBB</span><span class="p">);</span>
+ <span class="n">PHINode</span> <span class="o">*</span><span class="n">PN</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreatePHI</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="mi">2</span><span class="p">,</span> <span class="s">"iftmp"</span><span class="p">);</span>
+
+ <span class="n">PN</span><span class="o">-></span><span class="n">addIncoming</span><span class="p">(</span><span class="n">ThenV</span><span class="p">,</span> <span class="n">ThenBB</span><span class="p">);</span>
+ <span class="n">PN</span><span class="o">-></span><span class="n">addIncoming</span><span class="p">(</span><span class="n">ElseV</span><span class="p">,</span> <span class="n">ElseBB</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">PN</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">// Output for-loop as:</span>
+<span class="c1">// var = alloca double</span>
+<span class="c1">// ...</span>
+<span class="c1">// start = startexpr</span>
+<span class="c1">// store start -> var</span>
+<span class="c1">// goto loop</span>
+<span class="c1">// loop:</span>
+<span class="c1">// ...</span>
+<span class="c1">// bodyexpr</span>
+<span class="c1">// ...</span>
+<span class="c1">// loopend:</span>
+<span class="c1">// step = stepexpr</span>
+<span class="c1">// endcond = endexpr</span>
+<span class="c1">//</span>
+<span class="c1">// curvar = load var</span>
+<span class="c1">// nextvar = curvar + step</span>
+<span class="c1">// store nextvar -> var</span>
+<span class="c1">// br endcond, loop, endloop</span>
+<span class="c1">// outloop:</span>
+<span class="n">Value</span> <span class="o">*</span><span class="n">ForExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Create an alloca for the variable in the entry block.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">VarName</span><span class="p">);</span>
+
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+
+ <span class="c1">// Emit the start code first, without 'variable' in scope.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">StartVal</span> <span class="o">=</span> <span class="n">Start</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">StartVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Store the value into the alloca.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">StartVal</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Make the new basic block for the loop header, inserting after current</span>
+ <span class="c1">// block.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">LoopBB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"loop"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Insert an explicit fall through from the current block to the LoopBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateBr</span><span class="p">(</span><span class="n">LoopBB</span><span class="p">);</span>
+
+ <span class="c1">// Start insertion in LoopBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">LoopBB</span><span class="p">);</span>
+
+ <span class="c1">// Within the loop, the variable is defined equal to the PHI node. If it</span>
+ <span class="c1">// shadows an existing variable, we have to restore it, so save it now.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">OldVal</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">];</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+
+ <span class="c1">// Emit the body of the loop. This, like any other expr, can change the</span>
+ <span class="c1">// current BB. Note that we ignore the value computed by the body, but don't</span>
+ <span class="c1">// allow an error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Emit the step value.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">StepVal</span> <span class="o">=</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Step</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">StepVal</span> <span class="o">=</span> <span class="n">Step</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">StepVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// If not specified, use 1.0.</span>
+ <span class="n">StepVal</span> <span class="o">=</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">1.0</span><span class="p">));</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Compute the end condition.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">EndCond</span> <span class="o">=</span> <span class="n">End</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">EndCond</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Reload, increment, and restore the alloca. This handles the case where</span>
+ <span class="c1">// the body of the loop mutates the variable.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">CurVar</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateLoad</span><span class="p">(</span><span class="n">Alloca</span><span class="p">,</span> <span class="n">VarName</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">NextVar</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">CurVar</span><span class="p">,</span> <span class="n">StepVal</span><span class="p">,</span> <span class="s">"nextvar"</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">NextVar</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Convert condition to a bool by comparing non-equal to 0.0.</span>
+ <span class="n">EndCond</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpONE</span><span class="p">(</span>
+ <span class="n">EndCond</span><span class="p">,</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">)),</span> <span class="s">"loopcond"</span><span class="p">);</span>
+
+ <span class="c1">// Create the "after loop" block and insert it.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">AfterBB</span> <span class="o">=</span>
+ <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"afterloop"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Insert the conditional branch into the end of LoopEndBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCondBr</span><span class="p">(</span><span class="n">EndCond</span><span class="p">,</span> <span class="n">LoopBB</span><span class="p">,</span> <span class="n">AfterBB</span><span class="p">);</span>
+
+ <span class="c1">// Any new code will be inserted in AfterBB.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">AfterBB</span><span class="p">);</span>
+
+ <span class="c1">// Restore the unshadowed variable.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">OldVal</span><span class="p">)</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">OldVal</span><span class="p">;</span>
+ <span class="k">else</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">VarName</span><span class="p">);</span>
+
+ <span class="c1">// for expr always returns 0.0.</span>
+ <span class="k">return</span> <span class="n">Constant</span><span class="o">::</span><span class="n">getNullValue</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VarExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">AllocaInst</span> <span class="o">*></span> <span class="n">OldBindings</span><span class="p">;</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">()</span><span class="o">-></span><span class="n">getParent</span><span class="p">();</span>
+
+ <span class="c1">// Register all variables and emit their initializer.</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">VarName</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">;</span>
+ <span class="n">ExprAST</span> <span class="o">*</span><span class="n">Init</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">second</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
+
+ <span class="c1">// Emit the initializer before adding the variable to scope, this prevents</span>
+ <span class="c1">// the initializer from referencing the variable itself, and permits stuff</span>
+ <span class="c1">// like this:</span>
+ <span class="c1">// var a = 1 in</span>
+ <span class="c1">// var a = a in ... # refers to outer 'a'.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">InitVal</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Init</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">InitVal</span> <span class="o">=</span> <span class="n">Init</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">InitVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// If not specified, use 0.0.</span>
+ <span class="n">InitVal</span> <span class="o">=</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="mf">0.0</span><span class="p">));</span>
+ <span class="p">}</span>
+
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">VarName</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="n">InitVal</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Remember the old variable binding so that we can restore the binding when</span>
+ <span class="c1">// we unrecurse.</span>
+ <span class="n">OldBindings</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]);</span>
+
+ <span class="c1">// Remember this binding.</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarName</span><span class="p">]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
+
+ <span class="c1">// Codegen the body, now that all vars are in scope.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">BodyVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">BodyVal</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Pop all our variables from scope.</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">VarNames</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">VarNames</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">first</span><span class="p">]</span> <span class="o">=</span> <span class="n">OldBindings</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
+
+ <span class="c1">// Return the body computation.</span>
+ <span class="k">return</span> <span class="n">BodyVal</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">PrototypeAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Make the function type: double(double,double) etc.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Type</span> <span class="o">*></span> <span class="n">Doubles</span><span class="p">(</span><span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+ <span class="n">FunctionType</span> <span class="o">*</span><span class="n">FT</span> <span class="o">=</span>
+ <span class="n">FunctionType</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="n">Doubles</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span>
+ <span class="n">Function</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">FT</span><span class="p">,</span> <span class="n">Function</span><span class="o">::</span><span class="n">ExternalLinkage</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Set names for all arguments.</span>
+ <span class="kt">unsigned</span> <span class="n">Idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">Arg</span><span class="p">.</span><span class="n">setName</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">Idx</span><span class="o">++</span><span class="p">]);</span>
+
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Transfer ownership of the prototype to the FunctionProtos map, but keep a</span>
+ <span class="c1">// reference to it for use below.</span>
+ <span class="k">auto</span> <span class="o">&</span><span class="n">P</span> <span class="o">=</span> <span class="o">*</span><span class="n">Proto</span><span class="p">;</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">);</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If this is an operator, install it.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">isBinaryOp</span><span class="p">())</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">P</span><span class="p">.</span><span class="n">getOperatorName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">P</span><span class="p">.</span><span class="n">getBinaryPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// Create a new basic block to start insertion into.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">BB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"entry"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
+
+ <span class="c1">// Create a subprogram DIE for this function.</span>
+ <span class="n">DIFile</span> <span class="o">*</span><span class="n">Unit</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFile</span><span class="p">(</span><span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span><span class="o">-></span><span class="n">getFilename</span><span class="p">(),</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span><span class="o">-></span><span class="n">getDirectory</span><span class="p">());</span>
+ <span class="n">DIScope</span> <span class="o">*</span><span class="n">FContext</span> <span class="o">=</span> <span class="n">Unit</span><span class="p">;</span>
+ <span class="kt">unsigned</span> <span class="n">LineNo</span> <span class="o">=</span> <span class="n">P</span><span class="p">.</span><span class="n">getLine</span><span class="p">();</span>
+ <span class="kt">unsigned</span> <span class="n">ScopeLine</span> <span class="o">=</span> <span class="n">LineNo</span><span class="p">;</span>
+ <span class="n">DISubprogram</span> <span class="o">*</span><span class="n">SP</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFunction</span><span class="p">(</span>
+ <span class="n">FContext</span><span class="p">,</span> <span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span> <span class="n">StringRef</span><span class="p">(),</span> <span class="n">Unit</span><span class="p">,</span> <span class="n">LineNo</span><span class="p">,</span>
+ <span class="n">CreateFunctionType</span><span class="p">(</span><span class="n">TheFunction</span><span class="o">-></span><span class="n">arg_size</span><span class="p">(),</span> <span class="n">Unit</span><span class="p">),</span> <span class="n">ScopeLine</span><span class="p">,</span>
+ <span class="n">DINode</span><span class="o">::</span><span class="n">FlagPrototyped</span><span class="p">,</span> <span class="n">DISubprogram</span><span class="o">::</span><span class="n">SPFlagDefinition</span><span class="p">);</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">setSubprogram</span><span class="p">(</span><span class="n">SP</span><span class="p">);</span>
+
+ <span class="c1">// Push the current scope.</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">SP</span><span class="p">);</span>
+
+ <span class="c1">// Unset the location for the prologue emission (leading instructions with no</span>
+ <span class="c1">// location in a function are considered part of the prologue and the debugger</span>
+ <span class="c1">// will run past them when breaking on a function)</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="k">nullptr</span><span class="p">);</span>
+
+ <span class="c1">// Record the function arguments in the NamedValues map.</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+ <span class="kt">unsigned</span> <span class="n">ArgIdx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Create an alloca for this variable.</span>
+ <span class="n">AllocaInst</span> <span class="o">*</span><span class="n">Alloca</span> <span class="o">=</span> <span class="n">CreateEntryBlockAlloca</span><span class="p">(</span><span class="n">TheFunction</span><span class="p">,</span> <span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+
+ <span class="c1">// Create a debug descriptor for the variable.</span>
+ <span class="n">DILocalVariable</span> <span class="o">*</span><span class="n">D</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createParameterVariable</span><span class="p">(</span>
+ <span class="n">SP</span><span class="p">,</span> <span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">(),</span> <span class="o">++</span><span class="n">ArgIdx</span><span class="p">,</span> <span class="n">Unit</span><span class="p">,</span> <span class="n">LineNo</span><span class="p">,</span> <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">getDoubleTy</span><span class="p">(),</span>
+ <span class="nb">true</span><span class="p">);</span>
+
+ <span class="n">DBuilder</span><span class="o">-></span><span class="n">insertDeclare</span><span class="p">(</span><span class="n">Alloca</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createExpression</span><span class="p">(),</span>
+ <span class="n">DebugLoc</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">LineNo</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">SP</span><span class="p">),</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">GetInsertBlock</span><span class="p">());</span>
+
+ <span class="c1">// Store the initial value into the alloca.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateStore</span><span class="p">(</span><span class="o">&</span><span class="n">Arg</span><span class="p">,</span> <span class="n">Alloca</span><span class="p">);</span>
+
+ <span class="c1">// Add arguments to variable symbol table.</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">Alloca</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">emitLocation</span><span class="p">(</span><span class="n">Body</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Pop off the lexical block for the function.</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Error reading body, remove function.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">eraseFromParent</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">isBinaryOp</span><span class="p">())</span>
+ <span class="n">BinopPrecedence</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">Proto</span><span class="o">-></span><span class="n">getOperatorName</span><span class="p">());</span>
+
+ <span class="c1">// Pop off the lexical block for the function since we added it</span>
+ <span class="c1">// unconditionally.</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">LexicalBlocks</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Top-Level parsing and JIT Driver</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">InitializeModule</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Open a new module.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TheJIT</span><span class="o">-></span><span class="n">getTargetMachine</span><span class="p">().</span><span class="n">createDataLayout</span><span class="p">());</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error reading function definition:"</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ProtoAST</span> <span class="o">=</span> <span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ProtoAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error reading extern"</span><span class="p">);</span>
+ <span class="k">else</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">ProtoAST</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ProtoAST</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error generating code for top level expr"</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="n">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// "Library" functions that can be "extern'd" from user code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="cp">#ifdef _WIN32</span>
+<span class="cp">#define DLLEXPORT __declspec(dllexport)</span>
+<span class="cp">#else</span>
+<span class="cp">#define DLLEXPORT</span>
+<span class="cp">#endif</span>
+
+<span class="c1">/// putchard - putchar that takes a double and returns 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fputc</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// printd - printf that takes a double prints it as "%f\n", returning 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">printd</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Main driver code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">InitializeNativeTarget</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmPrinter</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmParser</span><span class="p">();</span>
+
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'='</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="n">TheJIT</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span><span class="p">();</span>
+
+ <span class="n">InitializeModule</span><span class="p">();</span>
+
+ <span class="c1">// Add the current debug info version into the module.</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">addModuleFlag</span><span class="p">(</span><span class="n">Module</span><span class="o">::</span><span class="n">Warning</span><span class="p">,</span> <span class="s">"Debug Info Version"</span><span class="p">,</span>
+ <span class="n">DEBUG_METADATA_VERSION</span><span class="p">);</span>
+
+ <span class="c1">// Darwin only supports dwarf2.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">Triple</span><span class="p">(</span><span class="n">sys</span><span class="o">::</span><span class="n">getProcessTriple</span><span class="p">()).</span><span class="n">isOSDarwin</span><span class="p">())</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">addModuleFlag</span><span class="p">(</span><span class="n">llvm</span><span class="o">::</span><span class="n">Module</span><span class="o">::</span><span class="n">Warning</span><span class="p">,</span> <span class="s">"Dwarf Version"</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
+
+ <span class="c1">// Construct the DIBuilder, we do this here because we need the module.</span>
+ <span class="n">DBuilder</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">DIBuilder</span><span class="o">></span><span class="p">(</span><span class="o">*</span><span class="n">TheModule</span><span class="p">);</span>
+
+ <span class="c1">// Create the compile unit for the module.</span>
+ <span class="c1">// Currently down as "fib.ks" as a filename since we're redirecting stdin</span>
+ <span class="c1">// but we'd like actual source locations.</span>
+ <span class="n">KSDbgInfo</span><span class="p">.</span><span class="n">TheCU</span> <span class="o">=</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createCompileUnit</span><span class="p">(</span>
+ <span class="n">dwarf</span><span class="o">::</span><span class="n">DW_LANG_C</span><span class="p">,</span> <span class="n">DBuilder</span><span class="o">-></span><span class="n">createFile</span><span class="p">(</span><span class="s">"fib.ks"</span><span class="p">,</span> <span class="s">"."</span><span class="p">),</span>
+ <span class="s">"Kaleidoscope Compiler"</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="c1">// Finalize the debug info.</span>
+ <span class="n">DBuilder</span><span class="o">-></span><span class="n">finalize</span><span class="p">();</span>
+
+ <span class="c1">// Print out all of the generated code.</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><a class="reference external" href="LangImpl10.html">Next: Conclusion and other useful LLVM tidbits</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="LangImpl10.html" title="10. Kaleidoscope: Conclusion and other useful LLVM tidbits"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl08.html" title="8. Kaleidoscope: Compiling to Object Code"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-08-05.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/LangImpl10.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/LangImpl10.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/LangImpl10.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/LangImpl10.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,333 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>10. Kaleidoscope: Conclusion and other useful LLVM tidbits — LLVM 8 documentation</title>
+ <link rel="stylesheet" href="../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../genindex.html" />
+ <link rel="search" title="Search" href="../search.html" />
+ <link rel="next" title="1. Kaleidoscope: Tutorial Introduction and the Lexer" href="OCamlLangImpl1.html" />
+ <link rel="prev" title="9. Kaleidoscope: Adding Debug Information" href="LangImpl09.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../index.html">
+ <img src="../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl1.html" title="1. Kaleidoscope: Tutorial Introduction and the Lexer"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl09.html" title="9. Kaleidoscope: Adding Debug Information"
+ accesskey="P">previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-conclusion-and-other-useful-llvm-tidbits">
+<h1>10. Kaleidoscope: Conclusion and other useful LLVM tidbits<a class="headerlink" href="#kaleidoscope-conclusion-and-other-useful-llvm-tidbits" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#tutorial-conclusion" id="id2">Tutorial Conclusion</a></li>
+<li><a class="reference internal" href="#properties-of-the-llvm-ir" id="id3">Properties of the LLVM IR</a><ul>
+<li><a class="reference internal" href="#target-independence" id="id4">Target Independence</a></li>
+<li><a class="reference internal" href="#safety-guarantees" id="id5">Safety Guarantees</a></li>
+<li><a class="reference internal" href="#language-specific-optimizations" id="id6">Language-Specific Optimizations</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#tips-and-tricks" id="id7">Tips and Tricks</a><ul>
+<li><a class="reference internal" href="#implementing-portable-offsetof-sizeof" id="id8">Implementing portable offsetof/sizeof</a></li>
+<li><a class="reference internal" href="#garbage-collected-stack-frames" id="id9">Garbage Collected Stack Frames</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="tutorial-conclusion">
+<h2><a class="toc-backref" href="#id2">10.1. Tutorial Conclusion</a><a class="headerlink" href="#tutorial-conclusion" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to the final chapter of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. In the course of this tutorial, we have
+grown our little Kaleidoscope language from being a useless toy, to
+being a semi-interesting (but probably still useless) toy. :)</p>
+<p>It is interesting to see how far weâve come, and how little code it has
+taken. We built the entire lexer, parser, AST, code generator, an
+interactive run-loop (with a JIT!), and emitted debug information in
+standalone executables - all in under 1000 lines of (non-comment/non-blank)
+code.</p>
+<p>Our little language supports a couple of interesting features: it
+supports user defined binary and unary operators, it uses JIT
+compilation for immediate evaluation, and it supports a few control flow
+constructs with SSA construction.</p>
+<p>Part of the idea of this tutorial was to show you how easy and fun it
+can be to define, build, and play with languages. Building a compiler
+need not be a scary or mystical process! Now that youâve seen some of
+the basics, I strongly encourage you to take the code and hack on it.
+For example, try adding:</p>
+<ul class="simple">
+<li><strong>global variables</strong> - While global variables have questional value
+in modern software engineering, they are often useful when putting
+together quick little hacks like the Kaleidoscope compiler itself.
+Fortunately, our current setup makes it very easy to add global
+variables: just have value lookup check to see if an unresolved
+variable is in the global variable symbol table before rejecting it.
+To create a new global variable, make an instance of the LLVM
+<code class="docutils literal notranslate"><span class="pre">GlobalVariable</span></code> class.</li>
+<li><strong>typed variables</strong> - Kaleidoscope currently only supports variables
+of type double. This gives the language a very nice elegance, because
+only supporting one type means that you never have to specify types.
+Different languages have different ways of handling this. The easiest
+way is to require the user to specify types for every variable
+definition, and record the type of the variable in the symbol table
+along with its Value*.</li>
+<li><strong>arrays, structs, vectors, etc</strong> - Once you add types, you can start
+extending the type system in all sorts of interesting ways. Simple
+arrays are very easy and are quite useful for many different
+applications. Adding them is mostly an exercise in learning how the
+LLVM <a class="reference external" href="../LangRef.html#getelementptr-instruction">getelementptr</a> instruction
+works: it is so nifty/unconventional, it <a class="reference external" href="../GetElementPtr.html">has its own
+FAQ</a>!</li>
+<li><strong>standard runtime</strong> - Our current language allows the user to access
+arbitrary external functions, and we use it for things like âprintdâ
+and âputchardâ. As you extend the language to add higher-level
+constructs, often these constructs make the most sense if they are
+lowered to calls into a language-supplied runtime. For example, if
+you add hash tables to the language, it would probably make sense to
+add the routines to a runtime, instead of inlining them all the way.</li>
+<li><strong>memory management</strong> - Currently we can only access the stack in
+Kaleidoscope. It would also be useful to be able to allocate heap
+memory, either with calls to the standard libc malloc/free interface
+or with a garbage collector. If you would like to use garbage
+collection, note that LLVM fully supports <a class="reference external" href="../GarbageCollection.html">Accurate Garbage
+Collection</a> including algorithms that
+move objects and need to scan/update the stack.</li>
+<li><strong>exception handling support</strong> - LLVM supports generation of <a class="reference external" href="../ExceptionHandling.html">zero
+cost exceptions</a> which interoperate with
+code compiled in other languages. You could also generate code by
+implicitly making every function return an error value and checking
+it. You could also make explicit use of setjmp/longjmp. There are
+many different ways to go here.</li>
+<li><strong>object orientation, generics, database access, complex numbers,
+geometric programming, â¦</strong> - Really, there is no end of crazy
+features that you can add to the language.</li>
+<li><strong>unusual domains</strong> - Weâve been talking about applying LLVM to a
+domain that many people are interested in: building a compiler for a
+specific language. However, there are many other domains that can use
+compiler technology that are not typically considered. For example,
+LLVM has been used to implement OpenGL graphics acceleration,
+translate C++ code to ActionScript, and many other cute and clever
+things. Maybe you will be the first to JIT compile a regular
+expression interpreter into native code with LLVM?</li>
+</ul>
+<p>Have fun - try doing something crazy and unusual. Building a language
+like everyone else always has, is much less fun than trying something a
+little crazy or off the wall and seeing how it turns out. If you get
+stuck or want to talk about it, feel free to email the <a class="reference external" href="http://lists.llvm.org/mailman/listinfo/llvm-dev">llvm-dev mailing
+list</a>: it has lots
+of people who are interested in languages and are often willing to help
+out.</p>
+<p>Before we end this tutorial, I want to talk about some âtips and tricksâ
+for generating LLVM IR. These are some of the more subtle things that
+may not be obvious, but are very useful if you want to take advantage of
+LLVMâs capabilities.</p>
+</div>
+<div class="section" id="properties-of-the-llvm-ir">
+<h2><a class="toc-backref" href="#id3">10.2. Properties of the LLVM IR</a><a class="headerlink" href="#properties-of-the-llvm-ir" title="Permalink to this headline">¶</a></h2>
+<p>We have a couple of common questions about code in the LLVM IR form -
+letâs just get these out of the way right now, shall we?</p>
+<div class="section" id="target-independence">
+<h3><a class="toc-backref" href="#id4">10.2.1. Target Independence</a><a class="headerlink" href="#target-independence" title="Permalink to this headline">¶</a></h3>
+<p>Kaleidoscope is an example of a âportable languageâ: any program written
+in Kaleidoscope will work the same way on any target that it runs on.
+Many other languages have this property, e.g. lisp, java, haskell,
+javascript, python, etc (note that while these languages are portable,
+not all their libraries are).</p>
+<p>One nice aspect of LLVM is that it is often capable of preserving target
+independence in the IR: you can take the LLVM IR for a
+Kaleidoscope-compiled program and run it on any target that LLVM
+supports, even emitting C code and compiling that on targets that LLVM
+doesnât support natively. You can trivially tell that the Kaleidoscope
+compiler generates target-independent code because it never queries for
+any target-specific information when generating code.</p>
+<p>The fact that LLVM provides a compact, target-independent,
+representation for code gets a lot of people excited. Unfortunately,
+these people are usually thinking about C or a language from the C
+family when they are asking questions about language portability. I say
+âunfortunatelyâ, because there is really no way to make (fully general)
+C code portable, other than shipping the source code around (and of
+course, C source code is not actually portable in general either - ever
+port a really old application from 32- to 64-bits?).</p>
+<p>The problem with C (again, in its full generality) is that it is heavily
+laden with target specific assumptions. As one simple example, the
+preprocessor often destructively removes target-independence from the
+code when it processes the input text:</p>
+<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef __i386__</span>
+ <span class="kt">int</span> <span class="n">X</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
+<span class="cp">#else</span>
+ <span class="kt">int</span> <span class="n">X</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
+<span class="cp">#endif</span>
+</pre></div>
+</div>
+<p>While it is possible to engineer more and more complex solutions to
+problems like this, it cannot be solved in full generality in a way that
+is better than shipping the actual source code.</p>
+<p>That said, there are interesting subsets of C that can be made portable.
+If you are willing to fix primitive types to a fixed size (say int =
+32-bits, and long = 64-bits), donât care about ABI compatibility with
+existing binaries, and are willing to give up some other minor features,
+you can have portable code. This can make sense for specialized domains
+such as an in-kernel language.</p>
+</div>
+<div class="section" id="safety-guarantees">
+<h3><a class="toc-backref" href="#id5">10.2.2. Safety Guarantees</a><a class="headerlink" href="#safety-guarantees" title="Permalink to this headline">¶</a></h3>
+<p>Many of the languages above are also âsafeâ languages: it is impossible
+for a program written in Java to corrupt its address space and crash the
+process (assuming the JVM has no bugs). Safety is an interesting
+property that requires a combination of language design, runtime
+support, and often operating system support.</p>
+<p>It is certainly possible to implement a safe language in LLVM, but LLVM
+IR does not itself guarantee safety. The LLVM IR allows unsafe pointer
+casts, use after free bugs, buffer over-runs, and a variety of other
+problems. Safety needs to be implemented as a layer on top of LLVM and,
+conveniently, several groups have investigated this. Ask on the <a class="reference external" href="http://lists.llvm.org/mailman/listinfo/llvm-dev">llvm-dev
+mailing list</a> if
+you are interested in more details.</p>
+</div>
+<div class="section" id="language-specific-optimizations">
+<h3><a class="toc-backref" href="#id6">10.2.3. Language-Specific Optimizations</a><a class="headerlink" href="#language-specific-optimizations" title="Permalink to this headline">¶</a></h3>
+<p>One thing about LLVM that turns off many people is that it does not
+solve all the worldâs problems in one system (sorry âworld hungerâ,
+someone else will have to solve you some other day). One specific
+complaint is that people perceive LLVM as being incapable of performing
+high-level language-specific optimization: LLVM âloses too much
+informationâ.</p>
+<p>Unfortunately, this is really not the place to give you a full and
+unified version of âChris Lattnerâs theory of compiler designâ. Instead,
+Iâll make a few observations:</p>
+<p>First, youâre right that LLVM does lose information. For example, as of
+this writing, there is no way to distinguish in the LLVM IR whether an
+SSA-value came from a C âintâ or a C âlongâ on an ILP32 machine (other
+than debug info). Both get compiled down to an âi32â value and the
+information about what it came from is lost. The more general issue
+here, is that the LLVM type system uses âstructural equivalenceâ instead
+of âname equivalenceâ. Another place this surprises people is if you
+have two types in a high-level language that have the same structure
+(e.g. two different structs that have a single int field): these types
+will compile down into a single LLVM type and it will be impossible to
+tell what it came from.</p>
+<p>Second, while LLVM does lose information, LLVM is not a fixed target: we
+continue to enhance and improve it in many different ways. In addition
+to adding new features (LLVM did not always support exceptions or debug
+info), we also extend the IR to capture important information for
+optimization (e.g. whether an argument is sign or zero extended,
+information about pointers aliasing, etc). Many of the enhancements are
+user-driven: people want LLVM to include some specific feature, so they
+go ahead and extend it.</p>
+<p>Third, it is <em>possible and easy</em> to add language-specific optimizations,
+and you have a number of choices in how to do it. As one trivial
+example, it is easy to add language-specific optimization passes that
+âknowâ things about code compiled for a language. In the case of the C
+family, there is an optimization pass that âknowsâ about the standard C
+library functions. If you call âexit(0)â in main(), it knows that it is
+safe to optimize that into âreturn 0;â because C specifies what the
+âexitâ function does.</p>
+<p>In addition to simple library knowledge, it is possible to embed a
+variety of other language-specific information into the LLVM IR. If you
+have a specific need and run into a wall, please bring the topic up on
+the llvm-dev list. At the very worst, you can always treat LLVM as if it
+were a âdumb code generatorâ and implement the high-level optimizations
+you desire in your front-end, on the language-specific AST.</p>
+</div>
+</div>
+<div class="section" id="tips-and-tricks">
+<h2><a class="toc-backref" href="#id7">10.3. Tips and Tricks</a><a class="headerlink" href="#tips-and-tricks" title="Permalink to this headline">¶</a></h2>
+<p>There is a variety of useful tips and tricks that you come to know after
+working on/with LLVM that arenât obvious at first glance. Instead of
+letting everyone rediscover them, this section talks about some of these
+issues.</p>
+<div class="section" id="implementing-portable-offsetof-sizeof">
+<h3><a class="toc-backref" href="#id8">10.3.1. Implementing portable offsetof/sizeof</a><a class="headerlink" href="#implementing-portable-offsetof-sizeof" title="Permalink to this headline">¶</a></h3>
+<p>One interesting thing that comes up, if you are trying to keep the code
+generated by your compiler âtarget independentâ, is that you often need
+to know the size of some LLVM type or the offset of some field in an
+llvm structure. For example, you might need to pass the size of a type
+into a function that allocates memory.</p>
+<p>Unfortunately, this can vary widely across targets: for example the
+width of a pointer is trivially target-specific. However, there is a
+<a class="reference external" href="http://nondot.org/sabre/LLVMNotes/SizeOf-OffsetOf-VariableSizedStructs.txt">clever way to use the getelementptr
+instruction</a>
+that allows you to compute this in a portable way.</p>
+</div>
+<div class="section" id="garbage-collected-stack-frames">
+<h3><a class="toc-backref" href="#id9">10.3.2. Garbage Collected Stack Frames</a><a class="headerlink" href="#garbage-collected-stack-frames" title="Permalink to this headline">¶</a></h3>
+<p>Some languages want to explicitly manage their stack frames, often so
+that they are garbage collected or to allow easy implementation of
+closures. There are often better ways to implement these features than
+explicit stack frames, but <a class="reference external" href="http://nondot.org/sabre/LLVMNotes/ExplicitlyManagedStackFrames.txt">LLVM does support
+them,</a>
+if you want. It requires your front-end to convert the code into
+<a class="reference external" href="http://en.wikipedia.org/wiki/Continuation-passing_style">Continuation Passing
+Style</a> and
+the use of tail calls (which LLVM also supports).</p>
+</div>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="OCamlLangImpl1.html" title="1. Kaleidoscope: Tutorial Introduction and the Lexer"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="LangImpl09.html" title="9. Kaleidoscope: Adding Debug Information"
+ >previous</a> |</li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../index.html">Documentation</a>»</li>
+
+ <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> »</li>
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-08-05.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl01.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,244 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Kaleidoscope: Kaleidoscope Introduction and the Lexer — LLVM 9 documentation</title>
+ <link rel="stylesheet" href="../../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../../index.html">
+ <img src="../../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-kaleidoscope-introduction-and-the-lexer">
+<h1>Kaleidoscope: Kaleidoscope Introduction and the Lexer<a class="headerlink" href="#kaleidoscope-kaleidoscope-introduction-and-the-lexer" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#the-kaleidoscope-language" id="id1">The Kaleidoscope Language</a></li>
+<li><a class="reference internal" href="#the-lexer" id="id2">The Lexer</a></li>
+</ul>
+</div>
+<div class="section" id="the-kaleidoscope-language">
+<h2><a class="toc-backref" href="#id1">The Kaleidoscope Language</a><a class="headerlink" href="#the-kaleidoscope-language" title="Permalink to this headline">¶</a></h2>
+<p>This tutorial is illustrated with a toy language called
+â<a class="reference external" href="http://en.wikipedia.org/wiki/Kaleidoscope">Kaleidoscope</a>â (derived
+from âmeaning beautiful, form, and viewâ). Kaleidoscope is a procedural
+language that allows you to define functions, use conditionals, math,
+etc. Over the course of the tutorial, weâll extend Kaleidoscope to
+support the if/then/else construct, a for loop, user defined operators,
+JIT compilation with a simple command line interface, debug info, etc.</p>
+<p>We want to keep things simple, so the only datatype in Kaleidoscope
+is a 64-bit floating point type (aka âdoubleâ in C parlance). As such,
+all values are implicitly double precision and the language doesnât
+require type declarations. This gives the language a very nice and
+simple syntax. For example, the following simple example computes
+<a class="reference external" href="http://en.wikipedia.org/wiki/Fibonacci_number">Fibonacci numbers:</a></p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compute the x'th fibonacci number.</span>
+<span class="k">def</span> <span class="nf">fib</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">x</span> <span class="o"><</span> <span class="mi">3</span> <span class="n">then</span>
+ <span class="mi">1</span>
+ <span class="k">else</span>
+ <span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="o">+</span><span class="n">fib</span><span class="p">(</span><span class="n">x</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
+
+<span class="c1"># This expression will compute the 40th number.</span>
+<span class="n">fib</span><span class="p">(</span><span class="mi">40</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>We also allow Kaleidoscope to call into standard library functions - the
+LLVM JIT makes this really easy. This means that you can use the
+âexternâ keyword to define a function before you use it (this is also
+useful for mutually recursive functions). For example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">extern</span> <span class="n">sin</span><span class="p">(</span><span class="n">arg</span><span class="p">);</span>
+<span class="n">extern</span> <span class="n">cos</span><span class="p">(</span><span class="n">arg</span><span class="p">);</span>
+<span class="n">extern</span> <span class="n">atan2</span><span class="p">(</span><span class="n">arg1</span> <span class="n">arg2</span><span class="p">);</span>
+
+<span class="n">atan2</span><span class="p">(</span><span class="n">sin</span><span class="p">(</span><span class="o">.</span><span class="mi">4</span><span class="p">),</span> <span class="n">cos</span><span class="p">(</span><span class="mi">42</span><span class="p">))</span>
+</pre></div>
+</div>
+<p>A more interesting example is included in Chapter 6 where we write a
+little Kaleidoscope application that <a class="reference external" href="LangImpl06.html#kicking-the-tires">displays a Mandelbrot
+Set</a> at various levels of magnification.</p>
+<p>Letâs dive into the implementation of this language!</p>
+</div>
+<div class="section" id="the-lexer">
+<h2><a class="toc-backref" href="#id2">The Lexer</a><a class="headerlink" href="#the-lexer" title="Permalink to this headline">¶</a></h2>
+<p>When it comes to implementing a language, the first thing needed is the
+ability to process a text file and recognize what it says. The
+traditional way to do this is to use a
+â<a class="reference external" href="http://en.wikipedia.org/wiki/Lexical_analysis">lexer</a>â (aka
+âscannerâ) to break the input up into âtokensâ. Each token returned by
+the lexer includes a token code and potentially some metadata (e.g. the
+numeric value of a number). First, we define the possibilities:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span><span class="p">,</span>
+<span class="p">};</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+</pre></div>
+</div>
+<p>Each token returned by our lexer will either be one of the Token enum
+values or it will be an âunknownâ character like â+â, which is returned
+as its ASCII value. If the current token is an identifier, the
+<code class="docutils literal notranslate"><span class="pre">IdentifierStr</span></code> global variable holds the name of the identifier. If
+the current token is a numeric literal (like 1.0), <code class="docutils literal notranslate"><span class="pre">NumVal</span></code> holds its
+value. We use global variables for simplicity, but this is not the
+best choice for a real language implementation :).</p>
+<p>The actual implementation of the lexer is a single function named
+<code class="docutils literal notranslate"><span class="pre">gettok</span></code>. The <code class="docutils literal notranslate"><span class="pre">gettok</span></code> function is called to return the next token
+from standard input. Its definition starts as:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+</pre></div>
+</div>
+<p><code class="docutils literal notranslate"><span class="pre">gettok</span></code> works by calling the C <code class="docutils literal notranslate"><span class="pre">getchar()</span></code> function to read
+characters one at a time from standard input. It eats them as it
+recognizes them and stores the last character read, but not processed,
+in LastChar. The first thing that it has to do is ignore whitespace
+between tokens. This is accomplished with the loop above.</p>
+<p>The next thing <code class="docutils literal notranslate"><span class="pre">gettok</span></code> needs to do is recognize identifiers and
+specific keywords like âdefâ. Kaleidoscope does this with this simple
+loop:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Note that this code sets the â<code class="docutils literal notranslate"><span class="pre">IdentifierStr</span></code>â global whenever it
+lexes an identifier. Also, since language keywords are matched by the
+same loop, we handle them here inline. Numeric values are similar:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="mi">0</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This is all pretty straightforward code for processing input. When
+reading a numeric value from input, we use the C <code class="docutils literal notranslate"><span class="pre">strtod</span></code> function to
+convert it to a numeric value that we store in <code class="docutils literal notranslate"><span class="pre">NumVal</span></code>. Note that
+this isnât doing sufficient error checking: it will incorrectly read
+â1.23.45.67â and handle it as if you typed in â1.23â. Feel free to
+extend it! Next we handle comments:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>We handle comments by skipping to the end of the line and then return
+the next token. Finally, if the input doesnât match one of the above
+cases, it is either an operator character like â+â or the end of the
+file. These are handled with this code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span> <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>With this, we have the complete lexer for the basic Kaleidoscope
+language (the <a class="reference external" href="LangImpl02.html#full-code-listing">full code listing</a> for the Lexer
+is available in the <a class="reference external" href="LangImpl02.html">next chapter</a> of the tutorial).
+Next weâll <a class="reference external" href="LangImpl02.html">build a simple parser that uses this to build an Abstract
+Syntax Tree</a>. When we have that, weâll include a
+driver so that you can use the lexer and parser together.</p>
+<p><a class="reference external" href="LangImpl02.html">Next: Implementing a Parser and AST</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ >index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-07-10.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl02.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,1185 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Kaleidoscope: Implementing a Parser and AST — LLVM 9 documentation</title>
+ <link rel="stylesheet" href="../../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../../index.html">
+ <img src="../../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-implementing-a-parser-and-ast">
+<h1>Kaleidoscope: Implementing a Parser and AST<a class="headerlink" href="#kaleidoscope-implementing-a-parser-and-ast" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-2-introduction" id="id2">Chapter 2 Introduction</a></li>
+<li><a class="reference internal" href="#the-abstract-syntax-tree-ast" id="id3">The Abstract Syntax Tree (AST)</a></li>
+<li><a class="reference internal" href="#parser-basics" id="id4">Parser Basics</a></li>
+<li><a class="reference internal" href="#basic-expression-parsing" id="id5">Basic Expression Parsing</a></li>
+<li><a class="reference internal" href="#binary-expression-parsing" id="id6">Binary Expression Parsing</a></li>
+<li><a class="reference internal" href="#parsing-the-rest" id="id7">Parsing the Rest</a></li>
+<li><a class="reference internal" href="#the-driver" id="id8">The Driver</a></li>
+<li><a class="reference internal" href="#conclusions" id="id9">Conclusions</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id10">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-2-introduction">
+<h2><a class="toc-backref" href="#id2">Chapter 2 Introduction</a><a class="headerlink" href="#chapter-2-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 2 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. This chapter shows you how to use the
+lexer, built in <a class="reference external" href="LangImpl01.html">Chapter 1</a>, to build a full
+<a class="reference external" href="http://en.wikipedia.org/wiki/Parsing">parser</a> for our Kaleidoscope
+language. Once we have a parser, weâll define and build an <a class="reference external" href="http://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract
+Syntax Tree</a> (AST).</p>
+<p>The parser we will build uses a combination of <a class="reference external" href="http://en.wikipedia.org/wiki/Recursive_descent_parser">Recursive Descent
+Parsing</a> and
+<a class="reference external" href="http://en.wikipedia.org/wiki/Operator-precedence_parser">Operator-Precedence
+Parsing</a> to
+parse the Kaleidoscope language (the latter for binary expressions and
+the former for everything else). Before we get to parsing though, letâs
+talk about the output of the parser: the Abstract Syntax Tree.</p>
+</div>
+<div class="section" id="the-abstract-syntax-tree-ast">
+<h2><a class="toc-backref" href="#id3">The Abstract Syntax Tree (AST)</a><a class="headerlink" href="#the-abstract-syntax-tree-ast" title="Permalink to this headline">¶</a></h2>
+<p>The AST for a program captures its behavior in such a way that it is
+easy for later stages of the compiler (e.g. code generation) to
+interpret. We basically want one object for each construct in the
+language, and the AST should closely model the language. In
+Kaleidoscope, we have expressions, a prototype, and a function object.
+Weâll start with expressions first:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+<span class="p">};</span>
+</pre></div>
+</div>
+<p>The code above shows the definition of the base ExprAST class and one
+subclass which we use for numeric literals. The important thing to note
+about this code is that the NumberExprAST class captures the numeric
+value of the literal as an instance variable. This allows later phases
+of the compiler to know what the stored numeric value is.</p>
+<p>Right now we only create the AST, so there are no useful accessor
+methods on them. It would be very easy to add a virtual method to pretty
+print the code, for example. Here are the other expression AST node
+definitions that weâll use in the basic form of the Kaleidoscope
+language:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span> <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Op</span><span class="p">(</span><span class="n">op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+</pre></div>
+</div>
+<p>This is all (intentionally) rather straight-forward: variables capture
+the variable name, binary operators capture their opcode (e.g. â+â), and
+calls capture a function name as well as a list of any argument
+expressions. One thing that is nice about our AST is that it captures
+the language features without talking about the syntax of the language.
+Note that there is no discussion about precedence of binary operators,
+lexical structure, etc.</p>
+<p>For our basic language, these are all of the expression nodes weâll
+define. Because it doesnât have conditional control flow, it isnât
+Turing-complete; weâll fix that in a later installment. The two things
+we need next are a way to talk about the interface to a function, and a
+way to talk about functions themselves:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes).</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+</pre></div>
+</div>
+<p>In Kaleidoscope, functions are typed with just a count of their
+arguments. Since all values are double precision floating point, the
+type of each argument doesnât need to be stored anywhere. In a more
+aggressive and realistic language, the âExprASTâ class would probably
+have a type field.</p>
+<p>With this scaffolding, we can now talk about parsing expressions and
+function bodies in Kaleidoscope.</p>
+</div>
+<div class="section" id="parser-basics">
+<h2><a class="toc-backref" href="#id4">Parser Basics</a><a class="headerlink" href="#parser-basics" title="Permalink to this headline">¶</a></h2>
+<p>Now that we have an AST to build, we need to define the parser code to
+build it. The idea here is that we want to parse something like âx+yâ
+(which is returned as three tokens by the lexer) into an AST that could
+be generated with calls like this:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="s">"x"</span><span class="p">);</span>
+<span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="s">"y"</span><span class="p">);</span>
+<span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="sc">'+'</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+</pre></div>
+</div>
+<p>In order to do this, weâll start by defining some basic helper routines:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This implements a simple token buffer around the lexer. This allows us
+to look one token ahead at what the lexer is returning. Every function
+in our parser will assume that CurTok is the current token that needs to
+be parsed.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"LogError: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>The <code class="docutils literal notranslate"><span class="pre">LogError</span></code> routines are simple helper routines that our parser will
+use to handle errors. The error recovery in our parser will not be the
+best and is not particular user-friendly, but it will be enough for our
+tutorial. These routines make it easier to handle errors in routines
+that have various return types: they always return null.</p>
+<p>With these basic helper functions, we can implement the first piece of
+our grammar: numeric literals.</p>
+</div>
+<div class="section" id="basic-expression-parsing">
+<h2><a class="toc-backref" href="#id5">Basic Expression Parsing</a><a class="headerlink" href="#basic-expression-parsing" title="Permalink to this headline">¶</a></h2>
+<p>We start with numeric literals, because they are the simplest to
+process. For each production in our grammar, weâll define a function
+which parses that production. For numeric literals, we have:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This routine is very simple: it expects to be called when the current
+token is a <code class="docutils literal notranslate"><span class="pre">tok_number</span></code> token. It takes the current number value,
+creates a <code class="docutils literal notranslate"><span class="pre">NumberExprAST</span></code> node, advances the lexer to the next token,
+and finally returns.</p>
+<p>There are some interesting aspects to this. The most important one is
+that this routine eats all of the tokens that correspond to the
+production and returns the lexer buffer with the next token (which is
+not part of the grammar production) ready to go. This is a fairly
+standard way to go for recursive descent parsers. For a better example,
+the parenthesis operator is defined like this:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This function illustrates a number of interesting things about the
+parser:</p>
+<p>1) It shows how we use the LogError routines. When called, this function
+expects that the current token is a â(â token, but after parsing the
+subexpression, it is possible that there is no â)â waiting. For example,
+if the user types in â(4 xâ instead of â(4)â, the parser should emit an
+error. Because errors can occur, the parser needs a way to indicate that
+they happened: in our parser, we return null on an error.</p>
+<p>2) Another interesting aspect of this function is that it uses recursion
+by calling <code class="docutils literal notranslate"><span class="pre">ParseExpression</span></code> (we will soon see that
+<code class="docutils literal notranslate"><span class="pre">ParseExpression</span></code> can call <code class="docutils literal notranslate"><span class="pre">ParseParenExpr</span></code>). This is powerful
+because it allows us to handle recursive grammars, and keeps each
+production very simple. Note that parentheses do not cause construction
+of AST nodes themselves. While we could do it this way, the most
+important role of parentheses are to guide the parser and provide
+grouping. Once the parser constructs the AST, parentheses are not
+needed.</p>
+<p>The next simple production is for handling variable references and
+function calls:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This routine follows the same style as the other routines. (It expects
+to be called if the current token is a <code class="docutils literal notranslate"><span class="pre">tok_identifier</span></code> token). It
+also has recursion and error handling. One interesting aspect of this is
+that it uses <em>look-ahead</em> to determine if the current identifier is a
+stand alone variable reference or if it is a function call expression.
+It handles this by checking to see if the token after the identifier is
+a â(â token, constructing either a <code class="docutils literal notranslate"><span class="pre">VariableExprAST</span></code> or
+<code class="docutils literal notranslate"><span class="pre">CallExprAST</span></code> node as appropriate.</p>
+<p>Now that we have all of our simple expression-parsing logic in place, we
+can define a helper function to wrap it together into one entry point.
+We call this class of expressions âprimaryâ expressions, for reasons
+that will become more clear <a class="reference external" href="LangImpl6.html#user-defined-unary-operators">later in the
+tutorial</a>. In order to parse an arbitrary
+primary expression, we need to determine what sort of expression it is:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Now that you see the definition of this function, it is more obvious why
+we can assume the state of CurTok in the various functions. This uses
+look-ahead to determine which sort of expression is being inspected, and
+then parses it with a function call.</p>
+<p>Now that basic expressions are handled, we need to handle binary
+expressions. They are a bit more complex.</p>
+</div>
+<div class="section" id="binary-expression-parsing">
+<h2><a class="toc-backref" href="#id6">Binary Expression Parsing</a><a class="headerlink" href="#binary-expression-parsing" title="Permalink to this headline">¶</a></h2>
+<p>Binary expressions are significantly harder to parse because they are
+often ambiguous. For example, when given the string âx+y*zâ, the parser
+can choose to parse it as either â(x+y)*zâ or âx+(y*z)â. With common
+definitions from mathematics, we expect the later parse, because â*â
+(multiplication) has higher <em>precedence</em> than â+â (addition).</p>
+<p>There are many ways to handle this, but an elegant and efficient way is
+to use <a class="reference external" href="http://en.wikipedia.org/wiki/Operator-precedence_parser">Operator-Precedence
+Parsing</a>.
+This parsing technique uses the precedence of binary operators to guide
+recursion. To start with, we need a table of precedences:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+ <span class="p">...</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>For the basic form of Kaleidoscope, we will only support 4 binary
+operators (this can obviously be extended by you, our brave and intrepid
+reader). The <code class="docutils literal notranslate"><span class="pre">GetTokPrecedence</span></code> function returns the precedence for
+the current token, or -1 if the token is not a binary operator. Having a
+map makes it easy to add new operators and makes it clear that the
+algorithm doesnât depend on the specific operators involved, but it
+would be easy enough to eliminate the map and do the comparisons in the
+<code class="docutils literal notranslate"><span class="pre">GetTokPrecedence</span></code> function. (Or just use a fixed-size array).</p>
+<p>With the helper above defined, we can now start parsing binary
+expressions. The basic idea of operator precedence parsing is to break
+down an expression with potentially ambiguous binary operators into
+pieces. Consider, for example, the expression âa+b+(c+d)*e*f+gâ.
+Operator precedence parsing considers this as a stream of primary
+expressions separated by binary operators. As such, it will first parse
+the leading primary expression âaâ, then it will see the pairs [+, b]
+[+, (c+d)] [*, e] [*, f] and [+, g]. Note that because parentheses are
+primary expressions, the binary expression parser doesnât need to worry
+about nested subexpressions like (c+d) at all.</p>
+<p>To start, an expression is a primary expression potentially followed by
+a sequence of [binop,primaryexpr] pairs:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// expression</span>
+<span class="c1">/// ::= primary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code> is the function that parses the sequence of pairs for
+us. It takes a precedence and a pointer to an expression for the part
+that has been parsed so far. Note that âxâ is a perfectly valid
+expression: As such, âbinoprhsâ is allowed to be empty, in which case it
+returns the expression that is passed into it. In our example above, the
+code passes the expression for âaâ into <code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code> and the
+current token is â+â.</p>
+<p>The precedence value passed into <code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code> indicates the
+<em>minimal operator precedence</em> that the function is allowed to eat. For
+example, if the current pair stream is [+, x] and <code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code> is
+passed in a precedence of 40, it will not consume any tokens (because
+the precedence of â+â is only 20). With this in mind, <code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code>
+starts with:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' primary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>This code gets the precedence of the current token and checks to see if
+if is too low. Because we defined invalid tokens to have a precedence of
+-1, this check implicitly knows that the pair-stream ends when the token
+stream runs out of binary operators. If this check succeeds, we know
+that the token is a binary operator and that it will be included in this
+expression:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Okay, we know this is a binop.</span>
+<span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+<span class="c1">// Parse the primary expression after the binary operator.</span>
+<span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>As such, this code eats (and remembers) the binary operator and then
+parses the primary expression that follows. This builds up the whole
+pair, the first of which is [+, b] for the running example.</p>
+<p>Now that we parsed the left-hand side of an expression and one pair of
+the RHS sequence, we have to decide which way the expression associates.
+In particular, we could have â(a+b) binop unparsedâ or âa + (b binop
+unparsed)â. To determine this, we look ahead at âbinopâ to determine its
+precedence and compare it to BinOpâs precedence (which is â+â in this
+case):</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+<span class="c1">// the pending operator take RHS as its LHS.</span>
+<span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+<span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+</pre></div>
+</div>
+<p>If the precedence of the binop to the right of âRHSâ is lower or equal
+to the precedence of our current operator, then we know that the
+parentheses associate as â(a+b) binop â¦â. In our example, the current
+operator is â+â and the next operator is â+â, we know that they have the
+same precedence. In this case weâll create the AST node for âa+bâ, and
+then continue parsing:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span> <span class="p">...</span> <span class="k">if</span> <span class="n">body</span> <span class="n">omitted</span> <span class="p">...</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span> <span class="c1">// loop around to the top of the while loop.</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In our example above, this will turn âa+b+â into â(a+b)â and execute the
+next iteration of the loop, with â+â as the current token. The code
+above will eat, remember, and parse â(c+d)â as the primary expression,
+which makes the current pair equal to [+, (c+d)]. It will then evaluate
+the âifâ conditional above with â*â as the binop to the right of the
+primary. In this case, the precedence of â*â is higher than the
+precedence of â+â so the if condition will be entered.</p>
+<p>The critical question left here is âhow can the if condition parse the
+right hand side in fullâ? In particular, to build the AST correctly for
+our example, it needs to get all of â(c+d)*e*fâ as the RHS expression
+variable. The code to do this is surprisingly simple (code from the
+above two blocks duplicated for context):</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span> <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span> <span class="c1">// loop around to the top of the while loop.</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>At this point, we know that the binary operator to the RHS of our
+primary has higher precedence than the binop we are currently parsing.
+As such, we know that any sequence of pairs whose operators are all
+higher precedence than â+â should be parsed together and returned as
+âRHSâ. To do this, we recursively invoke the <code class="docutils literal notranslate"><span class="pre">ParseBinOpRHS</span></code> function
+specifying âTokPrec+1â as the minimum precedence required for it to
+continue. In our example above, this will cause it to return the AST
+node for â(c+d)*e*fâ as RHS, which is then set as the RHS of the â+â
+expression.</p>
+<p>Finally, on the next iteration of the while loop, the â+gâ piece is
+parsed and added to the AST. With this little bit of code (14
+non-trivial lines), we correctly handle fully general binary expression
+parsing in a very elegant way. This was a whirlwind tour of this code,
+and it is somewhat subtle. I recommend running through it with a few
+tough examples to see how it works.</p>
+<p>This wraps up handling of expressions. At this point, we can point the
+parser at an arbitrary token stream and build an expression from it,
+stopping at the first token that is not part of the expression. Next up
+we need to handle function definitions, etc.</p>
+</div>
+<div class="section" id="parsing-the-rest">
+<h2><a class="toc-backref" href="#id7">Parsing the Rest</a><a class="headerlink" href="#parsing-the-rest" title="Permalink to this headline">¶</a></h2>
+<p>The next thing missing is handling of function prototypes. In
+Kaleidoscope, these are used both for âexternâ function declarations as
+well as function body definitions. The code to do this is
+straight-forward and not very interesting (once youâve survived
+expressions):</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// Read the list of argument names.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ArgNames</span><span class="p">));</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Given this, a function definition is very simple, just a prototype plus
+an expression to implement the body:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span> <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In addition, we support âexternâ to declare functions like âsinâ and
+âcosâ as well as to support forward declaration of user functions. These
+âexternâs are just prototypes with no body:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Finally, weâll also let the user type in arbitrary top-level expressions
+and evaluate them on the fly. We will handle this by defining anonymous
+nullary (zero argument) functions for them:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="s">""</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Now that we have all the pieces, letâs build a little driver that will
+let us actually <em>execute</em> this code weâve built!</p>
+</div>
+<div class="section" id="the-driver">
+<h2><a class="toc-backref" href="#id8">The Driver</a><a class="headerlink" href="#the-driver" title="Permalink to this headline">¶</a></h2>
+<p>The driver for this simply invokes all of the parsing pieces with a
+top-level dispatch loop. There isnât much interesting here, so Iâll just
+include the top-level loop. See <a class="reference external" href="#full-code-listing">below</a> for full code in the
+âTop-Level Parsingâ section.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="nf">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>The most interesting part of this is that we ignore top-level
+semicolons. Why is this, you ask? The basic reason is that if you type
+â4 + 5â at the command line, the parser doesnât know whether that is the
+end of what you will type or not. For example, on the next line you
+could type âdef fooâ¦â in which case 4+5 is the end of a top-level
+expression. Alternatively you could type â* 6â, which would continue
+the expression. Having top-level semicolons allows you to type â4+5;â,
+and the parser will know you are done.</p>
+</div>
+<div class="section" id="conclusions">
+<h2><a class="toc-backref" href="#id9">Conclusions</a><a class="headerlink" href="#conclusions" title="Permalink to this headline">¶</a></h2>
+<p>With just under 400 lines of commented code (240 lines of non-comment,
+non-blank code), we fully defined our minimal language, including a
+lexer, parser, and AST builder. With this done, the executable will
+validate Kaleidoscope code and tell us if it is grammatically invalid.
+For example, here is a sample interaction:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$ ./a.out
+ready> def foo<span class="o">(</span>x y<span class="o">)</span> x+foo<span class="o">(</span>y, <span class="m">4</span>.0<span class="o">)</span><span class="p">;</span>
+Parsed a <span class="k">function</span> definition.
+ready> def foo<span class="o">(</span>x y<span class="o">)</span> x+y y<span class="p">;</span>
+Parsed a <span class="k">function</span> definition.
+Parsed a top-level expr
+ready> def foo<span class="o">(</span>x y<span class="o">)</span> x+y <span class="o">)</span><span class="p">;</span>
+Parsed a <span class="k">function</span> definition.
+Error: unknown token when expecting an expression
+ready> extern sin<span class="o">(</span>a<span class="o">)</span><span class="p">;</span>
+ready> Parsed an extern
+ready> ^D
+$
+</pre></div>
+</div>
+<p>There is a lot of room for extension here. You can define new AST nodes,
+extend the language in many ways, etc. In the <a class="reference external" href="LangImpl03.html">next
+installment</a>, we will describe how to generate LLVM
+Intermediate Representation (IR) from the AST.</p>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id10">Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example. Because this
+uses the LLVM libraries, we need to link them in. To do this, we use the
+<a class="reference external" href="http://llvm.org/cmds/llvm-config.html">llvm-config</a> tool to inform
+our makefile/command line about which options to use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+clang++ -g -O3 toy.cpp <span class="sb">`</span>llvm-config --cxxflags<span class="sb">`</span>
+<span class="c1"># Run</span>
+./a.out
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">"llvm/ADT/STLExtras.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><algorithm></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cctype></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdio></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdlib></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><map></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><memory></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Lexer</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span>
+<span class="p">};</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+
+<span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">namespace</span> <span class="p">{</span>
+
+<span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span> <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Op</span><span class="p">(</span><span class="n">Op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes).</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+<span class="p">};</span>
+
+<span class="p">}</span> <span class="c1">// end anonymous namespace</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Parser</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span> <span class="p">}</span>
+
+<span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">();</span>
+
+<span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' primary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+
+ <span class="c1">// Okay, we know this is a binop.</span>
+ <span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+ <span class="c1">// Parse the primary expression after the binary operator.</span>
+ <span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// expression</span>
+<span class="c1">/// ::= primary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ArgNames</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Top-Level parsing</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Parsed a function definition.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Parsed an extern</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Parsed a top-level expr</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="n">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Main driver code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><a class="reference external" href="LangImpl03.html">Next: Implementing Code Generation to LLVM IR</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ >index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-07-10.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl03.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,1187 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Kaleidoscope: Code generation to LLVM IR — LLVM 9 documentation</title>
+ <link rel="stylesheet" href="../../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../../index.html">
+ <img src="../../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-code-generation-to-llvm-ir">
+<h1>Kaleidoscope: Code generation to LLVM IR<a class="headerlink" href="#kaleidoscope-code-generation-to-llvm-ir" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-3-introduction" id="id1">Chapter 3 Introduction</a></li>
+<li><a class="reference internal" href="#code-generation-setup" id="id2">Code Generation Setup</a></li>
+<li><a class="reference internal" href="#expression-code-generation" id="id3">Expression Code Generation</a></li>
+<li><a class="reference internal" href="#function-code-generation" id="id4">Function Code Generation</a></li>
+<li><a class="reference internal" href="#driver-changes-and-closing-thoughts" id="id5">Driver Changes and Closing Thoughts</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id6">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-3-introduction">
+<h2><a class="toc-backref" href="#id1">Chapter 3 Introduction</a><a class="headerlink" href="#chapter-3-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 3 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. This chapter shows you how to transform
+the <a class="reference external" href="LangImpl02.html">Abstract Syntax Tree</a>, built in Chapter 2, into
+LLVM IR. This will teach you a little bit about how LLVM does things, as
+well as demonstrate how easy it is to use. Itâs much more work to build
+a lexer and parser than it is to generate LLVM IR code. :)</p>
+<p><strong>Please note</strong>: the code in this chapter and later require LLVM 3.7 or
+later. LLVM 3.6 and before will not work with it. Also note that you
+need to use a version of this tutorial that matches your LLVM release:
+If you are using an official LLVM release, use the version of the
+documentation included with your release or on the <a class="reference external" href="http://llvm.org/releases/">llvm.org releases
+page</a>.</p>
+</div>
+<div class="section" id="code-generation-setup">
+<h2><a class="toc-backref" href="#id2">Code Generation Setup</a><a class="headerlink" href="#code-generation-setup" title="Permalink to this headline">¶</a></h2>
+<p>In order to generate LLVM IR, we want some simple setup to get started.
+First we define virtual code generation (codegen) methods in each AST
+class:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+<span class="p">};</span>
+<span class="p">...</span>
+</pre></div>
+</div>
+<p>The codegen() method says to emit IR for that AST node along with all
+the things it depends on, and they all return an LLVM Value object.
+âValueâ is the class used to represent a â<a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Static Single Assignment
+(SSA)</a>
+registerâ or âSSA valueâ in LLVM. The most distinct aspect of SSA values
+is that their value is computed as the related instruction executes, and
+it does not get a new value until (and if) the instruction re-executes.
+In other words, there is no way to âchangeâ an SSA value. For more
+information, please read up on <a class="reference external" href="http://en.wikipedia.org/wiki/Static_single_assignment_form">Static Single
+Assignment</a>
+- the concepts are really quite natural once you grok them.</p>
+<p>Note that instead of adding virtual methods to the ExprAST class
+hierarchy, it could also make sense to use a <a class="reference external" href="http://en.wikipedia.org/wiki/Visitor_pattern">visitor
+pattern</a> or some other
+way to model this. Again, this tutorial wonât dwell on good software
+engineering practices: for our purposes, adding a virtual method is
+simplest.</p>
+<p>The second thing we want is an âLogErrorâ method like we used for the
+parser, which will be used to report errors found during code generation
+(for example, use of an undeclared parameter):</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">LLVMContext</span> <span class="n">TheContext</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">Builder</span><span class="p">(</span><span class="n">TheContext</span><span class="p">);</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">Module</span><span class="o">></span> <span class="n">TheModule</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">Value</span> <span class="o">*></span> <span class="n">NamedValues</span><span class="p">;</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="nf">LogErrorV</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>The static variables will be used during code generation. <code class="docutils literal notranslate"><span class="pre">TheContext</span></code>
+is an opaque object that owns a lot of core LLVM data structures, such as
+the type and constant value tables. We donât need to understand it in
+detail, we just need a single instance to pass into APIs that require it.</p>
+<p>The <code class="docutils literal notranslate"><span class="pre">Builder</span></code> object is a helper object that makes it easy to generate
+LLVM instructions. Instances of the
+<a class="reference external" href="http://llvm.org/doxygen/IRBuilder_8h-source.html">IRBuilder</a>
+class template keep track of the current place to insert instructions
+and has methods to create new instructions.</p>
+<p><code class="docutils literal notranslate"><span class="pre">TheModule</span></code> is an LLVM construct that contains functions and global
+variables. In many ways, it is the top-level structure that the LLVM IR
+uses to contain code. It will own the memory for all of the IR that we
+generate, which is why the codegen() method returns a raw Value*,
+rather than a unique_ptr<Value>.</p>
+<p>The <code class="docutils literal notranslate"><span class="pre">NamedValues</span></code> map keeps track of which values are defined in the
+current scope and what their LLVM representation is. (In other words, it
+is a symbol table for the code). In this form of Kaleidoscope, the only
+things that can be referenced are function parameters. As such, function
+parameters will be in this map when generating code for their function
+body.</p>
+<p>With these basics in place, we can start talking about how to generate
+code for each expression. Note that this assumes that the <code class="docutils literal notranslate"><span class="pre">Builder</span></code>
+has been set up to generate code <em>into</em> something. For now, weâll assume
+that this has already been done, and weâll just use it to emit code.</p>
+</div>
+<div class="section" id="expression-code-generation">
+<h2><a class="toc-backref" href="#id3">Expression Code Generation</a><a class="headerlink" href="#expression-code-generation" title="Permalink to this headline">¶</a></h2>
+<p>Generating LLVM code for expression nodes is very straightforward: less
+than 45 lines of commented code for all four of our expression nodes.
+First weâll do numeric literals:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Value</span> <span class="o">*</span><span class="n">NumberExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="n">Val</span><span class="p">));</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In the LLVM IR, numeric constants are represented with the
+<code class="docutils literal notranslate"><span class="pre">ConstantFP</span></code> class, which holds the numeric value in an <code class="docutils literal notranslate"><span class="pre">APFloat</span></code>
+internally (<code class="docutils literal notranslate"><span class="pre">APFloat</span></code> has the capability of holding floating point
+constants of Arbitrary Precision). This code basically just creates
+and returns a <code class="docutils literal notranslate"><span class="pre">ConstantFP</span></code>. Note that in the LLVM IR that constants
+are all uniqued together and shared. For this reason, the API uses the
+âfoo::get(â¦)â idiom instead of ânew foo(..)â or âfoo::Create(..)â.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Value</span> <span class="o">*</span><span class="n">VariableExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look this variable up in the function.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">V</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">Name</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>References to variables are also quite simple using LLVM. In the simple
+version of Kaleidoscope, we assume that the variable has already been
+emitted somewhere and its value is available. In practice, the only
+values that can be in the <code class="docutils literal notranslate"><span class="pre">NamedValues</span></code> map are function arguments.
+This code simply checks to see that the specified name is in the map (if
+not, an unknown variable is being referenced) and returns the value for
+it. In future chapters, weâll add support for <a class="reference external" href="LangImpl5.html#for-loop-expression">loop induction
+variables</a> in the symbol table, and for <a class="reference external" href="LangImpl7.html#user-defined-local-variables">local
+variables</a>.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Value</span> <span class="o">*</span><span class="n">BinaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">L</span> <span class="o">=</span> <span class="n">LHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">R</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">L</span> <span class="o">||</span> <span class="o">!</span><span class="n">R</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Op</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="sc">'+'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"addtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'-'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFSub</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"subtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'*'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFMul</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"multmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'<'</span><span class="o">:</span>
+ <span class="n">L</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpULT</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"cmptmp"</span><span class="p">);</span>
+ <span class="c1">// Convert bool 0/1 to double 0.0 or 1.0</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateUIToFP</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span>
+ <span class="s">"booltmp"</span><span class="p">);</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"invalid binary operator"</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Binary operators start to get more interesting. The basic idea here is
+that we recursively emit code for the left-hand side of the expression,
+then the right-hand side, then we compute the result of the binary
+expression. In this code, we do a simple switch on the opcode to create
+the right LLVM instruction.</p>
+<p>In the example above, the LLVM builder class is starting to show its
+value. IRBuilder knows where to insert the newly created instruction,
+all you have to do is specify what instruction to create (e.g. with
+<code class="docutils literal notranslate"><span class="pre">CreateFAdd</span></code>), which operands to use (<code class="docutils literal notranslate"><span class="pre">L</span></code> and <code class="docutils literal notranslate"><span class="pre">R</span></code> here) and
+optionally provide a name for the generated instruction.</p>
+<p>One nice thing about LLVM is that the name is just a hint. For instance,
+if the code above emits multiple âaddtmpâ variables, LLVM will
+automatically provide each one with an increasing, unique numeric
+suffix. Local value names for instructions are purely optional, but it
+makes it much easier to read the IR dumps.</p>
+<p><a class="reference external" href="../LangRef.html#instruction-reference">LLVM instructions</a> are constrained by strict
+rules: for example, the Left and Right operators of an <a class="reference external" href="../LangRef.html#add-instruction">add
+instruction</a> must have the same type, and the
+result type of the add must match the operand types. Because all values
+in Kaleidoscope are doubles, this makes for very simple code for add,
+sub and mul.</p>
+<p>On the other hand, LLVM specifies that the <a class="reference external" href="../LangRef.html#fcmp-instruction">fcmp
+instruction</a> always returns an âi1â value (a
+one bit integer). The problem with this is that Kaleidoscope wants the
+value to be a 0.0 or 1.0 value. In order to get these semantics, we
+combine the fcmp instruction with a <a class="reference external" href="../LangRef.html#uitofp-to-instruction">uitofp
+instruction</a>. This instruction converts its
+input integer into a floating point value by treating the input as an
+unsigned value. In contrast, if we used the <a class="reference external" href="../LangRef.html#sitofp-to-instruction">sitofp
+instruction</a>, the Kaleidoscope â<â operator
+would return 0.0 and -1.0, depending on the input value.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CalleeF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown function referenced"</span><span class="p">);</span>
+
+ <span class="c1">// If argument mismatch error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CalleeF</span><span class="o">-></span><span class="n">arg_size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Incorrect # arguments passed"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Value</span> <span class="o">*></span> <span class="n">ArgsV</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">ArgsV</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">codegen</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ArgsV</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">CalleeF</span><span class="p">,</span> <span class="n">ArgsV</span><span class="p">,</span> <span class="s">"calltmp"</span><span class="p">);</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Code generation for function calls is quite straightforward with LLVM. The code
+above initially does a function name lookup in the LLVM Moduleâs symbol table.
+Recall that the LLVM Module is the container that holds the functions we are
+JITâing. By giving each function the same name as what the user specifies, we
+can use the LLVM symbol table to resolve function names for us.</p>
+<p>Once we have the function to call, we recursively codegen each argument
+that is to be passed in, and create an LLVM <a class="reference external" href="../LangRef.html#call-instruction">call
+instruction</a>. Note that LLVM uses the native C
+calling conventions by default, allowing these calls to also call into
+standard library functions like âsinâ and âcosâ, with no additional
+effort.</p>
+<p>This wraps up our handling of the four basic expressions that we have so
+far in Kaleidoscope. Feel free to go in and add some more. For example,
+by browsing the <a class="reference external" href="../LangRef.html">LLVM language reference</a> youâll find
+several other interesting instructions that are really easy to plug into
+our basic framework.</p>
+</div>
+<div class="section" id="function-code-generation">
+<h2><a class="toc-backref" href="#id4">Function Code Generation</a><a class="headerlink" href="#function-code-generation" title="Permalink to this headline">¶</a></h2>
+<p>Code generation for prototypes and functions must handle a number of
+details, which make their code less beautiful than expression code
+generation, but allows us to illustrate some important points. First,
+letâs talk about code generation for prototypes: they are used both for
+function bodies and external function declarations. The code starts
+with:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Function</span> <span class="o">*</span><span class="n">PrototypeAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Make the function type: double(double,double) etc.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Type</span><span class="o">*></span> <span class="n">Doubles</span><span class="p">(</span><span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span>
+ <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+ <span class="n">FunctionType</span> <span class="o">*</span><span class="n">FT</span> <span class="o">=</span>
+ <span class="n">FunctionType</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="n">Doubles</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span>
+ <span class="n">Function</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">FT</span><span class="p">,</span> <span class="n">Function</span><span class="o">::</span><span class="n">ExternalLinkage</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+</pre></div>
+</div>
+<p>This code packs a lot of power into a few lines. Note first that this
+function returns a âFunction*â instead of a âValue*â. Because a
+âprototypeâ really talks about the external interface for a function
+(not the value computed by an expression), it makes sense for it to
+return the LLVM Function it corresponds to when codegenâd.</p>
+<p>The call to <code class="docutils literal notranslate"><span class="pre">FunctionType::get</span></code> creates the <code class="docutils literal notranslate"><span class="pre">FunctionType</span></code> that
+should be used for a given Prototype. Since all function arguments in
+Kaleidoscope are of type double, the first line creates a vector of âNâ
+LLVM double types. It then uses the <code class="docutils literal notranslate"><span class="pre">Functiontype::get</span></code> method to
+create a function type that takes âNâ doubles as arguments, returns one
+double as a result, and that is not vararg (the false parameter
+indicates this). Note that Types in LLVM are uniqued just like Constants
+are, so you donât ânewâ a type, you âgetâ it.</p>
+<p>The final line above actually creates the IR Function corresponding to
+the Prototype. This indicates the type, linkage and name to use, as
+well as which module to insert into. â<a class="reference external" href="../LangRef.html#linkage">external
+linkage</a>â means that the function may be
+defined outside the current module and/or that it is callable by
+functions outside the module. The Name passed in is the name the user
+specified: since â<code class="docutils literal notranslate"><span class="pre">TheModule</span></code>â is specified, this name is registered
+in â<code class="docutils literal notranslate"><span class="pre">TheModule</span></code>âs symbol table.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Set names for all arguments.</span>
+<span class="kt">unsigned</span> <span class="n">Idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">Arg</span><span class="p">.</span><span class="n">setName</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">Idx</span><span class="o">++</span><span class="p">]);</span>
+
+<span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>Finally, we set the name of each of the functionâs arguments according to the
+names given in the Prototype. This step isnât strictly necessary, but keeping
+the names consistent makes the IR more readable, and allows subsequent code to
+refer directly to the arguments for their names, rather than having to look up
+them up in the Prototype AST.</p>
+<p>At this point we have a function prototype with no body. This is how LLVM IR
+represents function declarations. For extern statements in Kaleidoscope, this
+is as far as we need to go. For function definitions however, we need to
+codegen and attach a function body.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// First, check for an existing function from a previous 'extern' declaration.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">());</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Proto</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="o">-></span><span class="n">empty</span><span class="p">())</span>
+ <span class="k">return</span> <span class="p">(</span><span class="n">Function</span><span class="o">*</span><span class="p">)</span><span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Function cannot be redefined."</span><span class="p">);</span>
+</pre></div>
+</div>
+<p>For function definitions, we start by searching TheModuleâs symbol table for an
+existing version of this function, in case one has already been created using an
+âexternâ statement. If Module::getFunction returns null then no previous version
+exists, so weâll codegen one from the Prototype. In either case, we want to
+assert that the function is empty (i.e. has no body yet) before we start.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Create a new basic block to start insertion into.</span>
+<span class="n">BasicBlock</span> <span class="o">*</span><span class="n">BB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"entry"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+<span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
+
+<span class="c1">// Record the function arguments in the NamedValues map.</span>
+<span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="o">&</span><span class="n">Arg</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>Now we get to the point where the <code class="docutils literal notranslate"><span class="pre">Builder</span></code> is set up. The first line
+creates a new <a class="reference external" href="http://en.wikipedia.org/wiki/Basic_block">basic block</a>
+(named âentryâ), which is inserted into <code class="docutils literal notranslate"><span class="pre">TheFunction</span></code>. The second line
+then tells the builder that new instructions should be inserted into the
+end of the new basic block. Basic blocks in LLVM are an important part
+of functions that define the <a class="reference external" href="http://en.wikipedia.org/wiki/Control_flow_graph">Control Flow
+Graph</a>. Since we
+donât have any control flow, our functions will only contain one block
+at this point. Weâll fix this in <a class="reference external" href="LangImpl05.html">Chapter 5</a> :).</p>
+<p>Next we add the function arguments to the NamedValues map (after first clearing
+it out) so that theyâre accessible to <code class="docutils literal notranslate"><span class="pre">VariableExprAST</span></code> nodes.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Once the insertion point has been set up and the NamedValues map populated,
+we call the <code class="docutils literal notranslate"><span class="pre">codegen()</span></code> method for the root expression of the function. If no
+error happens, this emits code to compute the expression into the entry block
+and returns the value that was computed. Assuming no error, we then create an
+LLVM <a class="reference external" href="../LangRef.html#ret-instruction">ret instruction</a>, which completes the function.
+Once the function is built, we call <code class="docutils literal notranslate"><span class="pre">verifyFunction</span></code>, which is
+provided by LLVM. This function does a variety of consistency checks on
+the generated code, to determine if our compiler is doing everything
+right. Using this is important: it can catch a lot of bugs. Once the
+function is finished and validated, we return it.</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span> <span class="c1">// Error reading body, remove function.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">eraseFromParent</span><span class="p">();</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>The only piece left here is handling of the error case. For simplicity,
+we handle this by merely deleting the function we produced with the
+<code class="docutils literal notranslate"><span class="pre">eraseFromParent</span></code> method. This allows the user to redefine a function
+that they incorrectly typed in before: if we didnât delete it, it would
+live in the symbol table, with a body, preventing future redefinition.</p>
+<p>This code does have a bug, though: If the <code class="docutils literal notranslate"><span class="pre">FunctionAST::codegen()</span></code> method
+finds an existing IR Function, it does not validate its signature against the
+definitionâs own prototype. This means that an earlier âexternâ declaration will
+take precedence over the function definitionâs signature, which can cause
+codegen to fail, for instance if the function arguments are named differently.
+There are a number of ways to fix this bug, see what you can come up with! Here
+is a testcase:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">extern</span> <span class="n">foo</span><span class="p">(</span><span class="n">a</span><span class="p">);</span> <span class="c1"># ok, defines foo.</span>
+<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="n">b</span><span class="p">;</span> <span class="c1"># Error: Unknown variable name. (decl using 'a' takes precedence).</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="driver-changes-and-closing-thoughts">
+<h2><a class="toc-backref" href="#id5">Driver Changes and Closing Thoughts</a><a class="headerlink" href="#driver-changes-and-closing-thoughts" title="Permalink to this headline">¶</a></h2>
+<p>For now, code generation to LLVM doesnât really get us much, except that
+we can look at the pretty IR calls. The sample code inserts calls to
+codegen into the â<code class="docutils literal notranslate"><span class="pre">HandleDefinition</span></code>â, â<code class="docutils literal notranslate"><span class="pre">HandleExtern</span></code>â etc
+functions, and then dumps out the LLVM IR. This gives a nice way to look
+at the LLVM IR for simple functions. For example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="mi">4</span><span class="o">+</span><span class="mi">5</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">top</span><span class="o">-</span><span class="n">level</span> <span class="n">expression</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@0</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="mf">9.000000e+00</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Note how the parser turns the top-level expression into anonymous
+functions for us. This will be handy when we add <a class="reference external" href="LangImpl4.html#adding-a-jit-compiler">JIT
+support</a> in the next chapter. Also note that the
+code is very literally transcribed, no optimizations are being performed
+except simple constant folding done by IRBuilder. We will <a class="reference external" href="LangImpl4.html#trivial-constant-folding">add
+optimizations</a> explicitly in the next
+chapter.</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">a</span> <span class="n">b</span><span class="p">)</span> <span class="n">a</span><span class="o">*</span><span class="n">a</span> <span class="o">+</span> <span class="mi">2</span><span class="o">*</span><span class="n">a</span><span class="o">*</span><span class="n">b</span> <span class="o">+</span> <span class="n">b</span><span class="o">*</span><span class="n">b</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="n">double</span> <span class="o">%</span><span class="n">b</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">multmp</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="o">%</span><span class="n">a</span>
+ <span class="o">%</span><span class="n">multmp1</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="mf">2.000000e+00</span><span class="p">,</span> <span class="o">%</span><span class="n">a</span>
+ <span class="o">%</span><span class="n">multmp2</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp1</span><span class="p">,</span> <span class="o">%</span><span class="n">b</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp</span><span class="p">,</span> <span class="o">%</span><span class="n">multmp2</span>
+ <span class="o">%</span><span class="n">multmp3</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">b</span><span class="p">,</span> <span class="o">%</span><span class="n">b</span>
+ <span class="o">%</span><span class="n">addtmp4</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span><span class="p">,</span> <span class="o">%</span><span class="n">multmp3</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp4</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This shows some simple arithmetic. Notice the striking similarity to the
+LLVM builder calls that we use to create the instructions.</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="n">a</span><span class="p">)</span> <span class="n">foo</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="mf">4.0</span><span class="p">)</span> <span class="o">+</span> <span class="n">bar</span><span class="p">(</span><span class="mi">31337</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@bar</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="n">double</span> <span class="mf">4.000000e+00</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">calltmp1</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@bar</span><span class="p">(</span><span class="n">double</span> <span class="mf">3.133700e+04</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span><span class="p">,</span> <span class="o">%</span><span class="n">calltmp1</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This shows some function calls. Note that this function will take a long
+time to execute if you call it. In the future weâll add conditional
+control flow to actually make recursion useful :).</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="n">extern</span> <span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">extern</span><span class="p">:</span>
+<span class="n">declare</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span><span class="p">)</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">cos</span><span class="p">(</span><span class="mf">1.234</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">top</span><span class="o">-</span><span class="n">level</span> <span class="n">expression</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@1</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span> <span class="mf">1.234000e+00</span><span class="p">)</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This shows an extern for the libm âcosâ function, and a call to it.</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="o">^</span><span class="n">D</span>
+<span class="p">;</span> <span class="n">ModuleID</span> <span class="o">=</span> <span class="s1">'my cool jit'</span>
+
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@0</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="mf">4.000000e+00</span><span class="p">,</span> <span class="mf">5.000000e+00</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="n">double</span> <span class="o">%</span><span class="n">b</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">multmp</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="o">%</span><span class="n">a</span>
+ <span class="o">%</span><span class="n">multmp1</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="mf">2.000000e+00</span><span class="p">,</span> <span class="o">%</span><span class="n">a</span>
+ <span class="o">%</span><span class="n">multmp2</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp1</span><span class="p">,</span> <span class="o">%</span><span class="n">b</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp</span><span class="p">,</span> <span class="o">%</span><span class="n">multmp2</span>
+ <span class="o">%</span><span class="n">multmp3</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">b</span><span class="p">,</span> <span class="o">%</span><span class="n">b</span>
+ <span class="o">%</span><span class="n">addtmp4</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span><span class="p">,</span> <span class="o">%</span><span class="n">multmp3</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp4</span>
+<span class="p">}</span>
+
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@bar</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">a</span><span class="p">,</span> <span class="n">double</span> <span class="mf">4.000000e+00</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">calltmp1</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@bar</span><span class="p">(</span><span class="n">double</span> <span class="mf">3.133700e+04</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span><span class="p">,</span> <span class="o">%</span><span class="n">calltmp1</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+
+<span class="n">declare</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span><span class="p">)</span>
+
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@1</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span> <span class="mf">1.234000e+00</span><span class="p">)</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>When you quit the current demo (by sending an EOF via CTRL+D on Linux
+or CTRL+Z and ENTER on Windows), it dumps out the IR for the entire
+module generated. Here you can see the big picture with all the
+functions referencing each other.</p>
+<p>This wraps up the third chapter of the Kaleidoscope tutorial. Up next,
+weâll describe how to <a class="reference external" href="LangImpl04.html">add JIT codegen and optimizer
+support</a> to this so we can actually start running
+code!</p>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id6">Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+the LLVM code generator. Because this uses the LLVM libraries, we need
+to link them in. To do this, we use the
+<a class="reference external" href="http://llvm.org/cmds/llvm-config.html">llvm-config</a> tool to inform
+our makefile/command line about which options to use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+clang++ -g -O3 toy.cpp <span class="sb">`</span>llvm-config --cxxflags --ldflags --system-libs --libs core<span class="sb">`</span> -o toy
+<span class="c1"># Run</span>
+./toy
+</pre></div>
+</div>
+<p>Here is the code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">"llvm/ADT/APFloat.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/ADT/STLExtras.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/BasicBlock.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Constants.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/DerivedTypes.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Function.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/IRBuilder.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LLVMContext.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Module.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Type.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Verifier.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><algorithm></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cctype></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdio></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdlib></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><map></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><memory></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
+
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="p">;</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Lexer</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span>
+<span class="p">};</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+
+<span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">namespace</span> <span class="p">{</span>
+
+<span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
+
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="nf">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span> <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Op</span><span class="p">(</span><span class="n">Op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes).</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+<span class="p">};</span>
+
+<span class="p">}</span> <span class="c1">// end anonymous namespace</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Parser</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span> <span class="p">}</span>
+
+<span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">();</span>
+
+<span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' primary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+
+ <span class="c1">// Okay, we know this is a binop.</span>
+ <span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+ <span class="c1">// Parse the primary expression after the binary operator.</span>
+ <span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span>
+ <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// expression</span>
+<span class="c1">/// ::= primary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ArgNames</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Code Generation</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="n">LLVMContext</span> <span class="n">TheContext</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">Builder</span><span class="p">(</span><span class="n">TheContext</span><span class="p">);</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">Module</span><span class="o">></span> <span class="n">TheModule</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">Value</span> <span class="o">*></span> <span class="n">NamedValues</span><span class="p">;</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="nf">LogErrorV</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">NumberExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="n">Val</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VariableExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look this variable up in the function.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">V</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">Name</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">BinaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">L</span> <span class="o">=</span> <span class="n">LHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">R</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">L</span> <span class="o">||</span> <span class="o">!</span><span class="n">R</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Op</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="sc">'+'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"addtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'-'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFSub</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"subtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'*'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFMul</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"multmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'<'</span><span class="o">:</span>
+ <span class="n">L</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpULT</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"cmptmp"</span><span class="p">);</span>
+ <span class="c1">// Convert bool 0/1 to double 0.0 or 1.0</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateUIToFP</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="s">"booltmp"</span><span class="p">);</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"invalid binary operator"</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CalleeF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown function referenced"</span><span class="p">);</span>
+
+ <span class="c1">// If argument mismatch error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CalleeF</span><span class="o">-></span><span class="n">arg_size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Incorrect # arguments passed"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Value</span> <span class="o">*></span> <span class="n">ArgsV</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">ArgsV</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">codegen</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ArgsV</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">CalleeF</span><span class="p">,</span> <span class="n">ArgsV</span><span class="p">,</span> <span class="s">"calltmp"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">PrototypeAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Make the function type: double(double,double) etc.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Type</span> <span class="o">*></span> <span class="n">Doubles</span><span class="p">(</span><span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+ <span class="n">FunctionType</span> <span class="o">*</span><span class="n">FT</span> <span class="o">=</span>
+ <span class="n">FunctionType</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="n">Doubles</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span>
+ <span class="n">Function</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">FT</span><span class="p">,</span> <span class="n">Function</span><span class="o">::</span><span class="n">ExternalLinkage</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Set names for all arguments.</span>
+ <span class="kt">unsigned</span> <span class="n">Idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">Arg</span><span class="p">.</span><span class="n">setName</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">Idx</span><span class="o">++</span><span class="p">]);</span>
+
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// First, check for an existing function from a previous 'extern' declaration.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">());</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="n">TheFunction</span> <span class="o">=</span> <span class="n">Proto</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Create a new basic block to start insertion into.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">BB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"entry"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
+
+ <span class="c1">// Record the function arguments in the NamedValues map.</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="o">&</span><span class="n">Arg</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Error reading body, remove function.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">eraseFromParent</span><span class="p">();</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Top-Level parsing and JIT Driver</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read function definition:"</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ProtoAST</span> <span class="o">=</span> <span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">ProtoAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read extern: "</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read top-level expression:"</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="n">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Main driver code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="c1">// Make the module, which holds all the code.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="c1">// Print out all of the generated code.</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><a class="reference external" href="LangImpl04.html">Next: Adding JIT and Optimizer Support</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ >index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-07-10.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html
URL: http://llvm.org/viewvc/llvm-project/www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html?rev=368037&view=auto
==============================================================================
--- www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html (added)
+++ www-releases/trunk/8.0.1/docs/tutorial/MyFirstLanguageFrontend/LangImpl04.html Tue Aug 6 06:51:02 2019
@@ -0,0 +1,1361 @@
+
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Kaleidoscope: Adding JIT and Optimizer Support — LLVM 9 documentation</title>
+ <link rel="stylesheet" href="../../_static/llvm-theme.css" type="text/css" />
+ <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
+ <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <link rel="index" title="Index" href="../../genindex.html" />
+ <link rel="search" title="Search" href="../../search.html" />
+<style type="text/css">
+ table.right { float: right; margin-left: 20px; }
+ table.right td { border: 1px solid #ccc; }
+</style>
+
+ </head><body>
+<div class="logo">
+ <a href="../../index.html">
+ <img src="../../_static/logo.png"
+ alt="LLVM Logo" width="250" height="88"/></a>
+</div>
+
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="body" role="main">
+
+ <div class="section" id="kaleidoscope-adding-jit-and-optimizer-support">
+<h1>Kaleidoscope: Adding JIT and Optimizer Support<a class="headerlink" href="#kaleidoscope-adding-jit-and-optimizer-support" title="Permalink to this headline">¶</a></h1>
+<div class="contents local topic" id="contents">
+<ul class="simple">
+<li><a class="reference internal" href="#chapter-4-introduction" id="id1">Chapter 4 Introduction</a></li>
+<li><a class="reference internal" href="#trivial-constant-folding" id="id2">Trivial Constant Folding</a></li>
+<li><a class="reference internal" href="#llvm-optimization-passes" id="id3">LLVM Optimization Passes</a></li>
+<li><a class="reference internal" href="#adding-a-jit-compiler" id="id4">Adding a JIT Compiler</a></li>
+<li><a class="reference internal" href="#full-code-listing" id="id5">Full Code Listing</a></li>
+</ul>
+</div>
+<div class="section" id="chapter-4-introduction">
+<h2><a class="toc-backref" href="#id1">Chapter 4 Introduction</a><a class="headerlink" href="#chapter-4-introduction" title="Permalink to this headline">¶</a></h2>
+<p>Welcome to Chapter 4 of the â<a class="reference external" href="index.html">Implementing a language with
+LLVM</a>â tutorial. Chapters 1-3 described the implementation
+of a simple language and added support for generating LLVM IR. This
+chapter describes two new techniques: adding optimizer support to your
+language, and adding JIT compiler support. These additions will
+demonstrate how to get nice, efficient code for the Kaleidoscope
+language.</p>
+</div>
+<div class="section" id="trivial-constant-folding">
+<h2><a class="toc-backref" href="#id2">Trivial Constant Folding</a><a class="headerlink" href="#trivial-constant-folding" title="Permalink to this headline">¶</a></h2>
+<p>Our demonstration for Chapter 3 is elegant and easy to extend.
+Unfortunately, it does not produce wonderful code. The IRBuilder,
+however, does give us obvious optimizations when compiling simple code:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="o">+</span><span class="n">x</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@test</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="mf">3.000000e+00</span><span class="p">,</span> <span class="o">%</span><span class="n">x</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This code is not a literal transcription of the AST built by parsing the
+input. That would be:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="o">+</span><span class="n">x</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@test</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="mf">2.000000e+00</span><span class="p">,</span> <span class="mf">1.000000e+00</span>
+ <span class="o">%</span><span class="n">addtmp1</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span><span class="p">,</span> <span class="o">%</span><span class="n">x</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp1</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Constant folding, as seen above, in particular, is a very common and
+very important optimization: so much so that many language implementors
+implement constant folding support in their AST representation.</p>
+<p>With LLVM, you donât need this support in the AST. Since all calls to
+build LLVM IR go through the LLVM IR builder, the builder itself checked
+to see if there was a constant folding opportunity when you call it. If
+so, it just does the constant fold and return the constant instead of
+creating an instruction.</p>
+<p>Well, that was easy :). In practice, we recommend always using
+<code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> when generating code like this. It has no âsyntactic
+overheadâ for its use (you donât have to uglify your compiler with
+constant checks everywhere) and it can dramatically reduce the amount of
+LLVM IR that is generated in some cases (particular for languages with a
+macro preprocessor or that use a lot of constants).</p>
+<p>On the other hand, the <code class="docutils literal notranslate"><span class="pre">IRBuilder</span></code> is limited by the fact that it does
+all of its analysis inline with the code as it is built. If you take a
+slightly more complex example:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="o">+</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="p">(</span><span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="p">));</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@test</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="mf">3.000000e+00</span><span class="p">,</span> <span class="o">%</span><span class="n">x</span>
+ <span class="o">%</span><span class="n">addtmp1</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">,</span> <span class="mf">3.000000e+00</span>
+ <span class="o">%</span><span class="n">multmp</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span><span class="p">,</span> <span class="o">%</span><span class="n">addtmp1</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In this case, the LHS and RHS of the multiplication are the same value.
+Weâd really like to see this generate â<code class="docutils literal notranslate"><span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">x+3;</span> <span class="pre">result</span> <span class="pre">=</span> <span class="pre">tmp*tmp;</span></code>â
+instead of computing â<code class="docutils literal notranslate"><span class="pre">x+3</span></code>â twice.</p>
+<p>Unfortunately, no amount of local analysis will be able to detect and
+correct this. This requires two transformations: reassociation of
+expressions (to make the addâs lexically identical) and Common
+Subexpression Elimination (CSE) to delete the redundant add instruction.
+Fortunately, LLVM provides a broad range of optimizations that you can
+use, in the form of âpassesâ.</p>
+</div>
+<div class="section" id="llvm-optimization-passes">
+<h2><a class="toc-backref" href="#id3">LLVM Optimization Passes</a><a class="headerlink" href="#llvm-optimization-passes" title="Permalink to this headline">¶</a></h2>
+<div class="admonition warning">
+<p class="first admonition-title">Warning</p>
+<p class="last">Due to the transition to the new PassManager infrastructure this tutorial
+is based on <code class="docutils literal notranslate"><span class="pre">llvm::legacy::FunctionPassManager</span></code> which can be found in
+<a class="reference external" href="http://llvm.org/doxygen/classllvm_1_1legacy_1_1FunctionPassManager.html">LegacyPassManager.h</a>.
+For the purpose of the this tutorial the above should be used until
+the pass manager transition is complete.</p>
+</div>
+<p>LLVM provides many optimization passes, which do many different sorts of
+things and have different tradeoffs. Unlike other systems, LLVM doesnât
+hold to the mistaken notion that one set of optimizations is right for
+all languages and for all situations. LLVM allows a compiler implementor
+to make complete decisions about what optimizations to use, in which
+order, and in what situation.</p>
+<p>As a concrete example, LLVM supports both âwhole moduleâ passes, which
+look across as large of body of code as they can (often a whole file,
+but if run at link time, this can be a substantial portion of the whole
+program). It also supports and includes âper-functionâ passes which just
+operate on a single function at a time, without looking at other
+functions. For more information on passes and how they are run, see the
+<a class="reference external" href="../WritingAnLLVMPass.html">How to Write a Pass</a> document and the
+<a class="reference external" href="../Passes.html">List of LLVM Passes</a>.</p>
+<p>For Kaleidoscope, we are currently generating functions on the fly, one
+at a time, as the user types them in. We arenât shooting for the
+ultimate optimization experience in this setting, but we also want to
+catch the easy and quick stuff where possible. As such, we will choose
+to run a few per-function optimizations as the user types the function
+in. If we wanted to make a âstatic Kaleidoscope compilerâ, we would use
+exactly the code we have now, except that we would defer running the
+optimizer until the entire file has been parsed.</p>
+<p>In order to get per-function optimizations going, we need to set up a
+<a class="reference external" href="../WritingAnLLVMPass.html#what-passmanager-doesr">FunctionPassManager</a> to hold
+and organize the LLVM optimizations that we want to run. Once we have
+that, we can add a set of optimizations to run. Weâll need a new
+FunctionPassManager for each module that we want to optimize, so weâll
+write a function to create and initialize both the module and pass manager
+for us:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">InitializeModuleAndPassManager</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Open a new module.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+
+ <span class="c1">// Create a new pass manager attached to it.</span>
+ <span class="n">TheFPM</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionPassManager</span><span class="o">></span><span class="p">(</span><span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Do simple "peephole" optimizations and bit-twiddling optzns.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createInstructionCombiningPass</span><span class="p">());</span>
+ <span class="c1">// Reassociate expressions.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createReassociatePass</span><span class="p">());</span>
+ <span class="c1">// Eliminate Common SubExpressions.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createGVNPass</span><span class="p">());</span>
+ <span class="c1">// Simplify the control flow graph (deleting unreachable blocks, etc).</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createCFGSimplificationPass</span><span class="p">());</span>
+
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">doInitialization</span><span class="p">();</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>This code initializes the global module <code class="docutils literal notranslate"><span class="pre">TheModule</span></code>, and the function pass
+manager <code class="docutils literal notranslate"><span class="pre">TheFPM</span></code>, which is attached to <code class="docutils literal notranslate"><span class="pre">TheModule</span></code>. Once the pass manager is
+set up, we use a series of âaddâ calls to add a bunch of LLVM passes.</p>
+<p>In this case, we choose to add four optimization passes.
+The passes we choose here are a pretty standard set
+of âcleanupâ optimizations that are useful for a wide variety of code. I wonât
+delve into what they do but, believe me, they are a good starting place :).</p>
+<p>Once the PassManager is set up, we need to make use of it. We do this by
+running it after our newly created function is constructed (in
+<code class="docutils literal notranslate"><span class="pre">FunctionAST::codegen()</span></code>), but before it is returned to the client:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Optimize the function.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">run</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>As you can see, this is pretty straightforward. The
+<code class="docutils literal notranslate"><span class="pre">FunctionPassManager</span></code> optimizes and updates the LLVM Function* in
+place, improving (hopefully) its body. With this in place, we can try
+our test above again:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="o">+</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="p">(</span><span class="mi">1</span><span class="o">+</span><span class="mi">2</span><span class="p">));</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@test</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">,</span> <span class="mf">3.000000e+00</span>
+ <span class="o">%</span><span class="n">multmp</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span><span class="p">,</span> <span class="o">%</span><span class="n">addtmp</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>As expected, we now get our nicely optimized code, saving a floating
+point add instruction from every execution of this function.</p>
+<p>LLVM provides a wide variety of optimizations that can be used in
+certain circumstances. Some <a class="reference external" href="../Passes.html">documentation about the various
+passes</a> is available, but it isnât very complete.
+Another good source of ideas can come from looking at the passes that
+<code class="docutils literal notranslate"><span class="pre">Clang</span></code> runs to get started. The â<code class="docutils literal notranslate"><span class="pre">opt</span></code>â tool allows you to
+experiment with passes from the command line, so you can see if they do
+anything.</p>
+<p>Now that we have reasonable code coming out of our front-end, letâs talk
+about executing it!</p>
+</div>
+<div class="section" id="adding-a-jit-compiler">
+<h2><a class="toc-backref" href="#id4">Adding a JIT Compiler</a><a class="headerlink" href="#adding-a-jit-compiler" title="Permalink to this headline">¶</a></h2>
+<p>Code that is available in LLVM IR can have a wide variety of tools
+applied to it. For example, you can run optimizations on it (as we did
+above), you can dump it out in textual or binary forms, you can compile
+the code to an assembly file (.s) for some target, or you can JIT
+compile it. The nice thing about the LLVM IR representation is that it
+is the âcommon currencyâ between many different parts of the compiler.</p>
+<p>In this section, weâll add JIT compiler support to our interpreter. The
+basic idea that we want for Kaleidoscope is to have the user enter
+function bodies as they do now, but immediately evaluate the top-level
+expressions they type in. For example, if they type in â1 + 2;â, we
+should evaluate and print out 3. If they define a function, they should
+be able to call it from the command line.</p>
+<p>In order to do this, we first prepare the environment to create code for
+the current native target and declare and initialize the JIT. This is
+done by calling some <code class="docutils literal notranslate"><span class="pre">InitializeNativeTarget\*</span></code> functions and
+adding a global variable <code class="docutils literal notranslate"><span class="pre">TheJIT</span></code>, and initializing it in
+<code class="docutils literal notranslate"><span class="pre">main</span></code>:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span> <span class="n">TheJIT</span><span class="p">;</span>
+<span class="p">...</span>
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">InitializeNativeTarget</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmPrinter</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmParser</span><span class="p">();</span>
+
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="n">TheJIT</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span><span class="p">();</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>We also need to setup the data layout for the JIT:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span> <span class="nf">InitializeModuleAndPassManager</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Open a new module.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TheJIT</span><span class="o">-></span><span class="n">getTargetMachine</span><span class="p">().</span><span class="n">createDataLayout</span><span class="p">());</span>
+
+ <span class="c1">// Create a new pass manager attached to it.</span>
+ <span class="n">TheFPM</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionPassManager</span><span class="o">></span><span class="p">(</span><span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+ <span class="p">...</span>
+</pre></div>
+</div>
+<p>The KaleidoscopeJIT class is a simple JIT built specifically for these
+tutorials, available inside the LLVM source code
+at llvm-src/examples/Kaleidoscope/include/KaleidoscopeJIT.h.
+In later chapters we will look at how it works and extend it with
+new features, but for now we will take it as given. Its API is very simple:
+<code class="docutils literal notranslate"><span class="pre">addModule</span></code> adds an LLVM IR module to the JIT, making its functions
+available for execution; <code class="docutils literal notranslate"><span class="pre">removeModule</span></code> removes a module, freeing any
+memory associated with the code in that module; and <code class="docutils literal notranslate"><span class="pre">findSymbol</span></code> allows us
+to look up pointers to the compiled code.</p>
+<p>We can take this simple API and change our code that parses top-level expressions to
+look like this:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+
+ <span class="c1">// JIT the module containing the anonymous expression, keeping a handle so</span>
+ <span class="c1">// we can free it later.</span>
+ <span class="k">auto</span> <span class="n">H</span> <span class="o">=</span> <span class="n">TheJIT</span><span class="o">-></span><span class="n">addModule</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">TheModule</span><span class="p">));</span>
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+
+ <span class="c1">// Search the JIT for the __anon_expr symbol.</span>
+ <span class="k">auto</span> <span class="n">ExprSymbol</span> <span class="o">=</span> <span class="n">TheJIT</span><span class="o">-></span><span class="n">findSymbol</span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">);</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">ExprSymbol</span> <span class="o">&&</span> <span class="s">"Function not found"</span><span class="p">);</span>
+
+ <span class="c1">// Get the symbol's address and cast it to the right type (takes no</span>
+ <span class="c1">// arguments, returns a double) so we can call it as a native function.</span>
+ <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">FP</span><span class="p">)()</span> <span class="o">=</span> <span class="p">(</span><span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="p">)())(</span><span class="kt">intptr_t</span><span class="p">)</span><span class="n">ExprSymbol</span><span class="p">.</span><span class="n">getAddress</span><span class="p">();</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Evaluated to %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">FP</span><span class="p">());</span>
+
+ <span class="c1">// Delete the anonymous expression module from the JIT.</span>
+ <span class="n">TheJIT</span><span class="o">-></span><span class="n">removeModule</span><span class="p">(</span><span class="n">H</span><span class="p">);</span>
+ <span class="p">}</span>
+</pre></div>
+</div>
+<p>If parsing and codegen succeeed, the next step is to add the module containing
+the top-level expression to the JIT. We do this by calling addModule, which
+triggers code generation for all the functions in the module, and returns a
+handle that can be used to remove the module from the JIT later. Once the module
+has been added to the JIT it can no longer be modified, so we also open a new
+module to hold subsequent code by calling <code class="docutils literal notranslate"><span class="pre">InitializeModuleAndPassManager()</span></code>.</p>
+<p>Once weâve added the module to the JIT we need to get a pointer to the final
+generated code. We do this by calling the JITâs findSymbol method, and passing
+the name of the top-level expression function: <code class="docutils literal notranslate"><span class="pre">__anon_expr</span></code>. Since we just
+added this function, we assert that findSymbol returned a result.</p>
+<p>Next, we get the in-memory address of the <code class="docutils literal notranslate"><span class="pre">__anon_expr</span></code> function by calling
+<code class="docutils literal notranslate"><span class="pre">getAddress()</span></code> on the symbol. Recall that we compile top-level expressions
+into a self-contained LLVM function that takes no arguments and returns the
+computed double. Because the LLVM JIT compiler matches the native platform ABI,
+this means that you can just cast the result pointer to a function pointer of
+that type and call it directly. This means, there is no difference between JIT
+compiled code and native machine code that is statically linked into your
+application.</p>
+<p>Finally, since we donât support re-evaluation of top-level expressions, we
+remove the module from the JIT when weâre done to free the associated memory.
+Recall, however, that the module we created a few lines earlier (via
+<code class="docutils literal notranslate"><span class="pre">InitializeModuleAndPassManager</span></code>) is still open and waiting for new code to be
+added.</p>
+<p>With just these two changes, letâs see how Kaleidoscope works now!</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="mi">4</span><span class="o">+</span><span class="mi">5</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">top</span><span class="o">-</span><span class="n">level</span> <span class="n">expression</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@0</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="mf">9.000000e+00</span>
+<span class="p">}</span>
+
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">9.000000</span>
+</pre></div>
+</div>
+<p>Well this looks like it is basically working. The dump of the function
+shows the âno argument function that always returns doubleâ that we
+synthesize for each top-level expression that is typed in. This
+demonstrates very basic functionality, but can we do more?</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>ready> def testfunc(x y) x + y*2;
+Read function definition:
+define double @testfunc(double %x, double %y) {
+entry:
+ %multmp = fmul double %y, 2.000000e+00
+ %addtmp = fadd double %multmp, %x
+ ret double %addtmp
+}
+
+ready> testfunc(4, 10);
+Read top-level expression:
+define double @1() {
+entry:
+ %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
+ ret double %calltmp
+}
+
+Evaluated to 24.000000
+
+ready> testfunc(5, 10);
+ready> LLVM ERROR: Program used external function 'testfunc' which could not be resolved!
+</pre></div>
+</div>
+<p>Function definitions and calls also work, but something went very wrong on that
+last line. The call looks valid, so what happened? As you may have guessed from
+the API a Module is a unit of allocation for the JIT, and testfunc was part
+of the same module that contained anonymous expression. When we removed that
+module from the JIT to free the memory for the anonymous expression, we deleted
+the definition of <code class="docutils literal notranslate"><span class="pre">testfunc</span></code> along with it. Then, when we tried to call
+testfunc a second time, the JIT could no longer find it.</p>
+<p>The easiest way to fix this is to put the anonymous expression in a separate
+module from the rest of the function definitions. The JIT will happily resolve
+function calls across module boundaries, as long as each of the functions called
+has a prototype, and is added to the JIT before it is called. By putting the
+anonymous expression in a different module we can delete it without affecting
+the rest of the functions.</p>
+<p>In fact, weâre going to go a step further and put every function in its own
+module. Doing so allows us to exploit a useful property of the KaleidoscopeJIT
+that will make our environment more REPL-like: Functions can be added to the
+JIT more than once (unlike a module where every function must have a unique
+definition). When you look up a symbol in KaleidoscopeJIT it will always return
+the most recent definition:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">,</span> <span class="mf">1.000000e+00</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">foo</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">3.000000</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">,</span> <span class="mf">2.000000e+00</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">foo</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">4.000000</span>
+</pre></div>
+</div>
+<p>To allow each function to live in its own module weâll need a way to
+re-generate previous function declarations into each new module we open:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span> <span class="n">TheJIT</span><span class="p">;</span>
+
+<span class="p">...</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// First, see if the function has already been added to the current module.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Name</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+
+ <span class="c1">// If not, check whether we can codegen the declaration from some existing</span>
+ <span class="c1">// prototype.</span>
+ <span class="k">auto</span> <span class="n">FI</span> <span class="o">=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">Name</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FI</span> <span class="o">!=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">FI</span><span class="o">-></span><span class="n">second</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="c1">// If no existing prototype exists, return null.</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="p">...</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+
+<span class="p">...</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Transfer ownership of the prototype to the FunctionProtos map, but keep a</span>
+ <span class="c1">// reference to it for use below.</span>
+ <span class="k">auto</span> <span class="o">&</span><span class="n">P</span> <span class="o">=</span> <span class="o">*</span><span class="n">Proto</span><span class="p">;</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">);</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+</pre></div>
+</div>
+<p>To enable this, weâll start by adding a new global, <code class="docutils literal notranslate"><span class="pre">FunctionProtos</span></code>, that
+holds the most recent prototype for each function. Weâll also add a convenience
+method, <code class="docutils literal notranslate"><span class="pre">getFunction()</span></code>, to replace calls to <code class="docutils literal notranslate"><span class="pre">TheModule->getFunction()</span></code>.
+Our convenience method searches <code class="docutils literal notranslate"><span class="pre">TheModule</span></code> for an existing function
+declaration, falling back to generating a new declaration from FunctionProtos if
+it doesnât find one. In <code class="docutils literal notranslate"><span class="pre">CallExprAST::codegen()</span></code> we just need to replace the
+call to <code class="docutils literal notranslate"><span class="pre">TheModule->getFunction()</span></code>. In <code class="docutils literal notranslate"><span class="pre">FunctionAST::codegen()</span></code> we need to
+update the FunctionProtos map first, then call <code class="docutils literal notranslate"><span class="pre">getFunction()</span></code>. With this
+done, we can always obtain a function declaration in the current module for any
+previously declared function.</p>
+<p>We also need to update HandleDefinition and HandleExtern:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">static</span> <span class="kt">void</span> <span class="nf">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read function definition:"</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="n">TheJIT</span><span class="o">-></span><span class="n">addModule</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">TheModule</span><span class="p">));</span>
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="nf">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ProtoAST</span> <span class="o">=</span> <span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">ProtoAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read extern: "</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">ProtoAST</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ProtoAST</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>In HandleDefinition, we add two lines to transfer the newly defined function to
+the JIT and open a new module. In HandleExtern, we just need to add one line to
+add the prototype to FunctionProtos.</p>
+<p>With these changes made, letâs try our REPL again (I removed the dump of the
+anonymous functions this time, you should get the idea by now :) :</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">foo</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">3.000000</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">x</span> <span class="o">+</span> <span class="mi">2</span><span class="p">;</span>
+<span class="n">ready</span><span class="o">></span> <span class="n">foo</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">4.000000</span>
+</pre></div>
+</div>
+<p>It works!</p>
+<p>Even with this simple code, we get some surprisingly powerful capabilities -
+check this out:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ready</span><span class="o">></span> <span class="n">extern</span> <span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">extern</span><span class="p">:</span>
+<span class="n">declare</span> <span class="n">double</span> <span class="nd">@sin</span><span class="p">(</span><span class="n">double</span><span class="p">)</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">extern</span> <span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">extern</span><span class="p">:</span>
+<span class="n">declare</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span><span class="p">)</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">sin</span><span class="p">(</span><span class="mf">1.0</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">top</span><span class="o">-</span><span class="n">level</span> <span class="n">expression</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@2</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="mh">0x3FEAED548F090CEE</span>
+<span class="p">}</span>
+
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">0.841471</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">sin</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="o">+</span> <span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="n">cos</span><span class="p">(</span><span class="n">x</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">function</span> <span class="n">definition</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@sin</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">multmp</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span><span class="p">,</span> <span class="o">%</span><span class="n">calltmp</span>
+ <span class="o">%</span><span class="n">calltmp2</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@cos</span><span class="p">(</span><span class="n">double</span> <span class="o">%</span><span class="n">x</span><span class="p">)</span>
+ <span class="o">%</span><span class="n">multmp4</span> <span class="o">=</span> <span class="n">fmul</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp2</span><span class="p">,</span> <span class="o">%</span><span class="n">calltmp2</span>
+ <span class="o">%</span><span class="n">addtmp</span> <span class="o">=</span> <span class="n">fadd</span> <span class="n">double</span> <span class="o">%</span><span class="n">multmp</span><span class="p">,</span> <span class="o">%</span><span class="n">multmp4</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">addtmp</span>
+<span class="p">}</span>
+
+<span class="n">ready</span><span class="o">></span> <span class="n">foo</span><span class="p">(</span><span class="mf">4.0</span><span class="p">);</span>
+<span class="n">Read</span> <span class="n">top</span><span class="o">-</span><span class="n">level</span> <span class="n">expression</span><span class="p">:</span>
+<span class="n">define</span> <span class="n">double</span> <span class="nd">@3</span><span class="p">()</span> <span class="p">{</span>
+<span class="n">entry</span><span class="p">:</span>
+ <span class="o">%</span><span class="n">calltmp</span> <span class="o">=</span> <span class="n">call</span> <span class="n">double</span> <span class="nd">@foo</span><span class="p">(</span><span class="n">double</span> <span class="mf">4.000000e+00</span><span class="p">)</span>
+ <span class="n">ret</span> <span class="n">double</span> <span class="o">%</span><span class="n">calltmp</span>
+<span class="p">}</span>
+
+<span class="n">Evaluated</span> <span class="n">to</span> <span class="mf">1.000000</span>
+</pre></div>
+</div>
+<p>Whoa, how does the JIT know about sin and cos? The answer is surprisingly
+simple: The KaleidoscopeJIT has a straightforward symbol resolution rule that
+it uses to find symbols that arenât available in any given module: First
+it searches all the modules that have already been added to the JIT, from the
+most recent to the oldest, to find the newest definition. If no definition is
+found inside the JIT, it falls back to calling â<code class="docutils literal notranslate"><span class="pre">dlsym("sin")</span></code>â on the
+Kaleidoscope process itself. Since â<code class="docutils literal notranslate"><span class="pre">sin</span></code>â is defined within the JITâs
+address space, it simply patches up calls in the module to call the libm
+version of <code class="docutils literal notranslate"><span class="pre">sin</span></code> directly. But in some cases this even goes further:
+as sin and cos are names of standard math functions, the constant folder
+will directly evaluate the function calls to the correct result when called
+with constants like in the â<code class="docutils literal notranslate"><span class="pre">sin(1.0)</span></code>â above.</p>
+<p>In the future weâll see how tweaking this symbol resolution rule can be used to
+enable all sorts of useful features, from security (restricting the set of
+symbols available to JITâd code), to dynamic code generation based on symbol
+names, and even lazy compilation.</p>
+<p>One immediate benefit of the symbol resolution rule is that we can now extend
+the language by writing arbitrary C++ code to implement operations. For example,
+if we add:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef _WIN32</span>
+<span class="cp">#define DLLEXPORT __declspec(dllexport)</span>
+<span class="cp">#else</span>
+<span class="cp">#define DLLEXPORT</span>
+<span class="cp">#endif</span>
+
+<span class="c1">/// putchard - putchar that takes a double and returns 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fputc</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p>Note, that for Windows we need to actually export the functions because
+the dynamic symbol loader will use GetProcAddress to find the symbols.</p>
+<p>Now we can produce simple output to the console by using things like:
+â<code class="docutils literal notranslate"><span class="pre">extern</span> <span class="pre">putchard(x);</span> <span class="pre">putchard(120);</span></code>â, which prints a lowercase âxâ
+on the console (120 is the ASCII code for âxâ). Similar code could be
+used to implement file I/O, console input, and many other capabilities
+in Kaleidoscope.</p>
+<p>This completes the JIT and optimizer chapter of the Kaleidoscope
+tutorial. At this point, we can compile a non-Turing-complete
+programming language, optimize and JIT compile it in a user-driven way.
+Next up weâll look into <a class="reference external" href="LangImpl05.html">extending the language with control flow
+constructs</a>, tackling some interesting LLVM IR issues
+along the way.</p>
+</div>
+<div class="section" id="full-code-listing">
+<h2><a class="toc-backref" href="#id5">Full Code Listing</a><a class="headerlink" href="#full-code-listing" title="Permalink to this headline">¶</a></h2>
+<p>Here is the complete code listing for our running example, enhanced with
+the LLVM JIT and optimizer. To build this example, use:</p>
+<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span><span class="c1"># Compile</span>
+clang++ -g toy.cpp <span class="sb">`</span>llvm-config --cxxflags --ldflags --system-libs --libs core mcjit native<span class="sb">`</span> -O3 -o toy
+<span class="c1"># Run</span>
+./toy
+</pre></div>
+</div>
+<p>If you are compiling this on Linux, make sure to add the â-rdynamicâ
+option as well. This makes sure that the external functions are resolved
+properly at runtime.</p>
+<p>Here is the code:</p>
+<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">"../include/KaleidoscopeJIT.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/ADT/APFloat.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/ADT/STLExtras.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/BasicBlock.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Constants.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/DerivedTypes.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Function.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/IRBuilder.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LLVMContext.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/LegacyPassManager.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Module.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Type.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/IR/Verifier.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Support/TargetSelect.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Target/TargetMachine.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Transforms/InstCombine/InstCombine.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Transforms/Scalar.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf">"llvm/Transforms/Scalar/GVN.h"</span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><algorithm></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cassert></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cctype></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdint></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdio></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><cstdlib></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><map></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><memory></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><string></span><span class="cp"></span>
+<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
+
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="p">;</span>
+<span class="k">using</span> <span class="k">namespace</span> <span class="n">llvm</span><span class="o">::</span><span class="n">orc</span><span class="p">;</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Lexer</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">// The lexer returns tokens [0-255] if it is an unknown character, otherwise one</span>
+<span class="c1">// of these for known things.</span>
+<span class="k">enum</span> <span class="n">Token</span> <span class="p">{</span>
+ <span class="n">tok_eof</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span>
+
+ <span class="c1">// commands</span>
+ <span class="n">tok_def</span> <span class="o">=</span> <span class="o">-</span><span class="mi">2</span><span class="p">,</span>
+ <span class="n">tok_extern</span> <span class="o">=</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span>
+
+ <span class="c1">// primary</span>
+ <span class="n">tok_identifier</span> <span class="o">=</span> <span class="o">-</span><span class="mi">4</span><span class="p">,</span>
+ <span class="n">tok_number</span> <span class="o">=</span> <span class="o">-</span><span class="mi">5</span>
+<span class="p">};</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdentifierStr</span><span class="p">;</span> <span class="c1">// Filled in if tok_identifier</span>
+<span class="k">static</span> <span class="kt">double</span> <span class="n">NumVal</span><span class="p">;</span> <span class="c1">// Filled in if tok_number</span>
+
+<span class="c1">/// gettok - Return the next token from standard input.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">gettok</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">static</span> <span class="kt">int</span> <span class="n">LastChar</span> <span class="o">=</span> <span class="sc">' '</span><span class="p">;</span>
+
+ <span class="c1">// Skip any whitespace.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isspace</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isalpha</span><span class="p">(</span><span class="n">LastChar</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// identifier: [a-zA-Z][a-zA-Z0-9]*</span>
+ <span class="n">IdentifierStr</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">isalnum</span><span class="p">((</span><span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">())))</span>
+ <span class="n">IdentifierStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"def"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_def</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">IdentifierStr</span> <span class="o">==</span> <span class="s">"extern"</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_extern</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">tok_identifier</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Number: [0-9.]+</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">NumStr</span><span class="p">;</span>
+ <span class="k">do</span> <span class="p">{</span>
+ <span class="n">NumStr</span> <span class="o">+=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">isdigit</span><span class="p">(</span><span class="n">LastChar</span><span class="p">)</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'.'</span><span class="p">);</span>
+
+ <span class="n">NumVal</span> <span class="o">=</span> <span class="n">strtod</span><span class="p">(</span><span class="n">NumStr</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="k">nullptr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">tok_number</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="sc">'#'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// Comment until end of line.</span>
+ <span class="k">do</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\n'</span> <span class="o">&&</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">'\r'</span><span class="p">);</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">!=</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">gettok</span><span class="p">();</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Check for end of file. Don't eat the EOF.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">LastChar</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">tok_eof</span><span class="p">;</span>
+
+ <span class="c1">// Otherwise, just return the character as its ascii value.</span>
+ <span class="kt">int</span> <span class="n">ThisChar</span> <span class="o">=</span> <span class="n">LastChar</span><span class="p">;</span>
+ <span class="n">LastChar</span> <span class="o">=</span> <span class="n">getchar</span><span class="p">();</span>
+ <span class="k">return</span> <span class="n">ThisChar</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Abstract Syntax Tree (aka Parse Tree)</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">namespace</span> <span class="p">{</span>
+
+<span class="c1">/// ExprAST - Base class for all expression nodes.</span>
+<span class="k">class</span> <span class="nc">ExprAST</span> <span class="p">{</span>
+<span class="k">public</span><span class="o">:</span>
+ <span class="k">virtual</span> <span class="o">~</span><span class="n">ExprAST</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
+
+ <span class="k">virtual</span> <span class="n">Value</span> <span class="o">*</span><span class="nf">codegen</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// NumberExprAST - Expression class for numeric literals like "1.0".</span>
+<span class="k">class</span> <span class="nc">NumberExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">double</span> <span class="n">Val</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">NumberExprAST</span><span class="p">(</span><span class="kt">double</span> <span class="n">Val</span><span class="p">)</span> <span class="o">:</span> <span class="n">Val</span><span class="p">(</span><span class="n">Val</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// VariableExprAST - Expression class for referencing a variable, like "a".</span>
+<span class="k">class</span> <span class="nc">VariableExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">VariableExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">)</span> <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">)</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// BinaryExprAST - Expression class for a binary operator.</span>
+<span class="k">class</span> <span class="nc">BinaryExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="kt">char</span> <span class="n">Op</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span> <span class="n">RHS</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">BinaryExprAST</span><span class="p">(</span><span class="kt">char</span> <span class="n">Op</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">RHS</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Op</span><span class="p">(</span><span class="n">Op</span><span class="p">),</span> <span class="n">LHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">)),</span> <span class="n">RHS</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// CallExprAST - Expression class for function calls.</span>
+<span class="k">class</span> <span class="nc">CallExprAST</span> <span class="o">:</span> <span class="k">public</span> <span class="n">ExprAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Callee</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">CallExprAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Callee</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Callee</span><span class="p">(</span><span class="n">Callee</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Value</span> <span class="o">*</span><span class="n">codegen</span><span class="p">()</span> <span class="k">override</span><span class="p">;</span>
+<span class="p">};</span>
+
+<span class="c1">/// PrototypeAST - This class represents the "prototype" for a function,</span>
+<span class="c1">/// which captures its name, and its argument names (thus implicitly the number</span>
+<span class="c1">/// of arguments the function takes).</span>
+<span class="k">class</span> <span class="nc">PrototypeAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">PrototypeAST</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">Name</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">Args</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Name</span><span class="p">(</span><span class="n">Name</span><span class="p">),</span> <span class="n">Args</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&</span><span class="n">getName</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">Name</span><span class="p">;</span> <span class="p">}</span>
+<span class="p">};</span>
+
+<span class="c1">/// FunctionAST - This class represents a function definition itself.</span>
+<span class="k">class</span> <span class="nc">FunctionAST</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">;</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">;</span>
+
+<span class="k">public</span><span class="o">:</span>
+ <span class="n">FunctionAST</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">Proto</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">Body</span><span class="p">)</span>
+ <span class="o">:</span> <span class="n">Proto</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">)),</span> <span class="n">Body</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Body</span><span class="p">))</span> <span class="p">{}</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">codegen</span><span class="p">();</span>
+<span class="p">};</span>
+
+<span class="p">}</span> <span class="c1">// end anonymous namespace</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Parser</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="c1">/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current</span>
+<span class="c1">/// token the parser is looking at. getNextToken reads another token from the</span>
+<span class="c1">/// lexer and updates CurTok with its results.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="n">CurTok</span><span class="p">;</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">getNextToken</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">CurTok</span> <span class="o">=</span> <span class="n">gettok</span><span class="p">();</span> <span class="p">}</span>
+
+<span class="c1">/// BinopPrecedence - This holds the precedence for each binary operator that is</span>
+<span class="c1">/// defined.</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">BinopPrecedence</span><span class="p">;</span>
+
+<span class="c1">/// GetTokPrecedence - Get the precedence of the pending binary operator token.</span>
+<span class="k">static</span> <span class="kt">int</span> <span class="nf">GetTokPrecedence</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">isascii</span><span class="p">(</span><span class="n">CurTok</span><span class="p">))</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+
+ <span class="c1">// Make sure it's a declared binop.</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">BinopPrecedence</span><span class="p">[</span><span class="n">CurTok</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">)</span>
+ <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
+ <span class="k">return</span> <span class="n">TokPrec</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// LogError* - These are little helper functions for error handling.</span>
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LogError</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Error: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">LogErrorP</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">();</span>
+
+<span class="c1">/// numberexpr ::= number</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseNumberExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">Result</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">NumberExprAST</span><span class="o">></span><span class="p">(</span><span class="n">NumVal</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// consume the number</span>
+ <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Result</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="c1">/// parenexpr ::= '(' expression ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseParenExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (.</span>
+ <span class="k">auto</span> <span class="n">V</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"expected ')'"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ).</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// identifierexpr</span>
+<span class="c1">/// ::= identifier</span>
+<span class="c1">/// ::= identifier '(' expression* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseIdentifierExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">IdName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat identifier.</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span> <span class="c1">// Simple variable ref.</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">VariableExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">);</span>
+
+ <span class="c1">// Call.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat (</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">>></span> <span class="n">Args</span><span class="p">;</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">Arg</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="n">Args</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Arg</span><span class="p">));</span>
+ <span class="k">else</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">==</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">break</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">','</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"Expected ')' or ',' in argument list"</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Eat the ')'.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">CallExprAST</span><span class="o">></span><span class="p">(</span><span class="n">IdName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Args</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// primary</span>
+<span class="c1">/// ::= identifierexpr</span>
+<span class="c1">/// ::= numberexpr</span>
+<span class="c1">/// ::= parenexpr</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParsePrimary</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">"unknown token when expecting an expression"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="nl">tok_identifier</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseIdentifierExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="nl">tok_number</span><span class="p">:</span>
+ <span class="k">return</span> <span class="n">ParseNumberExpr</span><span class="p">();</span>
+ <span class="k">case</span> <span class="sc">'('</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">ParseParenExpr</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// binoprhs</span>
+<span class="c1">/// ::= ('+' primary)*</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="kt">int</span> <span class="n">ExprPrec</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">LHS</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// If this is a binop, find its precedence.</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="kt">int</span> <span class="n">TokPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+
+ <span class="c1">// If this is a binop that binds at least as tightly as the current binop,</span>
+ <span class="c1">// consume it, otherwise we are done.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">ExprPrec</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LHS</span><span class="p">;</span>
+
+ <span class="c1">// Okay, we know this is a binop.</span>
+ <span class="kt">int</span> <span class="n">BinOp</span> <span class="o">=</span> <span class="n">CurTok</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat binop</span>
+
+ <span class="c1">// Parse the primary expression after the binary operator.</span>
+ <span class="k">auto</span> <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// If BinOp binds less tightly with RHS than the operator after RHS, let</span>
+ <span class="c1">// the pending operator take RHS as its LHS.</span>
+ <span class="kt">int</span> <span class="n">NextPrec</span> <span class="o">=</span> <span class="n">GetTokPrecedence</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">TokPrec</span> <span class="o"><</span> <span class="n">NextPrec</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">RHS</span> <span class="o">=</span> <span class="n">ParseBinOpRHS</span><span class="p">(</span><span class="n">TokPrec</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">RHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Merge LHS/RHS.</span>
+ <span class="n">LHS</span> <span class="o">=</span>
+ <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">BinaryExprAST</span><span class="o">></span><span class="p">(</span><span class="n">BinOp</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">RHS</span><span class="p">));</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// expression</span>
+<span class="c1">/// ::= primary binoprhs</span>
+<span class="c1">///</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">ExprAST</span><span class="o">></span> <span class="n">ParseExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">auto</span> <span class="n">LHS</span> <span class="o">=</span> <span class="n">ParsePrimary</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">LHS</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">return</span> <span class="nf">ParseBinOpRHS</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">LHS</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// prototype</span>
+<span class="c1">/// ::= id '(' id* ')'</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParsePrototype</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected function name in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">FnName</span> <span class="o">=</span> <span class="n">IdentifierStr</span><span class="p">;</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">'('</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected '(' in prototype"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">ArgNames</span><span class="p">;</span>
+ <span class="k">while</span> <span class="p">(</span><span class="n">getNextToken</span><span class="p">()</span> <span class="o">==</span> <span class="n">tok_identifier</span><span class="p">)</span>
+ <span class="n">ArgNames</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">IdentifierStr</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CurTok</span> <span class="o">!=</span> <span class="sc">')'</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">"Expected ')' in prototype"</span><span class="p">);</span>
+
+ <span class="c1">// success.</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat ')'.</span>
+
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="n">FnName</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ArgNames</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="c1">/// definition ::= 'def' prototype expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat def.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">ParsePrototype</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">Proto</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// toplevelexpr ::= expression</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span> <span class="n">ParseTopLevelExpr</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">E</span> <span class="o">=</span> <span class="n">ParseExpression</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Make an anonymous proto.</span>
+ <span class="k">auto</span> <span class="n">Proto</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">,</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span><span class="p">());</span>
+ <span class="k">return</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">FunctionAST</span><span class="o">></span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">E</span><span class="p">));</span>
+ <span class="p">}</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// external ::= 'extern' prototype</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">></span> <span class="n">ParseExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat extern.</span>
+ <span class="k">return</span> <span class="nf">ParsePrototype</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Code Generation</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="n">LLVMContext</span> <span class="n">TheContext</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">IRBuilder</span><span class="o"><></span> <span class="n">Builder</span><span class="p">(</span><span class="n">TheContext</span><span class="p">);</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">Module</span><span class="o">></span> <span class="n">TheModule</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">Value</span> <span class="o">*></span> <span class="n">NamedValues</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">legacy</span><span class="o">::</span><span class="n">FunctionPassManager</span><span class="o">></span> <span class="n">TheFPM</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span> <span class="n">TheJIT</span><span class="p">;</span>
+<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">map</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">PrototypeAST</span><span class="o">>></span> <span class="n">FunctionProtos</span><span class="p">;</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="nf">LogErrorV</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">Str</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">LogError</span><span class="p">(</span><span class="n">Str</span><span class="p">);</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="nf">getFunction</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">Name</span><span class="p">)</span> <span class="p">{</span>
+ <span class="c1">// First, see if the function has already been added to the current module.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span> <span class="n">TheModule</span><span class="o">-></span><span class="n">getFunction</span><span class="p">(</span><span class="n">Name</span><span class="p">))</span>
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+
+ <span class="c1">// If not, check whether we can codegen the declaration from some existing</span>
+ <span class="c1">// prototype.</span>
+ <span class="k">auto</span> <span class="n">FI</span> <span class="o">=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">Name</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FI</span> <span class="o">!=</span> <span class="n">FunctionProtos</span><span class="p">.</span><span class="n">end</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">FI</span><span class="o">-></span><span class="n">second</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+
+ <span class="c1">// If no existing prototype exists, return null.</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">NumberExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">return</span> <span class="n">ConstantFP</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="n">APFloat</span><span class="p">(</span><span class="n">Val</span><span class="p">));</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">VariableExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look this variable up in the function.</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">V</span> <span class="o">=</span> <span class="n">NamedValues</span><span class="p">[</span><span class="n">Name</span><span class="p">];</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">V</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown variable name"</span><span class="p">);</span>
+ <span class="k">return</span> <span class="n">V</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">BinaryExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">L</span> <span class="o">=</span> <span class="n">LHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="n">Value</span> <span class="o">*</span><span class="n">R</span> <span class="o">=</span> <span class="n">RHS</span><span class="o">-></span><span class="n">codegen</span><span class="p">();</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">L</span> <span class="o">||</span> <span class="o">!</span><span class="n">R</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="k">switch</span> <span class="p">(</span><span class="n">Op</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="sc">'+'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFAdd</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"addtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'-'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFSub</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"subtmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'*'</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFMul</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"multmp"</span><span class="p">);</span>
+ <span class="k">case</span> <span class="sc">'<'</span><span class="o">:</span>
+ <span class="n">L</span> <span class="o">=</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateFCmpULT</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="s">"cmptmp"</span><span class="p">);</span>
+ <span class="c1">// Convert bool 0/1 to double 0.0 or 1.0</span>
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateUIToFP</span><span class="p">(</span><span class="n">L</span><span class="p">,</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="s">"booltmp"</span><span class="p">);</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"invalid binary operator"</span><span class="p">);</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="n">Value</span> <span class="o">*</span><span class="n">CallExprAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Look up the name in the global module table.</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">CalleeF</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">Callee</span><span class="p">);</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CalleeF</span><span class="p">)</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Unknown function referenced"</span><span class="p">);</span>
+
+ <span class="c1">// If argument mismatch error.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">CalleeF</span><span class="o">-></span><span class="n">arg_size</span><span class="p">()</span> <span class="o">!=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">())</span>
+ <span class="k">return</span> <span class="n">LogErrorV</span><span class="p">(</span><span class="s">"Incorrect # arguments passed"</span><span class="p">);</span>
+
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Value</span> <span class="o">*></span> <span class="n">ArgsV</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">e</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">ArgsV</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">codegen</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ArgsV</span><span class="p">.</span><span class="n">back</span><span class="p">())</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="k">return</span> <span class="n">Builder</span><span class="p">.</span><span class="n">CreateCall</span><span class="p">(</span><span class="n">CalleeF</span><span class="p">,</span> <span class="n">ArgsV</span><span class="p">,</span> <span class="s">"calltmp"</span><span class="p">);</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">PrototypeAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Make the function type: double(double,double) etc.</span>
+ <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">Type</span> <span class="o">*></span> <span class="n">Doubles</span><span class="p">(</span><span class="n">Args</span><span class="p">.</span><span class="n">size</span><span class="p">(),</span> <span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">));</span>
+ <span class="n">FunctionType</span> <span class="o">*</span><span class="n">FT</span> <span class="o">=</span>
+ <span class="n">FunctionType</span><span class="o">::</span><span class="n">get</span><span class="p">(</span><span class="n">Type</span><span class="o">::</span><span class="n">getDoubleTy</span><span class="p">(</span><span class="n">TheContext</span><span class="p">),</span> <span class="n">Doubles</span><span class="p">,</span> <span class="nb">false</span><span class="p">);</span>
+
+ <span class="n">Function</span> <span class="o">*</span><span class="n">F</span> <span class="o">=</span>
+ <span class="n">Function</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">FT</span><span class="p">,</span> <span class="n">Function</span><span class="o">::</span><span class="n">ExternalLinkage</span><span class="p">,</span> <span class="n">Name</span><span class="p">,</span> <span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Set names for all arguments.</span>
+ <span class="kt">unsigned</span> <span class="n">Idx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">Arg</span><span class="p">.</span><span class="n">setName</span><span class="p">(</span><span class="n">Args</span><span class="p">[</span><span class="n">Idx</span><span class="o">++</span><span class="p">]);</span>
+
+ <span class="k">return</span> <span class="n">F</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="n">Function</span> <span class="o">*</span><span class="n">FunctionAST</span><span class="o">::</span><span class="n">codegen</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Transfer ownership of the prototype to the FunctionProtos map, but keep a</span>
+ <span class="c1">// reference to it for use below.</span>
+ <span class="k">auto</span> <span class="o">&</span><span class="n">P</span> <span class="o">=</span> <span class="o">*</span><span class="n">Proto</span><span class="p">;</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">Proto</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">Proto</span><span class="p">);</span>
+ <span class="n">Function</span> <span class="o">*</span><span class="n">TheFunction</span> <span class="o">=</span> <span class="n">getFunction</span><span class="p">(</span><span class="n">P</span><span class="p">.</span><span class="n">getName</span><span class="p">());</span>
+ <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">TheFunction</span><span class="p">)</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+
+ <span class="c1">// Create a new basic block to start insertion into.</span>
+ <span class="n">BasicBlock</span> <span class="o">*</span><span class="n">BB</span> <span class="o">=</span> <span class="n">BasicBlock</span><span class="o">::</span><span class="n">Create</span><span class="p">(</span><span class="n">TheContext</span><span class="p">,</span> <span class="s">"entry"</span><span class="p">,</span> <span class="n">TheFunction</span><span class="p">);</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">SetInsertPoint</span><span class="p">(</span><span class="n">BB</span><span class="p">);</span>
+
+ <span class="c1">// Record the function arguments in the NamedValues map.</span>
+ <span class="n">NamedValues</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
+ <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-></span><span class="n">args</span><span class="p">())</span>
+ <span class="n">NamedValues</span><span class="p">[</span><span class="n">Arg</span><span class="p">.</span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="o">&</span><span class="n">Arg</span><span class="p">;</span>
+
+ <span class="k">if</span> <span class="p">(</span><span class="n">Value</span> <span class="o">*</span><span class="n">RetVal</span> <span class="o">=</span> <span class="n">Body</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// Finish off the function.</span>
+ <span class="n">Builder</span><span class="p">.</span><span class="n">CreateRet</span><span class="p">(</span><span class="n">RetVal</span><span class="p">);</span>
+
+ <span class="c1">// Validate the generated code, checking for consistency.</span>
+ <span class="n">verifyFunction</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="c1">// Run the optimizer on the function.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">run</span><span class="p">(</span><span class="o">*</span><span class="n">TheFunction</span><span class="p">);</span>
+
+ <span class="k">return</span> <span class="n">TheFunction</span><span class="p">;</span>
+ <span class="p">}</span>
+
+ <span class="c1">// Error reading body, remove function.</span>
+ <span class="n">TheFunction</span><span class="o">-></span><span class="n">eraseFromParent</span><span class="p">();</span>
+ <span class="k">return</span> <span class="k">nullptr</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Top-Level parsing and JIT Driver</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">InitializeModuleAndPassManager</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Open a new module.</span>
+ <span class="n">TheModule</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">Module</span><span class="o">></span><span class="p">(</span><span class="s">"my cool jit"</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
+ <span class="n">TheModule</span><span class="o">-></span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TheJIT</span><span class="o">-></span><span class="n">getTargetMachine</span><span class="p">().</span><span class="n">createDataLayout</span><span class="p">());</span>
+
+ <span class="c1">// Create a new pass manager attached to it.</span>
+ <span class="n">TheFPM</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">legacy</span><span class="o">::</span><span class="n">FunctionPassManager</span><span class="o">></span><span class="p">(</span><span class="n">TheModule</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
+
+ <span class="c1">// Do simple "peephole" optimizations and bit-twiddling optzns.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createInstructionCombiningPass</span><span class="p">());</span>
+ <span class="c1">// Reassociate expressions.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createReassociatePass</span><span class="p">());</span>
+ <span class="c1">// Eliminate Common SubExpressions.</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createGVNPass</span><span class="p">());</span>
+ <span class="c1">// Simplify the control flow graph (deleting unreachable blocks, etc).</span>
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">add</span><span class="p">(</span><span class="n">createCFGSimplificationPass</span><span class="p">());</span>
+
+ <span class="n">TheFPM</span><span class="o">-></span><span class="n">doInitialization</span><span class="p">();</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleDefinition</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseDefinition</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read function definition:"</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="n">TheJIT</span><span class="o">-></span><span class="n">addModule</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">TheModule</span><span class="p">));</span>
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleExtern</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">ProtoAST</span> <span class="o">=</span> <span class="n">ParseExtern</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="o">*</span><span class="n">FnIR</span> <span class="o">=</span> <span class="n">ProtoAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Read extern: "</span><span class="p">);</span>
+ <span class="n">FnIR</span><span class="o">-></span><span class="n">print</span><span class="p">(</span><span class="n">errs</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
+ <span class="n">FunctionProtos</span><span class="p">[</span><span class="n">ProtoAST</span><span class="o">-></span><span class="n">getName</span><span class="p">()]</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">ProtoAST</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="k">static</span> <span class="kt">void</span> <span class="n">HandleTopLevelExpression</span><span class="p">()</span> <span class="p">{</span>
+ <span class="c1">// Evaluate a top-level expression into an anonymous function.</span>
+ <span class="k">if</span> <span class="p">(</span><span class="k">auto</span> <span class="n">FnAST</span> <span class="o">=</span> <span class="n">ParseTopLevelExpr</span><span class="p">())</span> <span class="p">{</span>
+ <span class="k">if</span> <span class="p">(</span><span class="n">FnAST</span><span class="o">-></span><span class="n">codegen</span><span class="p">())</span> <span class="p">{</span>
+ <span class="c1">// JIT the module containing the anonymous expression, keeping a handle so</span>
+ <span class="c1">// we can free it later.</span>
+ <span class="k">auto</span> <span class="n">H</span> <span class="o">=</span> <span class="n">TheJIT</span><span class="o">-></span><span class="n">addModule</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">TheModule</span><span class="p">));</span>
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+
+ <span class="c1">// Search the JIT for the __anon_expr symbol.</span>
+ <span class="k">auto</span> <span class="n">ExprSymbol</span> <span class="o">=</span> <span class="n">TheJIT</span><span class="o">-></span><span class="n">findSymbol</span><span class="p">(</span><span class="s">"__anon_expr"</span><span class="p">);</span>
+ <span class="n">assert</span><span class="p">(</span><span class="n">ExprSymbol</span> <span class="o">&&</span> <span class="s">"Function not found"</span><span class="p">);</span>
+
+ <span class="c1">// Get the symbol's address and cast it to the right type (takes no</span>
+ <span class="c1">// arguments, returns a double) so we can call it as a native function.</span>
+ <span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="n">FP</span><span class="p">)()</span> <span class="o">=</span> <span class="p">(</span><span class="kt">double</span> <span class="p">(</span><span class="o">*</span><span class="p">)())(</span><span class="kt">intptr_t</span><span class="p">)</span><span class="n">cantFail</span><span class="p">(</span><span class="n">ExprSymbol</span><span class="p">.</span><span class="n">getAddress</span><span class="p">());</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"Evaluated to %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">FP</span><span class="p">());</span>
+
+ <span class="c1">// Delete the anonymous expression module from the JIT.</span>
+ <span class="n">TheJIT</span><span class="o">-></span><span class="n">removeModule</span><span class="p">(</span><span class="n">H</span><span class="p">);</span>
+ <span class="p">}</span>
+ <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
+ <span class="c1">// Skip token for error recovery.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">/// top ::= definition | external | expression | ';'</span>
+<span class="k">static</span> <span class="kt">void</span> <span class="n">MainLoop</span><span class="p">()</span> <span class="p">{</span>
+ <span class="k">while</span> <span class="p">(</span><span class="nb">true</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="k">switch</span> <span class="p">(</span><span class="n">CurTok</span><span class="p">)</span> <span class="p">{</span>
+ <span class="k">case</span> <span class="nl">tok_eof</span><span class="p">:</span>
+ <span class="k">return</span><span class="p">;</span>
+ <span class="k">case</span> <span class="sc">';'</span><span class="o">:</span> <span class="c1">// ignore top-level semicolons.</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_def</span><span class="p">:</span>
+ <span class="n">HandleDefinition</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">case</span> <span class="nl">tok_extern</span><span class="p">:</span>
+ <span class="n">HandleExtern</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="k">default</span><span class="o">:</span>
+ <span class="n">HandleTopLevelExpression</span><span class="p">();</span>
+ <span class="k">break</span><span class="p">;</span>
+ <span class="p">}</span>
+ <span class="p">}</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// "Library" functions that can be "extern'd" from user code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="cp">#ifdef _WIN32</span>
+<span class="cp">#define DLLEXPORT __declspec(dllexport)</span>
+<span class="cp">#else</span>
+<span class="cp">#define DLLEXPORT</span>
+<span class="cp">#endif</span>
+
+<span class="c1">/// putchard - putchar that takes a double and returns 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">putchard</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fputc</span><span class="p">((</span><span class="kt">char</span><span class="p">)</span><span class="n">X</span><span class="p">,</span> <span class="n">stderr</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">/// printd - printf that takes a double prints it as "%f\n", returning 0.</span>
+<span class="k">extern</span> <span class="s">"C"</span> <span class="n">DLLEXPORT</span> <span class="kt">double</span> <span class="n">printd</span><span class="p">(</span><span class="kt">double</span> <span class="n">X</span><span class="p">)</span> <span class="p">{</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">X</span><span class="p">);</span>
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+<span class="c1">// Main driver code.</span>
+<span class="c1">//===----------------------------------------------------------------------===//</span>
+
+<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
+ <span class="n">InitializeNativeTarget</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmPrinter</span><span class="p">();</span>
+ <span class="n">InitializeNativeTargetAsmParser</span><span class="p">();</span>
+
+ <span class="c1">// Install standard binary operators.</span>
+ <span class="c1">// 1 is lowest precedence.</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'<'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'+'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'-'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
+ <span class="n">BinopPrecedence</span><span class="p">[</span><span class="sc">'*'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">40</span><span class="p">;</span> <span class="c1">// highest.</span>
+
+ <span class="c1">// Prime the first token.</span>
+ <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"ready> "</span><span class="p">);</span>
+ <span class="n">getNextToken</span><span class="p">();</span>
+
+ <span class="n">TheJIT</span> <span class="o">=</span> <span class="n">llvm</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">KaleidoscopeJIT</span><span class="o">></span><span class="p">();</span>
+
+ <span class="n">InitializeModuleAndPassManager</span><span class="p">();</span>
+
+ <span class="c1">// Run the main "interpreter loop" now.</span>
+ <span class="n">MainLoop</span><span class="p">();</span>
+
+ <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
+<span class="p">}</span>
+</pre></div>
+</div>
+<p><a class="reference external" href="LangImpl05.html">Next: Extending the language: control flow</a></p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related" role="navigation" aria-label="related navigation">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="../../genindex.html" title="General Index"
+ >index</a></li>
+ <li><a href="http://llvm.org/">LLVM Home</a> | </li>
+ <li><a href="../../index.html">Documentation</a>»</li>
+
+ </ul>
+ </div>
+ <div class="footer" role="contentinfo">
+ © Copyright 2003-2019, LLVM Project.
+ Last updated on 2019-07-10.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.6.
+ </div>
+ </body>
+</html>
\ No newline at end of file
More information about the llvm-commits
mailing list