Big Kaleidoscope tutorial update.
[oota-llvm.git] / docs / tutorial / LangImpl2.rst
index 0d62894a24028434981b60ac896b03794b945082..92a266eeb031b838e32d522357b855d0079d7297 100644 (file)
@@ -5,8 +5,6 @@ Kaleidoscope: Implementing a Parser and AST
 .. contents::
    :local:
 
-Written by `Chris Lattner <mailto:sabre@nondot.org>`_
-
 Chapter 2 Introduction
 ======================
 
@@ -46,8 +44,9 @@ We'll start with expressions first:
     /// NumberExprAST - Expression class for numeric literals like "1.0".
     class NumberExprAST : public ExprAST {
       double Val;
+
     public:
-      NumberExprAST(double val) : Val(val) {}
+      NumberExprAST(double Val) : Val(Val) {}
     };
 
 The code above shows the definition of the base ExprAST class and one
@@ -67,26 +66,31 @@ language:
     /// VariableExprAST - Expression class for referencing a variable, like "a".
     class VariableExprAST : public ExprAST {
       std::string Name;
+
     public:
-      VariableExprAST(const std::string &name) : Name(name) {}
+      VariableExprAST(const std::string &Name) : Name(Name) {}
     };
 
     /// BinaryExprAST - Expression class for a binary operator.
     class BinaryExprAST : public ExprAST {
       char Op;
-      ExprAST *LHS, *RHS;
+      std::unique_ptr<ExprAST> LHS, RHS;
+
     public:
-      BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
-        : Op(op), LHS(lhs), RHS(rhs) {}
+      BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
+                    std::unique_ptr<ExprAST> RHS)
+        : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
     };
 
     /// CallExprAST - Expression class for function calls.
     class CallExprAST : public ExprAST {
       std::string Callee;
-      std::vector<ExprAST*> Args;
+      std::vector<std::unique_ptr<ExprAST>> Args;
+
     public:
-      CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
-        : Callee(callee), Args(args) {}
+      CallExprAST(const std::string &Callee,
+                  std::vector<std::unique_ptr<ExprAST>> Args)
+        : Callee(Callee), Args(std::move(Args)) {}
     };
 
 This is all (intentionally) rather straight-forward: variables capture
@@ -111,18 +115,21 @@ way to talk about functions themselves:
     class PrototypeAST {
       std::string Name;
       std::vector<std::string> Args;
+
     public:
-      PrototypeAST(const std::string &name, const std::vector<std::string> &args)
-        : Name(name), Args(args) {}
+      PrototypeAST(const std::string &name, std::vector<std::string> Args)
+        : Name(name), Args(std::move(Args)) {}
     };
 
     /// FunctionAST - This class represents a function definition itself.
     class FunctionAST {
-      PrototypeAST *Proto;
-      ExprAST *Body;
+      std::unique_ptr<PrototypeAST> Proto;
+      std::unique_ptr<ExprAST> Body;
+
     public:
-      FunctionAST(PrototypeAST *proto, ExprAST *body)
-        : Proto(proto), Body(body) {}
+      FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+                  std::unique_ptr<ExprAST> Body)
+        : Proto(std::move(Proto)), Body(std::move(Body)) {}
     };
 
 In Kaleidoscope, functions are typed with just a count of their
@@ -144,9 +151,10 @@ be generated with calls like this:
 
 .. code-block:: c++
 
-      ExprAST *X = new VariableExprAST("x");
-      ExprAST *Y = new VariableExprAST("y");
-      ExprAST *Result = new BinaryExprAST('+', X, Y);
+      auto LHS = llvm::make_unique<VariableExprAST>("x");
+      auto RHS = llvm::make_unique<VariableExprAST>("y");
+      auto Result = std::make_unique<BinaryExprAST>('+', std::move(LHS),
+                                                    std::move(RHS));
 
 In order to do this, we'll start by defining some basic helper routines:
 
