diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html
index ccd15dc..6664c7c 100644
--- a/docs/tutorial/LangImpl7.html
+++ b/docs/tutorial/LangImpl7.html
@@ -296,8 +296,664 @@
 running, and is very simple to implement.  Lets extend Kaleidoscope with mutable
 variables now!
 </p>
+
 </div>
 
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="kalvars">Mutable Variables in 
+Kaleidoscope</a></div>
+<!-- *********************************************************************** -->
+
+<div class="doc_text">
+
+<p>Now that we know the sort of problem we want to tackle, lets see what this
+looks like in the context of our little Kaleidoscope language.  We're going to
+add two features:</p>
+
+<ol>
+<li>The ability to mutate variables with the '=' operator.</li>
+<li>The ability to define new variables.</li>
+</ol>
+
+<p>While the first item is really what this is about, we only have variables
+for incoming arguments and for induction variables, and redefining them only
+goes so far :).  Also, the ability to define new variables is a
+useful thing regardless of whether you will be mutating them.  Here's a
+motivating example that shows how we could use these:</p>
+
+<div class="doc_code">
+<pre>
+# Define ':' for sequencing: as a low-precedence operator that ignores operands
+# and just returns the RHS.
+def binary : 1 (x y) y;
+
+# Recursive fib, we could do this before.
+def fib(x)
+  if (x &lt; 3) then
+    1
+  else
+    fib(x-1)+fib(x-2);
+
+# Iterative fib.
+def fibi(x)
+  <b>var a = 1, b = 1, c in</b>
+  (for i = 3, i &;t; x in 
+     <b>c = a + b</b> :
+     <b>a = b</b> :
+     <b>b = c</b>) :
+  b;
+
+# Call it. 
+fibi(10);
+</pre>
+</div>
+
+<p>
+In order to mutate variables, we have to change our existing variables to use
+the "alloca trick".  Once we have that, we'll add our new operator, then extend
+Kaleidoscope to support new variable definitions.
+</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="adjustments">Adjusting Existing Variables for
+Mutation</a></div>
+<!-- *********************************************************************** -->
+
+<div class="doc_text">
+
+<p>
+The symbol table in Kaleidoscope is managed at code generation time by the 
+'<tt>NamedValues</tt>' map.  This map currently keeps track of the LLVM "Value*"
+that holds the double value for the named variable.  In order to support
+mutation, we need to change this slightly, so that it <tt>NamedValues</tt> holds
+the <em>memory location</em> of the variable in question.  Note that this 
+change is a refactoring: it changes the structure of the code, but does not
+(by itself) change the behavior of the compiler.  All of these changes are 
+isolated in the Kaleidoscope code generator.</p>
+
+<p>
+At this point in Kaleidoscope's development, it only supports variables for two
+things: incoming arguments to functions and the induction variable of 'for'
+loops.  For consistency, we'll allow mutation of these variables in addition to
+other user-defined variables.  This means that these will both need memory
+locations.
+</p>
+
+<p>To start our transformation of Kaleidoscope, we'll change the NamedValues
+map to map to AllocaInst* instead of Value*.  Once we do this, the C++ compiler
+will tell use what parts of the code we need to update:</p>
+
+<div class="doc_code">
+<pre>
+static std::map&lt;std::string, AllocaInst*&gt; NamedValues;
+</pre>
+</div>
+
+<p>Also, since we will need to create these alloca's, we'll use a helper
+function that ensures that the allocas are created in the entry block of the
+function:</p>
+
+<div class="doc_code">
+<pre>
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function.  This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+                                          const std::string &amp;VarName) {
+  LLVMBuilder TmpB(&amp;TheFunction-&gt;getEntryBlock(),
+                   TheFunction-&gt;getEntryBlock().begin());
+  return TmpB.CreateAlloca(Type::DoubleTy, 0, VarName.c_str());
+}
+</pre>
+</div>
+
+<p>This funny looking code creates an LLVMBuilder object that is pointing at
+the first instruction (.begin()) of the entry block.  It then creates an alloca
+with the expected name and returns it.  Because all values in Kaleidoscope are
+doubles, there is no need to pass in a type to use.</p>
+
+<p>With this in place, the first functionality change we want to make is to
+variable references.  In our new scheme, variables live on the stack, so code
+generating a reference to them actually needs to produce a load from the stack
+slot:</p>
+
+<div class="doc_code">
+<pre>
+Value *VariableExprAST::Codegen() {
+  // Look this variable up in the function.
+  Value *V = NamedValues[Name];
+  if (V == 0) return ErrorV("Unknown variable name");
+
+  // Load the value.
+  return Builder.CreateLoad(V, Name.c_str());
+}
+</pre>
+</div>
+
+<p>As you can see, this is pretty straight-forward.  Next we need to update the
+things that define the variables to set up the alloca.  We'll start with 
+<tt>ForExprAST::Codegen</tt> (see the <a href="#code">full code listing</a> for
+the unabridged code):</p>
+
+<div class="doc_code">
+<pre>
+  Function *TheFunction = Builder.GetInsertBlock()->getParent();
+
+  <b>// Create an alloca for the variable in the entry block.
+  AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);</b>
+  
+    // Emit the start code first, without 'variable' in scope.
+  Value *StartVal = Start-&gt;Codegen();
+  if (StartVal == 0) return 0;
+  
+  <b>// Store the value into the alloca.
+  Builder.CreateStore(StartVal, Alloca);</b>
+  ...
+
+  // Compute the end condition.
+  Value *EndCond = End-&gt;Codegen();
+  if (EndCond == 0) return EndCond;
+  
+  <b>// Reload, increment, and restore the alloca.  This handles the case where
+  // the body of the loop mutates the variable.
+  Value *CurVar = Builder.CreateLoad(Alloca);
+  Value *NextVar = Builder.CreateAdd(CurVar, StepVal, "nextvar");
+  Builder.CreateStore(NextVar, Alloca);</b>
+  ...
+</pre>
+</div>
+
+<p>This code is virtually identical to the code <a 
+href="LangImpl5.html#forcodegen">before we allowed mutable variables</a>.  The
+big difference is that we no longer have to construct a PHI node, and we use
+load/store to access the variable as needed.</p>
+
+<p>To support mutable argument variables, we need to also make allocas for them.
+The code for this is also pretty simple:</p>
+
+<div class="doc_code">
+<pre>
+/// CreateArgumentAllocas - Create an alloca for each argument and register the
+/// argument in the symbol table so that references to it will succeed.
+void PrototypeAST::CreateArgumentAllocas(Function *F) {
+  Function::arg_iterator AI = F-&gt;arg_begin();
+  for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
+    // Create an alloca for this variable.
+    AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
+
+    // Store the initial value into the alloca.
+    Builder.CreateStore(AI, Alloca);
+
+    // Add arguments to variable symbol table.
+    NamedValues[Args[Idx]] = Alloca;
+  }
+}
+</pre>
+</div>
+
+<p>For each argument, we make an alloca, store the input value to the function
+into the alloca, and register the alloca as the memory location for the
+argument.  This method gets invoked by <tt>FunctionAST::Codegen</tt> right after
+it sets up the entry block for the function.</p>
+
+<p>The final missing piece is adding the 'mem2reg' pass, which allows us to get
+good codegen once again:</p>
+
+<div class="doc_code">
+<pre>
+    // Set up the optimizer pipeline.  Start with registering info about how the
+    // target lays out data structures.
+    OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+    <b>// Promote allocas to registers.
+    OurFPM.add(createPromoteMemoryToRegisterPass());</b>
+    // Do simple "peephole" optimizations and bit-twiddling optzns.
+    OurFPM.add(createInstructionCombiningPass());
+    // Reassociate expressions.
+    OurFPM.add(createReassociatePass());
+</pre>
+</div>
+
+<p>It is interesting to see what the code looks like before and after the
+mem2reg optimization runs.  For example, this is the before/after code for our
+recursive fib.  Before the optimization:</p>
+
+<div class="doc_code">
+<pre>
+define double @fib(double %x) {
+entry:
+	<b>%x1 = alloca double
+	store double %x, double* %x1
+	%x2 = load double* %x1</b>
+	%multmp = fcmp ult double %x2, 3.000000e+00
+	%booltmp = uitofp i1 %multmp to double
+	%ifcond = fcmp one double %booltmp, 0.000000e+00
+	br i1 %ifcond, label %then, label %else
+
+then:		; preds = %entry
+	br label %ifcont
+
+else:		; preds = %entry
+	<b>%x3 = load double* %x1</b>
+	%subtmp = sub double %x3, 1.000000e+00
+	%calltmp = call double @fib( double %subtmp )
+	<b>%x4 = load double* %x1</b>
+	%subtmp5 = sub double %x4, 2.000000e+00
+	%calltmp6 = call double @fib( double %subtmp5 )
+	%addtmp = add double %calltmp, %calltmp6
+	br label %ifcont
+
+ifcont:		; preds = %else, %then
+	%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
+	ret double %iftmp
+}
+</pre>
+</div>
+
+<p>Here there is only one variable (x, the input argument) but you can still
+see the extremely simple-minded code generation strategy we are using.  In the
+entry block, an alloca is created, and the initial input value is stored into
+it.  Each reference to the variable does a reload from the stack.  Also, note
+that we didn't modify the if/then/else expression, so it still inserts a PHI
+node.  While we could make an alloca for it, it is actually easier to create a 
+PHI node for it, so we still just make the PHI.</p>
+
+<p>Here is the code after the mem2reg pass runs:</p>
+
+<div class="doc_code">
+<pre>
+define double @fib(double %x) {
+entry:
+	%multmp = fcmp ult double <b>%x</b>, 3.000000e+00
+	%booltmp = uitofp i1 %multmp to double
+	%ifcond = fcmp one double %booltmp, 0.000000e+00
+	br i1 %ifcond, label %then, label %else
+
+then:
+	br label %ifcont
+
+else:
+	%subtmp = sub double <b>%x</b>, 1.000000e+00
+	%calltmp = call double @fib( double %subtmp )
+	%subtmp5 = sub double <b>%x</b>, 2.000000e+00
+	%calltmp6 = call double @fib( double %subtmp5 )
+	%addtmp = add double %calltmp, %calltmp6
+	br label %ifcont
+
+ifcont:		; preds = %else, %then
+	%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
+	ret double %iftmp
+}
+</pre>
+</div>
+
+<p>This is a trivial case for mem2reg, since there are no redefinitions of the
+variable.  The point of showing this is to calm your tension about inserting
+such blatent inefficiencies :).</p>
+
+<p>After the rest of the optimizers run, we get:</p>
+
+<div class="doc_code">
+<pre>
+define double @fib(double %x) {
+entry:
+	%multmp = fcmp ult double %x, 3.000000e+00
+	%booltmp = uitofp i1 %multmp to double
+	%ifcond = fcmp ueq double %booltmp, 0.000000e+00
+	br i1 %ifcond, label %else, label %ifcont
+
+else:
+	%subtmp = sub double %x, 1.000000e+00
+	%calltmp = call double @fib( double %subtmp )
+	%subtmp5 = sub double %x, 2.000000e+00
+	%calltmp6 = call double @fib( double %subtmp5 )
+	%addtmp = add double %calltmp, %calltmp6
+	ret double %addtmp
+
+ifcont:
+	ret double 1.000000e+00
+}
+</pre>
+</div>
+
+<p>Here we see that the simplifycfg pass decided to clone the return instruction
+into the end of the 'else' block.  This allowed it to eliminate some branches
+and the PHI node.</p>
+
+<p>Now that all symbol table references are updated to use stack variables, 
+we'll add the assignment operator.</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="assignment">New Assignment Operator</a></div>
+<!-- *********************************************************************** -->
+
+<div class="doc_text">
+
+<p>With our current framework, adding a new assignment operator is really
+simple.  We will parse it just like any other binary operator, but handle it
+internally (instead of allowing the user to define it).  The first step is to
+set a precedence:</p>
+
+<div class="doc_code">
+<pre>
+ int main() {
+   // Install standard binary operators.
+   // 1 is lowest precedence.
+   <b>BinopPrecedence['='] = 2;</b>
+   BinopPrecedence['&lt;'] = 10;
+   BinopPrecedence['+'] = 20;
+   BinopPrecedence['-'] = 20;
+</pre>
+</div>
+
+<p>Now that the parser knows the precedence of the binary operator, it takes
+care of all the parsing and AST generation.  We just need to implement codegen
+for the assignment operator.  This looks like:</p> 
+
+<div class="doc_code">
+<pre>
+Value *BinaryExprAST::Codegen() {
+  // Special case '=' because we don't want to emit the LHS as an expression.
+  if (Op == '=') {
+    // Assignment requires the LHS to be an identifier.
+    VariableExprAST *LHSE = dynamic_cast&lt;VariableExprAST*&gt;(LHS);
+    if (!LHSE)
+      return ErrorV("destination of '=' must be a variable");
+</pre>
+</div>
+
+<p>Unlike the rest of the binary operators, our assignment operator doesn't
+follow the "emit LHS, emit RHS, do computation" model.  As such, it is handled
+as a special case before the other binary operators are handled.  The other 
+strange thing about it is that it requires the LHS to be a variable directly.
+</p>
+
+<div class="doc_code">
+<pre>
+    // Codegen the RHS.
+    Value *Val = RHS-&gt;Codegen();
+    if (Val == 0) return 0;
+
+    // Look up the name.
+    Value *Variable = NamedValues[LHSE-&gt;getName()];
+    if (Variable == 0) return ErrorV("Unknown variable name");
+
+    Builder.CreateStore(Val, Variable);
+    return Val;
+  }
+  ...  
+</pre>
+</div>
+
+<p>Once it has the variable, codegen'ing the assignment is straight-forward:
+we emit the RHS of the assignment, create a store, and return the computed
+value.  Returning a value allows for chained assignments like "X = (Y = Z)".</p>
+
+<p>Now that we have an assignment operator, we can mutate loop variables and
+arguments.  For example, we can now run code like this:</p>
+
+<div class="doc_code">
+<pre>
+# Function to print a double.
+extern printd(x);
+
+# Define ':' for sequencing: as a low-precedence operator that ignores operands
+# and just returns the RHS.
+def binary : 1 (x y) y;
+
+def test(x)
+  printd(x) :
+  x = 4 :
+  printd(x);
+
+test(123);
+</pre>
+</div>
+
+<p>When run, this example prints "123" and then "4", showing that we did
+actually mutate the value!  Okay, we have now officially implemented our goal:
+getting this to work requires SSA construction in the general case.  However,
+to be really useful, we want the ability to define our own local variables, lets
+add this next! 
+</p>
+
+</div>
+
+<!-- *********************************************************************** -->
+<div class="doc_section"><a name="localvars">User-defined Local 
+Variables</a></div>
+<!-- *********************************************************************** -->
+
+<div class="doc_text">
+
+<p>Adding var/in is just like any other other extensions we made to 
+Kaleidoscope: we extend the lexer, the parser, the AST and the code generator.
+The first step for adding our new 'var/in' construct is to extend the lexer.
+As before, this is pretty trivial, the code looks like this:</p>
+
+<div class="doc_code">
+<pre>
+enum Token {
+  ...
+  <b>// var definition
+  tok_var = -13</b>
+...
+}
+...
+static int gettok() {
+...
+    if (IdentifierStr == "in") return tok_in;
+    if (IdentifierStr == "binary") return tok_binary;
+    if (IdentifierStr == "unary") return tok_unary;
+    <b>if (IdentifierStr == "var") return tok_var;</b>
+    return tok_identifier;
+...
+</pre>
+</div>
+
+<p>The next step is to define the AST node that we will construct.  For var/in,
+it will look like this:</p>
+
+<div class="doc_code">
+<pre>
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
+  ExprAST *Body;
+public:
+  VarExprAST(const std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; &amp;varnames,
+             ExprAST *body)
+  : VarNames(varnames), Body(body) {}
+  
+  virtual Value *Codegen();
+};
+</pre>
+</div>
+
+<p>var/in allows a list of names to be defined all at once, and each name can
+optionally have an initializer value.  As such, we capture this information in
+the VarNames vector.  Also, var/in has a body, this body is allowed to access
+the variables defined by the let/in.</p>
+
+<p>With this ready, we can define the parser pieces.  First thing we do is add
+it as a primary expression:</p>
+
+<div class="doc_code">
+<pre>
+/// primary
+///   ::= identifierexpr
+///   ::= numberexpr
+///   ::= parenexpr
+///   ::= ifexpr
+///   ::= forexpr
+<b>///   ::= varexpr</b>
+static ExprAST *ParsePrimary() {
+  switch (CurTok) {
+  default: return Error("unknown token when expecting an expression");
+  case tok_identifier: return ParseIdentifierExpr();
+  case tok_number:     return ParseNumberExpr();
+  case '(':            return ParseParenExpr();
+  case tok_if:         return ParseIfExpr();
+  case tok_for:        return ParseForExpr();
+  <b>case tok_var:        return ParseVarExpr();</b>
+  }
+}
+</pre>
+</div>
+
+<p>Next we define ParseVarExpr:</p>
+
+<div class="doc_code">
+<pre>
+/// varexpr ::= 'var' identifer ('=' expression)? 
+//                    (',' identifer ('=' expression)?)* 'in' expression
+static ExprAST *ParseVarExpr() {
+  getNextToken();  // eat the var.
+
+  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
+
+  // At least one variable name is required.
+  if (CurTok != tok_identifier)
+    return Error("expected identifier after var");
+</pre>
+</div>
+
+<p>The first part of this code parses the list of identifier/expr pairs into the
+local <tt>VarNames</tt> vector.  
+
+<div class="doc_code">
+<pre>
+  while (1) {
+    std::string Name = IdentifierStr;
+    getNextToken();  // eat identifer.
+
+    // Read the optional initializer.
+    ExprAST *Init = 0;
+    if (CurTok == '=') {
+      getNextToken(); // eat the '='.
+      
+      Init = ParseExpression();
+      if (Init == 0) return 0;
+    }
+    
+    VarNames.push_back(std::make_pair(Name, Init));
+    
+    // End of var list, exit loop.
+    if (CurTok != ',') break;
+    getNextToken(); // eat the ','.
+    
+    if (CurTok != tok_identifier)
+      return Error("expected identifier list after var");
+  }
+</pre>
+</div>
+
+<p>Once all the variables are parsed, we then parse the body and create the
+AST node:</p>
+
+<div class="doc_code">
+<pre>
+  // At this point, we have to have 'in'.
+  if (CurTok != tok_in)
+    return Error("expected 'in' keyword after 'var'");
+  getNextToken();  // eat 'in'.
+  
+  ExprAST *Body = ParseExpression();
+  if (Body == 0) return 0;
+  
+  return new VarExprAST(VarNames, Body);
+}
+</pre>
+</div>
+
+<p>Now that we can parse and represent the code, we need to support emission of
+LLVM IR for it.  This code starts out with:</p>
+
+<div class="doc_code">
+<pre>
+Value *VarExprAST::Codegen() {
+  std::vector&lt;AllocaInst *&gt; OldBindings;
+  
+  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
+
+  // Register all variables and emit their initializer.
+  for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+    const std::string &amp;VarName = VarNames[i].first;
+    ExprAST *Init = VarNames[i].second;
+</pre>
+</div>
+
+<p>Basically it loops over all the variables, installing them one at a time.
+For each variable we put into the symbol table, we remember the previous value
+that we replace in OldBindings.</p>
+
+<div class="doc_code">
+<pre>
+    // Emit the initializer before adding the variable to scope, this prevents
+    // the initializer from referencing the variable itself, and permits stuff
+    // like this:
+    //  var a = 1 in
+    //    var a = a in ...   # refers to outer 'a'.
+    Value *InitVal;
+    if (Init) {
+      InitVal = Init-&gt;Codegen();
+      if (InitVal == 0) return 0;
+    } else { // If not specified, use 0.0.
+      InitVal = ConstantFP::get(Type::DoubleTy, APFloat(0.0));
+    }
+    
+    AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+    Builder.CreateStore(InitVal, Alloca);
+
+    // Remember the old variable binding so that we can restore the binding when
+    // we unrecurse.
+    OldBindings.push_back(NamedValues[VarName]);
+    
+    // Remember this binding.
+    NamedValues[VarName] = Alloca;
+  }
+</pre>
+</div>
+
+<p>There are more comments here than code.  The basic idea is that we emit the
+initializer, create the alloca, then update the symbol table to point to it.
+Once all the variables are installed in the symbol table, we evaluate the body
+of the var/in expression:</p>
+
+<div class="doc_code">
+<pre>
+  // Codegen the body, now that all vars are in scope.
+  Value *BodyVal = Body-&gt;Codegen();
+  if (BodyVal == 0) return 0;
+</pre>
+</div>
+
+<p>Finally, before returning, we restore the previous variable bindings:</p>
+
+<div class="doc_code">
+<pre>
+  // Pop all our variables from scope.
+  for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+    NamedValues[VarNames[i].first] = OldBindings[i];
+
+  // Return the body computation.
+  return BodyVal;
+}
+</pre>
+</div>
+
+<p>The end result of all of this is that we get properly scoped variable 
+definitions, and we even (trivially) allow mutation of them :).</p>
+
+<p>With this, we completed what we set out to do.  Our nice iterative fib
+example from the intro compiles and runs just fine.  The mem2reg pass optimizes
+all of our stack variables into SSA registers, inserting PHI nodes where needed,
+and our front-end remains simple: no iterated dominator frontier computation
+anywhere in sight.</p>
+
+</div>
 
 <!-- *********************************************************************** -->
 <div class="doc_section"><a name="code">Full Code Listing</a></div>
