Sophie

Sophie

distrib > Mageia > 7 > i586 > media > core-updates > by-pkgid > d635a8cd705396ade48f1d2b830a115d > files > 2609

libllvm-devel-8.0.0-1.1.mga7.i586.rpm



<!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 &#8212; 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>
    <script type="text/javascript" src="../_static/language_data.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>&nbsp;|&nbsp;</li>
  <li><a href="../index.html">Documentation</a>&raquo;</li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">LLVM Tutorial: Table of Contents</a> &#187;</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">&lt;</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&lt;PrototypeAST&gt;(&quot;&quot;, std::vector&lt;std::string&gt;());</span>
<span class="gi">+    auto Proto = llvm::make_unique&lt;PrototypeAST&gt;(&quot;main&quot;, std::vector&lt;std::string&gt;());</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 | &#39;;&#39;
 static void MainLoop() {
   while (1) {
<span class="gd">-    fprintf(stderr, &quot;ready&gt; &quot;);</span>
     switch (CurTok) {
     case tok_eof:
       return;
<span class="gu">@@ -1184,7 +1183,6 @@ int main() {</span>
   BinopPrecedence[&#39;*&#39;] = 40; // highest.

   // Prime the first token.
<span class="gd">-  fprintf(stderr, &quot;ready&gt; &quot;);</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-&gt;codegen()) {</span>
<span class="gd">-      // We&#39;re just doing this to make sure it executes.</span>
<span class="gd">-      TheExecutionEngine-&gt;finalizeObject();</span>
<span class="gd">-      // JIT the function, returning a function pointer.</span>
<span class="gd">-      void *FPtr = TheExecutionEngine-&gt;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-&gt;codegen()) {</span>
<span class="gi">+      fprintf(stderr, &quot;Error generating code for top level expr&quot;);</span>
     }
   } else {
     // Skip token for error recovery.
<span class="gu">@@ -1439,11 +1459,11 @@ int main() {</span>
   // target lays out data structures.
   TheModule-&gt;setDataLayout(TheExecutionEngine-&gt;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 &lt; fib.ks <span class="p">|</span> <span class="p">&amp;</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">-&gt;</span><span class="n">createBasicType</span><span class="p">(</span><span class="s">&quot;double&quot;</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">-&gt;</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">-&gt;</span><span class="n">createFile</span><span class="p">(</span><span class="s">&quot;fib.ks&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">),</span>
    <span class="s">&quot;Kaleidoscope Compiler&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;&quot;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&#39;\n&#39;</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">&#39;\r&#39;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="sc">&#39;:&#39;</span> <span class="o">&lt;&lt;</span> <span class="n">getLine</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;:&#39;</span> <span class="o">&lt;&lt;</span> <span class="n">getCol</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</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">&lt;</span><span class="n">BinaryExprAST</span><span class="o">&gt;</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">-&gt;</span><span class="n">getLine</span><span class="p">(),</span> <span class="n">AST</span><span class="o">-&gt;</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">&lt;</span><span class="n">DIScope</span> <span class="o">*&gt;</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">&amp;</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">&quot;llvm/ADT/STLExtras.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/Analysis/BasicAliasAnalysis.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/Analysis/Passes.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/DIBuilder.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/IRBuilder.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/LLVMContext.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/LegacyPassManager.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/Module.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/IR/Verifier.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/Support/TargetSelect.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;llvm/Transforms/Scalar.h&quot;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;cctype&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;cstdio&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;map&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;../include/KaleidoscopeJIT.h&quot;</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">&quot;eof&quot;</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">&quot;def&quot;</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">&quot;extern&quot;</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">&quot;identifier&quot;</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">&quot;number&quot;</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">&quot;if&quot;</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">&quot;then&quot;</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">&quot;else&quot;</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">&quot;for&quot;</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">&quot;in&quot;</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">&quot;binary&quot;</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">&quot;unary&quot;</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">&quot;var&quot;</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">&lt;&gt;</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">&lt;</span><span class="n">DIScope</span> <span class="o">*&gt;</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">&#39;\n&#39;</span> <span class="o">||</span> <span class="n">LastChar</span> <span class="o">==</span> <span class="sc">&#39;\r&#39;</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">&#39; &#39;</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">&quot;def&quot;</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">&quot;extern&quot;</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">&quot;if&quot;</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">&quot;then&quot;</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">&quot;else&quot;</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">&quot;for&quot;</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">&quot;in&quot;</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">&quot;binary&quot;</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">&quot;unary&quot;</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">&quot;var&quot;</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">&#39;.&#39;</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">&#39;.&#39;</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">&#39;#&#39;</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">&amp;&amp;</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">&#39;\n&#39;</span> <span class="o">&amp;&amp;</span> <span class="n">LastChar</span> <span class="o">!=</span> <span class="sc">&#39;\r&#39;</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&#39;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">&amp;</span><span class="n">indent</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</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">&#39; &#39;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="sc">&#39;:&#39;</span> <span class="o">&lt;&lt;</span> <span class="n">getLine</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;:&#39;</span> <span class="o">&lt;&lt;</span> <span class="n">getCol</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;\n&#39;</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">};</span>

<span class="c1">/// NumberExprAST - Expression class for numeric literals like &quot;1.0&quot;.</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</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 &quot;a&quot;.</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">&amp;</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">&amp;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;unary&quot;</span> <span class="o">&lt;&lt;</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">-&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;binary&quot;</span> <span class="o">&lt;&lt;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;LHS:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;RHS:&quot;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;</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">&amp;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;call &quot;</span> <span class="o">&lt;&lt;</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">&amp;</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">-&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;if&quot;</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
    <span class="n">Cond</span><span class="o">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Cond:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Then:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Else:&quot;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;for&quot;</span><span class="p">,</span> <span class="n">ind</span><span class="p">);</span>
    <span class="n">Start</span><span class="o">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Cond:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;End:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Step:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Body:&quot;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;var&quot;</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">&amp;</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">-&gt;</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">&lt;&lt;</span> <span class="n">NamedVar</span><span class="p">.</span><span class="n">first</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39;:&#39;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;Body:&quot;</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 &quot;prototype&quot; 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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&amp;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&amp;</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">&amp;&amp;</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">&amp;&amp;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&amp;</span><span class="n">dump</span><span class="p">(</span><span class="n">raw_ostream</span> <span class="o">&amp;</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">&lt;&lt;</span> <span class="s">&quot;FunctionAST</span><span class="se">\n</span><span class="s">&quot;</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">&lt;&lt;</span> <span class="s">&quot;Body:&quot;</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">-&gt;</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">&lt;&lt;</span> <span class="s">&quot;null</span><span class="se">\n</span><span class="s">&quot;</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">&lt;</span><span class="kt">char</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</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&#39;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">&lt;=</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&quot;Error: %s</span><span class="se">\n</span><span class="s">&quot;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">NumberExprAST</span><span class="o">&gt;</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 ::= &#39;(&#39; expression &#39;)&#39;</span>
<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&#39;)&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">&quot;expected &#39;)&#39;&quot;</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 &#39;(&#39; expression* &#39;)&#39;</span>
<span class="k">static</span> <span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&#39;(&#39;</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">&lt;</span><span class="n">VariableExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;</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">&#39;)&#39;</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">&#39;)&#39;</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">&#39;,&#39;</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">&quot;Expected &#39;)&#39; or &#39;,&#39; in argument list&quot;</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 &#39;)&#39;.</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">&lt;</span><span class="n">CallExprAST</span><span class="o">&gt;</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 ::= &#39;if&#39; expression &#39;then&#39; expression &#39;else&#39; 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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&quot;expected then&quot;</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">&quot;expected else&quot;</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">&lt;</span><span class="n">IfExprAST</span><span class="o">&gt;</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 ::= &#39;for&#39; identifier &#39;=&#39; expr &#39;,&#39; expr (&#39;,&#39; expr)? &#39;in&#39; 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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&quot;expected identifier after for&quot;</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">&#39;=&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">&quot;expected &#39;=&#39; after for&quot;</span><span class="p">);</span>
  <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat &#39;=&#39;.</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">&#39;,&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">LogError</span><span class="p">(</span><span class="s">&quot;expected &#39;,&#39; after for start value&quot;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&#39;,&#39;</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">&quot;expected &#39;in&#39; after for&quot;</span><span class="p">);</span>
  <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat &#39;in&#39;.</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">&lt;</span><span class="n">ForExprAST</span><span class="o">&gt;</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 ::= &#39;var&#39; identifier (&#39;=&#39; expression)?</span>
<span class="c1">//                    (&#39;,&#39; identifier (&#39;=&#39; expression)?)* &#39;in&#39; 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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">pair</span><span class="o">&lt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;&gt;&gt;</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">&quot;expected identifier after var&quot;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&#39;=&#39;</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat the &#39;=&#39;.</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">&#39;,&#39;</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 &#39;,&#39;.</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">&quot;expected identifier list after var&quot;</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="c1">// At this point, we have to have &#39;in&#39;.</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">&quot;expected &#39;in&#39; keyword after &#39;var&#39;&quot;</span><span class="p">);</span>
  <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat &#39;in&#39;.</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">&lt;</span><span class="n">VarExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&quot;unknown token when expecting an expression&quot;</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">&#39;(&#39;</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">///   ::= &#39;!&#39; 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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&#39;(&#39;</span> <span class="o">||</span> <span class="n">CurTok</span> <span class="o">==</span> <span class="sc">&#39;,&#39;</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">&lt;</span><span class="n">UnaryExprAST</span><span class="o">&gt;</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">///   ::= (&#39;+&#39; 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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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">&lt;</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">&lt;</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">&lt;</span><span class="n">BinaryExprAST</span><span class="o">&gt;</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">&lt;</span><span class="n">ExprAST</span><span class="o">&gt;</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 &#39;(&#39; id* &#39;)&#39;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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">&quot;Expected function name in prototype&quot;</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">&quot;Expected unary operator&quot;</span><span class="p">);</span>
    <span class="n">FnName</span> <span class="o">=</span> <span class="s">&quot;unary&quot;</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">&quot;Expected binary operator&quot;</span><span class="p">);</span>
    <span class="n">FnName</span> <span class="o">=</span> <span class="s">&quot;binary&quot;</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">&lt;</span> <span class="mi">1</span> <span class="o">||</span> <span class="n">NumVal</span> <span class="o">&gt;</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">&quot;Invalid precedence: must be 1..100&quot;</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">&#39;(&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">&quot;Expected &#39;(&#39; in prototype&quot;</span><span class="p">);</span>

  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&#39;)&#39;</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">LogErrorP</span><span class="p">(</span><span class="s">&quot;Expected &#39;)&#39; in prototype&quot;</span><span class="p">);</span>

  <span class="c1">// success.</span>
  <span class="n">getNextToken</span><span class="p">();</span> <span class="c1">// eat &#39;)&#39;.</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">&amp;&amp;</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">&quot;Invalid number of operands for operator&quot;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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 ::= &#39;def&#39; 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">&lt;</span><span class="n">FunctionAST</span><span class="o">&gt;</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">&lt;</span><span class="n">FunctionAST</span><span class="o">&gt;</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">&lt;</span><span class="n">FunctionAST</span><span class="o">&gt;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</span><span class="p">(</span><span class="n">FnLoc</span><span class="p">,</span> <span class="s">&quot;__anon_expr&quot;</span><span class="p">,</span>
                                                 <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;</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">&lt;</span><span class="n">FunctionAST</span><span class="o">&gt;</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 ::= &#39;extern&#39; 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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;</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">&lt;</span><span class="n">DIBuilder</span><span class="o">&gt;</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">-&gt;</span><span class="n">createBasicType</span><span class="p">(</span><span class="s">&quot;double&quot;</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">-&gt;</span><span class="n">getLine</span><span class="p">(),</span> <span class="n">AST</span><span class="o">-&gt;</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">&lt;</span><span class="n">Metadata</span> <span class="o">*</span><span class="p">,</span> <span class="mi">8</span><span class="o">&gt;</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">-&gt;</span><span class="n">createSubroutineType</span><span class="p">(</span><span class="n">DBuilder</span><span class="o">-&gt;</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">&lt;</span><span class="n">Module</span><span class="o">&gt;</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">&lt;</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">*&gt;</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">&lt;</span><span class="n">KaleidoscopeJIT</span><span class="o">&gt;</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">&lt;</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">&lt;</span><span class="n">PrototypeAST</span><span class="o">&gt;&gt;</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">-&gt;</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">-&gt;</span><span class="n">second</span><span class="o">-&gt;</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">&amp;</span><span class="n">VarName</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">IRBuilder</span><span class="o">&lt;&gt;</span> <span class="n">TmpB</span><span class="p">(</span><span class="o">&amp;</span><span class="n">TheFunction</span><span class="o">-&gt;</span><span class="n">getEntryBlock</span><span class="p">(),</span>
                   <span class="n">TheFunction</span><span class="o">-&gt;</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">&quot;Unknown variable name&quot;</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">-&gt;</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">&quot;unary&quot;</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">&quot;Unknown unary operator&quot;</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">&quot;unop&quot;</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 &#39;=&#39; because we don&#39;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">&#39;=&#39;</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&#39;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">&lt;</span><span class="n">VariableExprAST</span> <span class="o">*&gt;</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">&quot;destination of &#39;=&#39; must be a variable&quot;</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">-&gt;</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">-&gt;</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">&quot;Unknown variable name&quot;</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">-&gt;</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">-&gt;</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">&#39;+&#39;</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">&quot;addtmp&quot;</span><span class="p">);</span>
  <span class="k">case</span> <span class="sc">&#39;-&#39;</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">&quot;subtmp&quot;</span><span class="p">);</span>
  <span class="k">case</span> <span class="sc">&#39;*&#39;</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">&quot;multmp&quot;</span><span class="p">);</span>
  <span class="k">case</span> <span class="sc">&#39;&lt;&#39;</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">&quot;cmptmp&quot;</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">&quot;booltmp&quot;</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&#39;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">&quot;binary&quot;</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">&amp;&amp;</span> <span class="s">&quot;binary operator not found!&quot;</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">&quot;binop&quot;</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">&quot;Unknown function referenced&quot;</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">-&gt;</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">&quot;Incorrect # arguments passed&quot;</span><span class="p">);</span>

  <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Value</span> <span class="o">*&gt;</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">-&gt;</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">&quot;calltmp&quot;</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">-&gt;</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">&quot;ifcond&quot;</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">-&gt;</span><span class="n">getParent</span><span class="p">();</span>

  <span class="c1">// Create blocks for the then and else cases.  Insert the &#39;then&#39; 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">&quot;then&quot;</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">&quot;else&quot;</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">&quot;ifcont&quot;</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">-&gt;</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 &#39;Then&#39; 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">-&gt;</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">-&gt;</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 &#39;Else&#39; 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">-&gt;</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">&quot;iftmp&quot;</span><span class="p">);</span>

  <span class="n">PN</span><span class="o">-&gt;</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">-&gt;</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 -&gt; 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 -&gt; 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">-&gt;</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 &#39;variable&#39; 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">-&gt;</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">&quot;loop&quot;</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&#39;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">-&gt;</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">-&gt;</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">-&gt;</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">&quot;nextvar&quot;</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">&quot;loopcond&quot;</span><span class="p">);</span>

  <span class="c1">// Create the &quot;after loop&quot; 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">&quot;afterloop&quot;</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">&lt;</span><span class="n">AllocaInst</span> <span class="o">*&gt;</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">-&gt;</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">&amp;</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 &#39;a&#39;.</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">-&gt;</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">-&gt;</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">&lt;</span><span class="n">Type</span> <span class="o">*&gt;</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">&amp;</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">F</span><span class="o">-&gt;</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">&amp;</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">-&gt;</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">&quot;entry&quot;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</span><span class="nl">Arg</span> <span class="p">:</span> <span class="n">TheFunction</span><span class="o">-&gt;</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">-&gt;</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">-&gt;</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">-&gt;</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">&amp;</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">-&gt;</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">-&gt;</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">-&gt;</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">&lt;</span><span class="n">Module</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&quot;my cool jit&quot;</span><span class="p">,</span> <span class="n">TheContext</span><span class="p">);</span>
  <span class="n">TheModule</span><span class="o">-&gt;</span><span class="n">setDataLayout</span><span class="p">(</span><span class="n">TheJIT</span><span class="o">-&gt;</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">-&gt;</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">&quot;Error reading function definition:&quot;</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">-&gt;</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">&quot;Error reading extern&quot;</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">-&gt;</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">-&gt;</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">&quot;Error generating code for top level expr&quot;</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 | &#39;;&#39;</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">&#39;;&#39;</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">// &quot;Library&quot; functions that can be &quot;extern&#39;d&quot; 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">&quot;C&quot;</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 &quot;%f\n&quot;, returning 0.</span>
<span class="k">extern</span> <span class="s">&quot;C&quot;</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">&quot;%f</span><span class="se">\n</span><span class="s">&quot;</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">&#39;=&#39;</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">&#39;&lt;&#39;</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">&#39;+&#39;</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">&#39;-&#39;</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">&#39;*&#39;</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">&lt;</span><span class="n">KaleidoscopeJIT</span><span class="o">&gt;</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">-&gt;</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">&quot;Debug Info Version&quot;</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">-&gt;</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">&quot;Dwarf Version&quot;</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">&lt;</span><span class="n">DIBuilder</span><span class="o">&gt;</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 &quot;fib.ks&quot; as a filename since we&#39;re redirecting stdin</span>
  <span class="c1">// but we&#39;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">-&gt;</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">-&gt;</span><span class="n">createFile</span><span class="p">(</span><span class="s">&quot;fib.ks&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">),</span>
      <span class="s">&quot;Kaleidoscope Compiler&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

  <span class="c1">// Run the main &quot;interpreter loop&quot; 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">-&gt;</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">-&gt;</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>&nbsp;|&nbsp;</li>
  <li><a href="../index.html">Documentation</a>&raquo;</li>

          <li class="nav-item nav-item-1"><a href="index.html" >LLVM Tutorial: Table of Contents</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
        &#169; Copyright 2003-2020, LLVM Project.
      Last updated on 2020-09-07.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.8.4.
    </div>
  </body>
</html>