@@ -169,9 +177,14 @@ be parsed.
 
 
     /// 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; }
+    std::unique_ptr<ExprAST> Error(const char *Str) {
+      fprintf(stderr, "Error: %s\n", Str);
+      return nullptr;
+    }
+    std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
+      Error(Str);
+      return nullptr;
+    }
 
 The ``Error`` routines are simple helper routines that our parser will
 use to handle errors. The error recovery in our parser will not be the
@@ -192,10 +205,10 @@ which parses that production. For numeric literals, we have:
 .. code-block:: c++
 
     /// numberexpr ::= number
-    static ExprAST *ParseNumberExpr() {
-      ExprAST *Result = new NumberExprAST(NumVal);
+    static std::unique_ptr<ExprAST> ParseNumberExpr() {
+      auto Result = llvm::make_unique<NumberExprAST>(NumVal);
       getNextToken(); // consume the number
-      return Result;
+      return std::move(Result);
     }
 
 This routine is very simple: it expects to be called when the current
@@ -213,14 +226,15 @@ the parenthesis operator is defined like this:
 .. code-block:: c++
 
     /// parenexpr ::= '(' expression ')'
-    static ExprAST *ParseParenExpr() {
-      getNextToken();  // eat (.
-      ExprAST *V = ParseExpression();
-      if (!V) return 0;
+    static std::unique_ptr<ExprAST> ParseParenExpr() {
+      getNextToken(); // eat (.
+      auto V = ParseExpression();
+      if (!V)
+        return nullptr;
 
       if (CurTok != ')')
         return Error("expected ')'");
-      getNextToken();  // eat ).
+      getNextToken(); // eat ).
       return V;
     }
 
@@ -252,24 +266,26 @@ function calls:
     /// identifierexpr
     ///   ::= identifier
     ///   ::= identifier '(' expression* ')'
-    static ExprAST *ParseIdentifierExpr() {
+    static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
       std::string IdName = IdentifierStr;
 
       getNextToken();  // eat identifier.
 
       if (CurTok != '(') // Simple variable ref.
-        return new VariableExprAST(IdName);
+        return llvm::make_unique<VariableExprAST>(IdName);
 
       // Call.
       getNextToken();  // eat (
-      std::vector<ExprAST*> Args;
+      std::vector<std::unique_ptr<ExprAST>> Args;
       if (CurTok != ')') {
         while (1) {
-          ExprAST *Arg = ParseExpression();
-          if (!Arg) return 0;
-          Args.push_back(Arg);
+          if (auto Arg = ParseExpression())
+            Args.push_back(std::move(Arg));
+          else
+            return nullptr;
 
-          if (CurTok == ')') break;
+          if (CurTok == ')')
+            break;
 
           if (CurTok != ',')
             return Error("Expected ')' or ',' in argument list");
@@ -280,7 +296,7 @@ function calls:
       // Eat the ')'.
       getNextToken();
 
-      return new CallExprAST(IdName, Args);
+      return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
     }
 
 This routine follows the same style as the other routines. (It expects
@@ -305,12 +321,16 @@ primary expression, we need to determine what sort of expression it is:
     ///   ::= identifierexpr
     ///   ::= numberexpr
     ///   ::= parenexpr
-    static ExprAST *ParsePrimary() {
+    static std::unique_ptr<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();
+      default:
+        return Error("unknown token when expecting an expression");
+      case tok_identifier:
+        return ParseIdentifierExpr();
+      case tok_number:
+        return ParseNumberExpr();
+      case '(':
+        return ParseParenExpr();
       }
     }
 
@@ -392,11 +412,12 @@ a sequence of [binop,primaryexpr] pairs:
     /// expression
     ///   ::= primary binoprhs
     ///
-    static ExprAST *ParseExpression() {
-      ExprAST *LHS = ParsePrimary();
-      if (!LHS) return 0;
+    static std::unique_ptr<ExprAST> ParseExpression() {
+      auto LHS = ParsePrimary();
+      if (!LHS)
+        return nullptr;
 
-      return ParseBinOpRHS(0, LHS);
+      return ParseBinOpRHS(0, std::move(LHS));
     }
 
 ``ParseBinOpRHS`` is the function that parses the sequence of pairs for
@@ -418,7 +439,8 @@ starts with:
 
     /// binoprhs
     ///   ::= ('+' primary)*
-    static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+    static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+                                                  std::unique_ptr<ExprAST> LHS) {
       // If this is a binop, find its precedence.
       while (1) {
         int TokPrec = GetTokPrecedence();
@@ -442,8 +464,9 @@ expression:
         getNextToken();  // eat binop
 
         // Parse the primary expression after the binary operator.
-        ExprAST *RHS = ParsePrimary();
-        if (!RHS) return 0;
+        auto RHS = ParsePrimary();
+        if (!RHS)
+          return nullptr;
 
 As such, this code eats (and remembers) the binary operator and then
 parses the primary expression that follows. This builds up the whole
@@ -476,7 +499,8 @@ then continue parsing:
         }
 
         // Merge LHS/RHS.
-        LHS = new BinaryExprAST(BinOp, LHS, RHS);
+        LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+                                               std::move(RHS));
       }  // loop around to the top of the while loop.
     }
 
@@ -500,11 +524,13 @@ above two blocks duplicated for context):
         // the pending operator take RHS as its LHS.
         int NextPrec = GetTokPrecedence();
         if (TokPrec < NextPrec) {
-          RHS = ParseBinOpRHS(TokPrec+1, RHS);
-          if (RHS == 0) return 0;
+          RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
+          if (!RHS)
+            return nullptr;
         }
         // Merge LHS/RHS.
-        LHS = new BinaryExprAST(BinOp, LHS, RHS);
+        LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+                                               std::move(RHS));
       }  // loop around to the top of the while loop.
     }
 