@@ -306,8 +962,8 @@
 <div class="doc_text">
 
 <p>
-Here is the complete code listing for our running example, enhanced with the
-if/then/else and for expressions..  To build this example, use:
+Here is the complete code listing for our running example, enhanced with mutable
+variables and var/in support.  To build this example, use:
 </p>
 
 <div class="doc_code">
@@ -323,6 +979,1141 @@
 
 <div class="doc_code">
 <pre>
+#include "llvm/DerivedTypes.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/LLVMBuilder.h"
+#include &lt;cstdio&gt;
+#include &lt;string&gt;
+#include &lt;map&gt;
+#include &lt;vector&gt;
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+  tok_eof = -1,
+
+  // commands
+  tok_def = -2, tok_extern = -3,
+
+  // primary
+  tok_identifier = -4, tok_number = -5,
+  
+  // control
+  tok_if = -6, tok_then = -7, tok_else = -8,
+  tok_for = -9, tok_in = -10,
+  
+  // operators
+  tok_binary = -11, tok_unary = -12,
+  
+  // var definition
+  tok_var = -13
+};
+
+static std::string IdentifierStr;  // Filled in if tok_identifier
+static double NumVal;              // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+  static int LastChar = ' ';
+
+  // Skip any whitespace.
+  while (isspace(LastChar))
+    LastChar = getchar();
+
+  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+    IdentifierStr = LastChar;
+    while (isalnum((LastChar = getchar())))
+      IdentifierStr += LastChar;
+
+    if (IdentifierStr == "def") return tok_def;
+    if (IdentifierStr == "extern") return tok_extern;
+    if (IdentifierStr == "if") return tok_if;
+    if (IdentifierStr == "then") return tok_then;
+    if (IdentifierStr == "else") return tok_else;
+    if (IdentifierStr == "for") return tok_for;
+    if (IdentifierStr == "in") return tok_in;
+    if (IdentifierStr == "binary") return tok_binary;
+    if (IdentifierStr == "unary") return tok_unary;
+    if (IdentifierStr == "var") return tok_var;
+    return tok_identifier;
+  }
+
+  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
+    std::string NumStr;
+    do {
+      NumStr += LastChar;
+      LastChar = getchar();
+    } while (isdigit(LastChar) || LastChar == '.');
+
+    NumVal = strtod(NumStr.c_str(), 0);
+    return tok_number;
+  }
+
+  if (LastChar == '#') {
+    // Comment until end of line.
+    do LastChar = getchar();
+    while (LastChar != EOF &amp;&amp; LastChar != '\n' &amp; LastChar != '\r');
+    
+    if (LastChar != EOF)
+      return gettok();
+  }
+  
+  // Check for end of file.  Don't eat the EOF.
+  if (LastChar == EOF)
+    return tok_eof;
+
+  // Otherwise, just return the character as its ascii value.
+  int ThisChar = LastChar;
+  LastChar = getchar();
+  return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+  virtual ~ExprAST() {}
+  virtual Value *Codegen() = 0;
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+  double Val;
+public:
+  NumberExprAST(double val) : Val(val) {}
+  virtual Value *Codegen();
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+  std::string Name;
+public:
+  VariableExprAST(const std::string &amp;name) : Name(name) {}
+  const std::string &amp;getName() const { return Name; }
+  virtual Value *Codegen();
+};
+
+/// UnaryExprAST - Expression class for a unary operator.
+class UnaryExprAST : public ExprAST {
+  char Opcode;
+  ExprAST *Operand;
+public:
+  UnaryExprAST(char opcode, ExprAST *operand) 
+    : Opcode(opcode), Operand(operand) {}
+  virtual Value *Codegen();
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+  char Op;
+  ExprAST *LHS, *RHS;
+public:
+  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 
+    : Op(op), LHS(lhs), RHS(rhs) {}
+  virtual Value *Codegen();
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+  std::string Callee;
+  std::vector&lt;ExprAST*&gt; Args;
+public:
+  CallExprAST(const std::string &amp;callee, std::vector&lt;ExprAST*&gt; &amp;args)
+    : Callee(callee), Args(args) {}
+  virtual Value *Codegen();
+};
+
+/// IfExprAST - Expression class for if/then/else.
+class IfExprAST : public ExprAST {
+  ExprAST *Cond, *Then, *Else;
+public:
+  IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
+  : Cond(cond), Then(then), Else(_else) {}
+  virtual Value *Codegen();
+};
+
+/// ForExprAST - Expression class for for/in.
+class ForExprAST : public ExprAST {
+  std::string VarName;
+  ExprAST *Start, *End, *Step, *Body;
+public:
+  ForExprAST(const std::string &amp;varname, ExprAST *start, ExprAST *end,
+             ExprAST *step, ExprAST *body)
+    : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+  virtual Value *Codegen();
+};
+
+/// VarExprAST - Expression class for var/in
+class VarExprAST : public ExprAST {
+  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
+  ExprAST *Body;
+public:
+  VarExprAST(const std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; &amp;varnames,
+             ExprAST *body)
+  : VarNames(varnames), Body(body) {}
+  
+  virtual Value *Codegen();
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its argument names as well as if it is an operator.
+class PrototypeAST {
+  std::string Name;
+  std::vector&lt;std::string&gt; Args;
+  bool isOperator;
+  unsigned Precedence;  // Precedence if a binary op.
+public:
+  PrototypeAST(const std::string &amp;name, const std::vector&lt;std::string&gt; &amp;args,
+               bool isoperator = false, unsigned prec = 0)
+  : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
+  
+  bool isUnaryOp() const { return isOperator &amp;&amp; Args.size() == 1; }
+  bool isBinaryOp() const { return isOperator &amp;&amp; Args.size() == 2; }
+  
+  char getOperatorName() const {
+    assert(isUnaryOp() || isBinaryOp());
+    return Name[Name.size()-1];
+  }
+  
+  unsigned getBinaryPrecedence() const { return Precedence; }
+  
+  Function *Codegen();
+  
+  void CreateArgumentAllocas(Function *F);
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+  PrototypeAST *Proto;
+  ExprAST *Body;
+public:
+  FunctionAST(PrototypeAST *proto, ExprAST *body)
+    : Proto(proto), Body(body) {}
+  
+  Function *Codegen();
+};
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
+/// token the parser it looking at.  getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() {
+  return CurTok = gettok();
+}
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map&lt;char, int&gt; BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+  if (!isascii(CurTok))
+    return -1;
+  
+  // Make sure it's a declared binop.
+  int TokPrec = BinopPrecedence[CurTok];
+  if (TokPrec &lt;= 0) return -1;
+  return TokPrec;
+}
+
+/// Error* - These are little helper functions for error handling.
+ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
+PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
+FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
+
+static ExprAST *ParseExpression();
+
+/// identifierexpr
+///   ::= identifer
+///   ::= identifer '(' expression* ')'
+static ExprAST *ParseIdentifierExpr() {
+  std::string IdName = IdentifierStr;
+  
+  getNextToken();  // eat identifer.
+  
+  if (CurTok != '(') // Simple variable ref.
+    return new VariableExprAST(IdName);
+  
+  // Call.
+  getNextToken();  // eat (
+  std::vector&lt;ExprAST*&gt; Args;
+  if (CurTok != ')') {
+    while (1) {
+      ExprAST *Arg = ParseExpression();
+      if (!Arg) return 0;
+      Args.push_back(Arg);
+      
+      if (CurTok == ')') break;
+      
+      if (CurTok != ',')
+        return Error("Expected ')'");
+      getNextToken();
+    }
+  }
+
+  // Eat the ')'.
+  getNextToken();
+  
+  return new CallExprAST(IdName, Args);
+}
+
+/// numberexpr ::= number
+static ExprAST *ParseNumberExpr() {
+  ExprAST *Result = new NumberExprAST(NumVal);
+  getNextToken(); // consume the number
+  return Result;
+}
+
+/// parenexpr ::= '(' expression ')'
+static ExprAST *ParseParenExpr() {
+  getNextToken();  // eat (.
+  ExprAST *V = ParseExpression();
+  if (!V) return 0;
+  
+  if (CurTok != ')')
+    return Error("expected ')'");
+  getNextToken();  // eat ).
+  return V;
+}
+
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression
+static ExprAST *ParseIfExpr() {
+  getNextToken();  // eat the if.
+  
+  // condition.
+  ExprAST *Cond = ParseExpression();
+  if (!Cond) return 0;
+  
+  if (CurTok != tok_then)
+    return Error("expected then");
+  getNextToken();  // eat the then
+  
+  ExprAST *Then = ParseExpression();
+  if (Then == 0) return 0;
+  
+  if (CurTok != tok_else)
+    return Error("expected else");
+  
+  getNextToken();
+  
+  ExprAST *Else = ParseExpression();
+  if (!Else) return 0;
+  
+  return new IfExprAST(Cond, Then, Else);
+}
+
+/// forexpr ::= 'for' identifer '=' expr ',' expr (',' expr)? 'in' expression
+static ExprAST *ParseForExpr() {
+  getNextToken();  // eat the for.
+
+  if (CurTok != tok_identifier)
+    return Error("expected identifier after for");
+  
+  std::string IdName = IdentifierStr;
+  getNextToken();  // eat identifer.
+  
+  if (CurTok != '=')
+    return Error("expected '=' after for");
+  getNextToken();  // eat '='.
+  
+  
+  ExprAST *Start = ParseExpression();
+  if (Start == 0) return 0;
+  if (CurTok != ',')
+    return Error("expected ',' after for start value");
+  getNextToken();
+  
+  ExprAST *End = ParseExpression();
+  if (End == 0) return 0;
+  
+  // The step value is optional.
+  ExprAST *Step = 0;
+  if (CurTok == ',') {
+    getNextToken();
+    Step = ParseExpression();
+    if (Step == 0) return 0;
+  }
+  
+  if (CurTok != tok_in)
+    return Error("expected 'in' after for");
+  getNextToken();  // eat 'in'.
+  
+  ExprAST *Body = ParseExpression();
+  if (Body == 0) return 0;
+
+  return new ForExprAST(IdName, Start, End, Step, Body);
+}
+
+/// varexpr ::= 'var' identifer ('=' expression)? 
+//                    (',' identifer ('=' expression)?)* 'in' expression
+static ExprAST *ParseVarExpr() {
+  getNextToken();  // eat the var.
+
+  std::vector&lt;std::pair&lt;std::string, ExprAST*&gt; &gt; VarNames;
+
+  // At least one variable name is required.
+  if (CurTok != tok_identifier)
+    return Error("expected identifier after var");
+  
+  while (1) {
+    std::string Name = IdentifierStr;
+    getNextToken();  // eat identifer.
+
+    // Read the optional initializer.
+    ExprAST *Init = 0;
+    if (CurTok == '=') {
+      getNextToken(); // eat the '='.
+      
+      Init = ParseExpression();
+      if (Init == 0) return 0;
+    }
+    
+    VarNames.push_back(std::make_pair(Name, Init));
+    
+    // End of var list, exit loop.
+    if (CurTok != ',') break;
+    getNextToken(); // eat the ','.
+    
+    if (CurTok != tok_identifier)
+      return Error("expected identifier list after var");
+  }
+  
+  // At this point, we have to have 'in'.
+  if (CurTok != tok_in)
+    return Error("expected 'in' keyword after 'var'");
+  getNextToken();  // eat 'in'.
+  
+  ExprAST *Body = ParseExpression();
+  if (Body == 0) return 0;
+  
+  return new VarExprAST(VarNames, Body);
+}
+
+
+/// primary
+///   ::= identifierexpr
+///   ::= numberexpr
+///   ::= parenexpr
+///   ::= ifexpr
+///   ::= forexpr
+///   ::= varexpr
+static ExprAST *ParsePrimary() {
+  switch (CurTok) {
+  default: return Error("unknown token when expecting an expression");
+  case tok_identifier: return ParseIdentifierExpr();
+  case tok_number:     return ParseNumberExpr();
+  case '(':            return ParseParenExpr();
+  case tok_if:         return ParseIfExpr();
+  case tok_for:        return ParseForExpr();
+  case tok_var:        return ParseVarExpr();
+  }
+}
+
+/// unary
+///   ::= primary
+///   ::= '!' unary
+static ExprAST *ParseUnary() {
+  // If the current token is not an operator, it must be a primary expr.
+  if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
+    return ParsePrimary();
+  
+  // If this is a unary operator, read it.
+  int Opc = CurTok;
+  getNextToken();
+  if (ExprAST *Operand = ParseUnary())
+    return new UnaryExprAST(Opc, Operand);
+  return 0;
+}
+
+/// binoprhs
+///   ::= ('+' unary)*
+static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+  // If this is a binop, find its precedence.
+  while (1) {
+    int TokPrec = GetTokPrecedence();
+    
+    // If this is a binop that binds at least as tightly as the current binop,
+    // consume it, otherwise we are done.
+    if (TokPrec &lt; ExprPrec)
+      return LHS;
+    
+    // Okay, we know this is a binop.
+    int BinOp = CurTok;
+    getNextToken();  // eat binop
+    
+    // Parse the unary expression after the binary operator.
+    ExprAST *RHS = ParseUnary();
+    if (!RHS) return 0;
+    
+    // If BinOp binds less tightly with RHS than the operator after RHS, let
+    // the pending operator take RHS as its LHS.
+    int NextPrec = GetTokPrecedence();
+    if (TokPrec &lt; NextPrec) {
+      RHS = ParseBinOpRHS(TokPrec+1, RHS);
+      if (RHS == 0) return 0;
+    }
+    
+    // Merge LHS/RHS.
+    LHS = new BinaryExprAST(BinOp, LHS, RHS);
+  }
+}
+
+/// expression
+///   ::= unary binoprhs
+///
+static ExprAST *ParseExpression() {
+  ExprAST *LHS = ParseUnary();
+  if (!LHS) return 0;
+  
+  return ParseBinOpRHS(0, LHS);
+}
+
+/// prototype
+///   ::= id '(' id* ')'
+///   ::= binary LETTER number? (id, id)
+///   ::= unary LETTER (id)
+static PrototypeAST *ParsePrototype() {
+  std::string FnName;
+  
+  int Kind = 0;  // 0 = identifier, 1 = unary, 2 = binary.
+  unsigned BinaryPrecedence = 30;
+  
+  switch (CurTok) {
+  default:
+    return ErrorP("Expected function name in prototype");
+  case tok_identifier:
+    FnName = IdentifierStr;
+    Kind = 0;
+    getNextToken();
+    break;
+  case tok_unary:
+    getNextToken();
+    if (!isascii(CurTok))
+      return ErrorP("Expected unary operator");
+    FnName = "unary";
+    FnName += (char)CurTok;
+    Kind = 1;
+    getNextToken();
+    break;
+  case tok_binary:
+    getNextToken();
+    if (!isascii(CurTok))
+      return ErrorP("Expected binary operator");
+    FnName = "binary";
+    FnName += (char)CurTok;
+    Kind = 2;
+    getNextToken();
+    
+    // Read the precedence if present.
+    if (CurTok == tok_number) {
+      if (NumVal &lt; 1 || NumVal &gt; 100)
+        return ErrorP("Invalid precedecnce: must be 1..100");
+      BinaryPrecedence = (unsigned)NumVal;
+      getNextToken();
+    }
+    break;
+  }
+  
+  if (CurTok != '(')
+    return ErrorP("Expected '(' in prototype");
+  
+  std::vector&lt;std::string&gt; ArgNames;
+  while (getNextToken() == tok_identifier)
+    ArgNames.push_back(IdentifierStr);
+  if (CurTok != ')')
+    return ErrorP("Expected ')' in prototype");
+  
+  // success.
+  getNextToken();  // eat ')'.
+  
+  // Verify right number of names for operator.
+  if (Kind &amp;&amp; ArgNames.size() != Kind)
+    return ErrorP("Invalid number of operands for operator");
+  
+  return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence);
+}
+
+/// definition ::= 'def' prototype expression
+static FunctionAST *ParseDefinition() {
+  getNextToken();  // eat def.
+  PrototypeAST *Proto = ParsePrototype();
+  if (Proto == 0) return 0;
+
+  if (ExprAST *E = ParseExpression())
+    return new FunctionAST(Proto, E);
+  return 0;
+}
+
+/// toplevelexpr ::= expression
+static FunctionAST *ParseTopLevelExpr() {
+  if (ExprAST *E = ParseExpression()) {
+    // Make an anonymous proto.
+    PrototypeAST *Proto = new PrototypeAST("", std::vector&lt;std::string&gt;());
+    return new FunctionAST(Proto, E);
+  }
+  return 0;
+}
+
+/// external ::= 'extern' prototype
+static PrototypeAST *ParseExtern() {
+  getNextToken();  // eat extern.
+  return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Code Generation
+//===----------------------------------------------------------------------===//
+
+static Module *TheModule;
+static LLVMFoldingBuilder Builder;
+static std::map&lt;std::string, AllocaInst*&gt; NamedValues;
+static FunctionPassManager *TheFPM;
+
+Value *ErrorV(const char *Str) { Error(Str); return 0; }
+
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
+/// the function.  This is used for mutable variables etc.
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,
+                                          const std::string &amp;VarName) {
+  LLVMBuilder TmpB(&amp;TheFunction-&gt;getEntryBlock(),
+                   TheFunction-&gt;getEntryBlock().begin());
+  return TmpB.CreateAlloca(Type::DoubleTy, 0, VarName.c_str());
+}
+
+
+Value *NumberExprAST::Codegen() {
+  return ConstantFP::get(Type::DoubleTy, APFloat(Val));
+}
+
+Value *VariableExprAST::Codegen() {
+  // Look this variable up in the function.
+  Value *V = NamedValues[Name];
+  if (V == 0) return ErrorV("Unknown variable name");
+
+  // Load the value.
+  return Builder.CreateLoad(V, Name.c_str());
+}
+
+Value *UnaryExprAST::Codegen() {
+  Value *OperandV = Operand-&gt;Codegen();
+  if (OperandV == 0) return 0;
+  
+  Function *F = TheModule-&gt;getFunction(std::string("unary")+Opcode);
+  if (F == 0)
+    return ErrorV("Unknown unary operator");
+  
+  return Builder.CreateCall(F, OperandV, "unop");
+}
+
+
+Value *BinaryExprAST::Codegen() {
+  // Special case '=' because we don't want to emit the LHS as an expression.
+  if (Op == '=') {
+    // Assignment requires the LHS to be an identifier.
+    VariableExprAST *LHSE = dynamic_cast&lt;VariableExprAST*&gt;(LHS);
+    if (!LHSE)
+      return ErrorV("destination of '=' must be a variable");
+    // Codegen the RHS.
+    Value *Val = RHS-&gt;Codegen();
+    if (Val == 0) return 0;
+
+    // Look up the name.
+    Value *Variable = NamedValues[LHSE-&gt;getName()];
+    if (Variable == 0) return ErrorV("Unknown variable name");
+
+    Builder.CreateStore(Val, Variable);
+    return Val;
+  }
+  
+  
+  Value *L = LHS-&gt;Codegen();
+  Value *R = RHS-&gt;Codegen();
+  if (L == 0 || R == 0) return 0;
+  
+  switch (Op) {
+  case '+': return Builder.CreateAdd(L, R, "addtmp");
+  case '-': return Builder.CreateSub(L, R, "subtmp");
+  case '*': return Builder.CreateMul(L, R, "multmp");
+  case '&lt;':
+    L = Builder.CreateFCmpULT(L, R, "multmp");
+    // Convert bool 0/1 to double 0.0 or 1.0
+    return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
+  default: break;
+  }
+  
+  // If it wasn't a builtin binary operator, it must be a user defined one. Emit
+  // a call to it.
+  Function *F = TheModule-&gt;getFunction(std::string("binary")+Op);
+  assert(F &amp;&amp; "binary operator not found!");
+  
+  Value *Ops[] = { L, R };
+  return Builder.CreateCall(F, Ops, Ops+2, "binop");
+}
+
+Value *CallExprAST::Codegen() {
+  // Look up the name in the global module table.
+  Function *CalleeF = TheModule-&gt;getFunction(Callee);
+  if (CalleeF == 0)
+    return ErrorV("Unknown function referenced");
+  
+  // If argument mismatch error.
+  if (CalleeF-&gt;arg_size() != Args.size())
+    return ErrorV("Incorrect # arguments passed");
+
+  std::vector&lt;Value*&gt; ArgsV;
+  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+    ArgsV.push_back(Args[i]-&gt;Codegen());
+    if (ArgsV.back() == 0) return 0;
+  }
+  
+  return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
+}
+
+Value *IfExprAST::Codegen() {
+  Value *CondV = Cond-&gt;Codegen();
+  if (CondV == 0) return 0;
+  
+  // Convert condition to a bool by comparing equal to 0.0.
+  CondV = Builder.CreateFCmpONE(CondV, 
+                                ConstantFP::get(Type::DoubleTy, APFloat(0.0)),
+                                "ifcond");
+  
+  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
+  
+  // Create blocks for the then and else cases.  Insert the 'then' block at the
+  // end of the function.
+  BasicBlock *ThenBB = new BasicBlock("then", TheFunction);
+  BasicBlock *ElseBB = new BasicBlock("else");
+  BasicBlock *MergeBB = new BasicBlock("ifcont");
+  
+  Builder.CreateCondBr(CondV, ThenBB, ElseBB);
+  
+  // Emit then value.
+  Builder.SetInsertPoint(ThenBB);
+  
+  Value *ThenV = Then-&gt;Codegen();
+  if (ThenV == 0) return 0;
+  
+  Builder.CreateBr(MergeBB);
+  // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
+  ThenBB = Builder.GetInsertBlock();
+  
+  // Emit else block.
+  TheFunction-&gt;getBasicBlockList().push_back(ElseBB);
+  Builder.SetInsertPoint(ElseBB);
+  
+  Value *ElseV = Else-&gt;Codegen();
+  if (ElseV == 0) return 0;
+  
+  Builder.CreateBr(MergeBB);
+  // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
+  ElseBB = Builder.GetInsertBlock();
+  
+  // Emit merge block.
+  TheFunction-&gt;getBasicBlockList().push_back(MergeBB);
+  Builder.SetInsertPoint(MergeBB);
+  PHINode *PN = Builder.CreatePHI(Type::DoubleTy, "iftmp");
+  
+  PN-&gt;addIncoming(ThenV, ThenBB);
+  PN-&gt;addIncoming(ElseV, ElseBB);
+  return PN;
+}
+
+Value *ForExprAST::Codegen() {
+  // Output this as:
+  //   var = alloca double
+  //   ...
+  //   start = startexpr
+  //   store start -&gt; var
+  //   goto loop
+  // loop: 
+  //   ...
+  //   bodyexpr
+  //   ...
+  // loopend:
+  //   step = stepexpr
+  //   endcond = endexpr
+  //
+  //   curvar = load var
+  //   nextvar = curvar + step
+  //   store nextvar -&gt; var
+  //   br endcond, loop, endloop
+  // outloop:
+  
+  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
+
+  // Create an alloca for the variable in the entry block.
+  AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+  
+  // Emit the start code first, without 'variable' in scope.
+  Value *StartVal = Start-&gt;Codegen();
+  if (StartVal == 0) return 0;
+  
+  // Store the value into the alloca.
+  Builder.CreateStore(StartVal, Alloca);
+  
+  // Make the new basic block for the loop header, inserting after current
+  // block.
+  BasicBlock *PreheaderBB = Builder.GetInsertBlock();
+  BasicBlock *LoopBB = new BasicBlock("loop", TheFunction);
+  
+  // Insert an explicit fall through from the current block to the LoopBB.
+  Builder.CreateBr(LoopBB);
+
+  // Start insertion in LoopBB.
+  Builder.SetInsertPoint(LoopBB);
+  
+  // Within the loop, the variable is defined equal to the PHI node.  If it
+  // shadows an existing variable, we have to restore it, so save it now.
+  AllocaInst *OldVal = NamedValues[VarName];
+  NamedValues[VarName] = Alloca;
+  
+  // Emit the body of the loop.  This, like any other expr, can change the
+  // current BB.  Note that we ignore the value computed by the body, but don't
+  // allow an error.
+  if (Body-&gt;Codegen() == 0)
+    return 0;
+  
+  // Emit the step value.
+  Value *StepVal;
+  if (Step) {
+    StepVal = Step-&gt;Codegen();
+    if (StepVal == 0) return 0;
+  } else {
+    // If not specified, use 1.0.
+    StepVal = ConstantFP::get(Type::DoubleTy, APFloat(1.0));
+  }
+  
+  // Compute the end condition.
+  Value *EndCond = End-&gt;Codegen();
+  if (EndCond == 0) return EndCond;
+  
+  // Reload, increment, and restore the alloca.  This handles the case where
+  // the body of the loop mutates the variable.
+  Value *CurVar = Builder.CreateLoad(Alloca, VarName.c_str());
+  Value *NextVar = Builder.CreateAdd(CurVar, StepVal, "nextvar");
+  Builder.CreateStore(NextVar, Alloca);
+  
+  // Convert condition to a bool by comparing equal to 0.0.
+  EndCond = Builder.CreateFCmpONE(EndCond, 
+                                  ConstantFP::get(Type::DoubleTy, APFloat(0.0)),
+                                  "loopcond");
+  
+  // Create the "after loop" block and insert it.
+  BasicBlock *LoopEndBB = Builder.GetInsertBlock();
+  BasicBlock *AfterBB = new BasicBlock("afterloop", TheFunction);
+  
+  // Insert the conditional branch into the end of LoopEndBB.
+  Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
+  
+  // Any new code will be inserted in AfterBB.
+  Builder.SetInsertPoint(AfterBB);
+  
+  // Restore the unshadowed variable.
+  if (OldVal)
+    NamedValues[VarName] = OldVal;
+  else
+    NamedValues.erase(VarName);
+
+  
+  // for expr always returns 0.0.
+  return Constant::getNullValue(Type::DoubleTy);
+}
+
+Value *VarExprAST::Codegen() {
+  std::vector&lt;AllocaInst *&gt; OldBindings;
+  
+  Function *TheFunction = Builder.GetInsertBlock()-&gt;getParent();
+
+  // Register all variables and emit their initializer.
+  for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
+    const std::string &amp;VarName = VarNames[i].first;
+    ExprAST *Init = VarNames[i].second;
+    
+    // Emit the initializer before adding the variable to scope, this prevents
+    // the initializer from referencing the variable itself, and permits stuff
+    // like this:
+    //  var a = 1 in
+    //    var a = a in ...   # refers to outer 'a'.
+    Value *InitVal;
+    if (Init) {
+      InitVal = Init-&gt;Codegen();
+      if (InitVal == 0) return 0;
+    } else { // If not specified, use 0.0.
+      InitVal = ConstantFP::get(Type::DoubleTy, APFloat(0.0));
+    }
+    
+    AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);
+    Builder.CreateStore(InitVal, Alloca);
+
+    // Remember the old variable binding so that we can restore the binding when
+    // we unrecurse.
+    OldBindings.push_back(NamedValues[VarName]);
+    
+    // Remember this binding.
+    NamedValues[VarName] = Alloca;
+  }
+  
+  // Codegen the body, now that all vars are in scope.
+  Value *BodyVal = Body-&gt;Codegen();
+  if (BodyVal == 0) return 0;
+  
+  // Pop all our variables from scope.
+  for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
+    NamedValues[VarNames[i].first] = OldBindings[i];
+
+  // Return the body computation.
+  return BodyVal;
+}
+
+
+Function *PrototypeAST::Codegen() {
+  // Make the function type:  double(double,double) etc.
+  std::vector&lt;const Type*&gt; Doubles(Args.size(), Type::DoubleTy);
+  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
+  
+  Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
+  
+  // If F conflicted, there was already something named 'Name'.  If it has a
+  // body, don't allow redefinition or reextern.
+  if (F-&gt;getName() != Name) {
+    // Delete the one we just made and get the existing one.
+    F-&gt;eraseFromParent();
+    F = TheModule-&gt;getFunction(Name);
+    
+    // If F already has a body, reject this.
+    if (!F-&gt;empty()) {
+      ErrorF("redefinition of function");
+      return 0;
+    }
+    
+    // If F took a different number of args, reject.
+    if (F-&gt;arg_size() != Args.size()) {
+      ErrorF("redefinition of function with different # args");
+      return 0;
+    }
+  }
+  
+  // Set names for all arguments.
+  unsigned Idx = 0;
+  for (Function::arg_iterator AI = F-&gt;arg_begin(); Idx != Args.size();
+       ++AI, ++Idx)
+    AI-&gt;setName(Args[Idx]);
+    
+  return F;
+}
+
+/// CreateArgumentAllocas - Create an alloca for each argument and register the
+/// argument in the symbol table so that references to it will succeed.
+void PrototypeAST::CreateArgumentAllocas(Function *F) {
+  Function::arg_iterator AI = F-&gt;arg_begin();
+  for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {
+    // Create an alloca for this variable.
+    AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);
+
+    // Store the initial value into the alloca.
+    Builder.CreateStore(AI, Alloca);
+
+    // Add arguments to variable symbol table.
+    NamedValues[Args[Idx]] = Alloca;
+  }
+}
+
+
+Function *FunctionAST::Codegen() {
+  NamedValues.clear();
+  
+  Function *TheFunction = Proto-&gt;Codegen();
+  if (TheFunction == 0)
+    return 0;
+  
+  // If this is an operator, install it.
+  if (Proto-&gt;isBinaryOp())
+    BinopPrecedence[Proto-&gt;getOperatorName()] = Proto-&gt;getBinaryPrecedence();
+  
+  // Create a new basic block to start insertion into.
+  BasicBlock *BB = new BasicBlock("entry", TheFunction);
+  Builder.SetInsertPoint(BB);
+  
+  // Add all arguments to the symbol table and create their allocas.
+  Proto-&gt;CreateArgumentAllocas(TheFunction);
+  
+  if (Value *RetVal = Body-&gt;Codegen()) {
+    // Finish off the function.
+    Builder.CreateRet(RetVal);
+
+    // Validate the generated code, checking for consistency.
+    verifyFunction(*TheFunction);
+
+    // Optimize the function.
+    TheFPM-&gt;run(*TheFunction);
+    
+    return TheFunction;
+  }
+  
+  // Error reading body, remove function.
+  TheFunction-&gt;eraseFromParent();
+
+  if (Proto-&gt;isBinaryOp())
+    BinopPrecedence.erase(Proto-&gt;getOperatorName());
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing and JIT Driver
+//===----------------------------------------------------------------------===//
+
+static ExecutionEngine *TheExecutionEngine;
+
+static void HandleDefinition() {
+  if (FunctionAST *F = ParseDefinition()) {
+    if (Function *LF = F-&gt;Codegen()) {
+      fprintf(stderr, "Read function definition:");
+      LF-&gt;dump();
+    }
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+static void HandleExtern() {
+  if (PrototypeAST *P = ParseExtern()) {
+    if (Function *F = P-&gt;Codegen()) {
+      fprintf(stderr, "Read extern: ");
+      F-&gt;dump();
+    }
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+static void HandleTopLevelExpression() {
+  // Evaluate a top level expression into an anonymous function.
+  if (FunctionAST *F = ParseTopLevelExpr()) {
+    if (Function *LF = F-&gt;Codegen()) {
+      // JIT the function, returning a function pointer.
+      void *FPtr = TheExecutionEngine-&gt;getPointerToFunction(LF);
+      
+      // Cast it to the right type (takes no arguments, returns a double) so we
+      // can call it as a native function.
+      double (*FP)() = (double (*)())FPtr;
+      fprintf(stderr, "Evaluated to %f\n", FP());
+    }
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+  while (1) {
+    fprintf(stderr, "ready&gt; ");
+    switch (CurTok) {
+    case tok_eof:    return;
+    case ';':        getNextToken(); break;  // ignore top level semicolons.
+    case tok_def:    HandleDefinition(); break;
+    case tok_extern: HandleExtern(); break;
+    default:         HandleTopLevelExpression(); break;
+    }
+  }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// "Library" functions that can be "extern'd" from user code.
+//===----------------------------------------------------------------------===//
+
+/// putchard - putchar that takes a double and returns 0.
+extern "C" 
+double putchard(double X) {
+  putchar((char)X);
+  return 0;
+}
+
+/// printd - printf that takes a double prints it as "%f\n", returning 0.
+extern "C" 
+double printd(double X) {
+  printf("%f\n", X);
+  return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+  // Install standard binary operators.
+  // 1 is lowest precedence.
+  BinopPrecedence['='] = 2;
+  BinopPrecedence['&lt;'] = 10;
+  BinopPrecedence['+'] = 20;
+  BinopPrecedence['-'] = 20;
+  BinopPrecedence['*'] = 40;  // highest.
+
+  // Prime the first token.
+  fprintf(stderr, "ready&gt; ");
+  getNextToken();
+
+  // Make the module, which holds all the code.
+  TheModule = new Module("my cool jit");
+  
+  // Create the JIT.
+  TheExecutionEngine = ExecutionEngine::create(TheModule);
+
+  {
+    ExistingModuleProvider OurModuleProvider(TheModule);
+    FunctionPassManager OurFPM(&amp;OurModuleProvider);
+      
+    // Set up the optimizer pipeline.  Start with registering info about how the
+    // target lays out data structures.
+    OurFPM.add(new TargetData(*TheExecutionEngine-&gt;getTargetData()));
+    // Promote allocas to registers.
+    OurFPM.add(createPromoteMemoryToRegisterPass());
+    // Do simple "peephole" optimizations and bit-twiddling optzns.
+    OurFPM.add(createInstructionCombiningPass());
+    // Reassociate expressions.
+    OurFPM.add(createReassociatePass());
+    // Eliminate Common SubExpressions.
+    OurFPM.add(createGVNPass());
+    // Simplify the control flow graph (deleting unreachable blocks, etc).
+    OurFPM.add(createCFGSimplificationPass());
+
+    // Set the global so the code gen can use this.
+    TheFPM = &amp;OurFPM;
+
+    // Run the main "interpreter loop" now.
+    MainLoop();
+    
+    TheFPM = 0;
+  }  // Free module provider and pass manager.
+                                   
+                                   
+  // Print out all of the generated code.
+  TheModule-&gt;dump();
+  return 0;
+}
 </pre>
 </div>
 