@@ -543,7 +569,7 @@ expressions):
 
     /// prototype
     ///   ::= id '(' id* ')'
-    static PrototypeAST *ParsePrototype() {
+    static std::unique_ptr<PrototypeAST> ParsePrototype() {
       if (CurTok != tok_identifier)
         return ErrorP("Expected function name in prototype");
 
@@ -563,7 +589,7 @@ expressions):
       // success.
       getNextToken();  // eat ')'.
 
-      return new PrototypeAST(FnName, ArgNames);
+      return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
     }
 
 Given this, a function definition is very simple, just a prototype plus
@@ -572,14 +598,14 @@ an expression to implement the body:
 .. code-block:: c++
 
     /// definition ::= 'def' prototype expression
-    static FunctionAST *ParseDefinition() {
+    static std::unique_ptr<FunctionAST> ParseDefinition() {
       getNextToken();  // eat def.
-      PrototypeAST *Proto = ParsePrototype();
-      if (Proto == 0) return 0;
+      auto Proto = ParsePrototype();
+      if (!Proto) return nullptr;
 
-      if (ExprAST *E = ParseExpression())
-        return new FunctionAST(Proto, E);
-      return 0;
+      if (auto E = ParseExpression())
+        return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+      return nullptr;
     }
 
 In addition, we support 'extern' to declare functions like 'sin' and
@@ -589,7 +615,7 @@ In addition, we support 'extern' to declare functions like 'sin' and
 .. code-block:: c++
 
     /// external ::= 'extern' prototype
-    static PrototypeAST *ParseExtern() {
+    static std::unique_ptr<PrototypeAST> ParseExtern() {
       getNextToken();  // eat extern.
       return ParsePrototype();
     }
@@ -601,13 +627,13 @@ nullary (zero argument) functions for them:
 .. code-block:: c++
 
     /// toplevelexpr ::= expression
-    static FunctionAST *ParseTopLevelExpr() {
-      if (ExprAST *E = ParseExpression()) {
+    static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+      if (auto E = ParseExpression()) {
         // Make an anonymous proto.
-        PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
-        return new FunctionAST(Proto, E);
+        auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+        return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
       }
-      return 0;
+      return nullptr;
     }
 
 Now that we have all the pieces, let's build a little driver that will
@@ -628,11 +654,20 @@ include the top-level loop. See `below <#code>`_ for full code in the
       while (1) {
         fprintf(stderr, "ready> ");
         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;
+        case tok_eof:
+          return;
+        case ';': // ignore top-level semicolons.
+          getNextToken();
+          break;
+        case tok_def:
+          HandleDefinition();
+          break;
+        case tok_extern:
+          HandleExtern();
+          break;
+        default:
+          HandleTopLevelExpression();
+          break;
         }
       }
     }
@@ -693,406 +728,8 @@ libraries, of course.) To build this, just compile with:
 
 Here is the code:
 
-.. code-block:: c++
-
-    #include <cstdio>
-    #include <cstdlib>
-    #include <string>
-    #include <map>
-    #include <vector>
-
-    //===----------------------------------------------------------------------===//
-    // 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
-    };
-
-    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;
-        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 && LastChar != '\n' && 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() {}
-    };
-
-    /// NumberExprAST - Expression class for numeric literals like "1.0".
-    class NumberExprAST : public ExprAST {
-      double Val;
-    public:
-      NumberExprAST(double val) : Val(val) {}
-    };
-
-    /// VariableExprAST - Expression class for referencing a variable, like "a".
-    class VariableExprAST : public ExprAST {
-      std::string Name;
-    public:
-      VariableExprAST(const std::string &name) : Name(name) {}
-    };
-
-    /// 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) {}
-    };
-
-    /// CallExprAST - Expression class for function calls.
-    class CallExprAST : public ExprAST {
-      std::string Callee;
-      std::vector<ExprAST*> Args;
-    public:
-      CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
-        : Callee(callee), Args(args) {}
-    };
-
-    /// PrototypeAST - This class represents the "prototype" for a function,
-    /// which captures its name, and its argument names (thus implicitly the number
-    /// of arguments the function takes).
-    class PrototypeAST {
-      std::string Name;
-      std::vector<std::string> Args;
-    public:
-      PrototypeAST(const std::string &name, const std::vector<std::string> &args)
-        : Name(name), Args(args) {}
-
-    };
-
-    /// FunctionAST - This class represents a function definition itself.
-    class FunctionAST {
-      PrototypeAST *Proto;
-      ExprAST *Body;
-    public:
-      FunctionAST(PrototypeAST *proto, ExprAST *body)
-        : Proto(proto), Body(body) {}
-
-    };
-
-    //===----------------------------------------------------------------------===//
-    // Parser
-    //===----------------------------------------------------------------------===//
-
-    /// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
-    /// token the parser is 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<char, int> 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 <= 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
-    ///   ::= identifier
-    ///   ::= identifier '(' expression* ')'
-    static ExprAST *ParseIdentifierExpr() {
-      std::string IdName = IdentifierStr;
-
-      getNextToken();  // eat identifier.
-
-      if (CurTok != '(') // Simple variable ref.
-        return new VariableExprAST(IdName);
-
-      // Call.
-      getNextToken();  // eat (
-      std::vector<ExprAST*> Args;
-      if (CurTok != ')') {
-        while (1) {
-          ExprAST *Arg = ParseExpression();
-          if (!Arg) return 0;
-          Args.push_back(Arg);
-
-          if (CurTok == ')') break;
-
-          if (CurTok != ',')
-            return Error("Expected ')' or ',' in argument list");
-          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;
-    }
-
-    /// primary
-    ///   ::= identifierexpr
-    ///   ::= numberexpr
-    ///   ::= parenexpr
-    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();
-      }
-    }
-
-    /// binoprhs
-    ///   ::= ('+' primary)*
-    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 < ExprPrec)
-          return LHS;
-
-        // Okay, we know this is a binop.
-        int BinOp = CurTok;
-        getNextToken();  // eat binop
-
-        // Parse the primary expression after the binary operator.
-        ExprAST *RHS = ParsePrimary();
-        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 < NextPrec) {
-          RHS = ParseBinOpRHS(TokPrec+1, RHS);
-          if (RHS == 0) return 0;
-        }
-
-        // Merge LHS/RHS.
-        LHS = new BinaryExprAST(BinOp, LHS, RHS);
-      }
-    }
-
-    /// expression
-    ///   ::= primary binoprhs
-    ///
-    static ExprAST *ParseExpression() {
-      ExprAST *LHS = ParsePrimary();
-      if (!LHS) return 0;
-
-      return ParseBinOpRHS(0, LHS);
-    }
-
-    /// prototype
-    ///   ::= id '(' id* ')'
-    static PrototypeAST *ParsePrototype() {
-      if (CurTok != tok_identifier)
-        return ErrorP("Expected function name in prototype");
-
-      std::string FnName = IdentifierStr;
-      getNextToken();
-
-      if (CurTok != '(')
-        return ErrorP("Expected '(' in prototype");
-
-      std::vector<std::string> ArgNames;
-      while (getNextToken() == tok_identifier)
-        ArgNames.push_back(IdentifierStr);
-      if (CurTok != ')')
-        return ErrorP("Expected ')' in prototype");
-
-      // success.
-      getNextToken();  // eat ')'.
-
-      return new PrototypeAST(FnName, ArgNames);
-    }
-
-    /// 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<std::string>());
-        return new FunctionAST(Proto, E);
-      }
-      return 0;
-    }
-
-    /// external ::= 'extern' prototype
-    static PrototypeAST *ParseExtern() {
-      getNextToken();  // eat extern.
-      return ParsePrototype();
-    }
-
-    //===----------------------------------------------------------------------===//
-    // Top-Level parsing
-    //===----------------------------------------------------------------------===//
-
-    static void HandleDefinition() {
-      if (ParseDefinition()) {
-        fprintf(stderr, "Parsed a function definition.\n");
-      } else {
-        // Skip token for error recovery.
-        getNextToken();
-      }
-    }
-
-    static void HandleExtern() {
-      if (ParseExtern()) {
-        fprintf(stderr, "Parsed an extern\n");
-      } else {
-        // Skip token for error recovery.
-        getNextToken();
-      }
-    }
-
-    static void HandleTopLevelExpression() {
-      // Evaluate a top-level expression into an anonymous function.
-      if (ParseTopLevelExpr()) {
-        fprintf(stderr, "Parsed a top-level expr\n");
-      } else {
-        // Skip token for error recovery.
-        getNextToken();
-      }
-    }
-
-    /// top ::= definition | external | expression | ';'
-    static void MainLoop() {
-      while (1) {
-        fprintf(stderr, "ready> ");
-        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;
-        }
-      }
-    }
-
-    //===----------------------------------------------------------------------===//
-    // Main driver code.
-    //===----------------------------------------------------------------------===//
-
-    int main() {
-      // Install standard binary operators.
-      // 1 is lowest precedence.
-      BinopPrecedence['<'] = 10;
-      BinopPrecedence['+'] = 20;
-      BinopPrecedence['-'] = 20;
-      BinopPrecedence['*'] = 40;  // highest.
-
-      // Prime the first token.
-      fprintf(stderr, "ready> ");
-      getNextToken();
-
-      // Run the main "interpreter loop" now.
-      MainLoop();
-
-      return 0;
-    }
+.. literalinclude:: ../../examples/Kaleidoscope/Chapter2/toy.cpp
+   :language: c++
 
 `Next: Implementing Code Generation to LLVM IR <LangImpl3.html>`_