<div dir="ltr">Yep. The earlier C/C++ Kaleidoscope implementations (from which this was adapted) were pretty laid back about memory safety. I've tried to fix parts of it up as I go (e.g. the AST no longer leaks), but there's a lot still to be done.<div><br></div><div>I'll fix this issue up. Patches are always welcome if you see other things that are obviously broken too.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 6, 2015 at 7:36 PM, Sean Silva <span dir="ltr"><<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class=""><span style="font-size:13px">+  if (V == 0) {</span><br style="font-size:13px"><span style="font-size:13px">+    char ErrStr[256];</span><br style="font-size:13px"><span style="font-size:13px">+    sprintf(ErrStr, "Unknown variable name %s", Name.c_str());</span><br style="font-size:13px"><span style="font-size:13px">+    return ErrorP<Value>(ErrStr);</span><br style="font-size:13px"><span style="font-size:13px">+  }</span><br><div><span style="font-size:13px"><br></span></div></span><div><span style="font-size:13px">Buffer overflow?</span></div><span class="HOEnZb"><font color="#888888"><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">-- Sean Silva</span></div><div><span style="font-size:13px"><br></span></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 6, 2015 at 2:52 PM, Lang Hames <span dir="ltr"><<a href="mailto:lhames@gmail.com" target="_blank">lhames@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Fri Feb  6 16:52:04 2015<br>
New Revision: 228456<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228456&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228456&view=rev</a><br>
Log:<br>
[Orc] Add a Kaleidoscope tutorial for Orc demonstrating eager compilation.<br>
<br>
This tutorial demonstrates a very basic custom Orc JIT stack that performs eager<br>
compilation: All modules are CodeGen'd immediately upon being added to the JIT.<br>
<br>
<br>
Added:<br>
    llvm/trunk/examples/Kaleidoscope/Orc/<br>
    llvm/trunk/examples/Kaleidoscope/Orc/initial/<br>
    llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile<br>
    llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt<br>
    llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp<br>
<br>
Added: llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile?rev=228456&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile?rev=228456&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile (added)<br>
+++ llvm/trunk/examples/Kaleidoscope/Orc/initial/Makefile Fri Feb  6 16:52:04 2015<br>
@@ -0,0 +1,9 @@<br>
+.PHONY: all<br>
+all: toy<br>
+<br>
+toy: toy.cpp<br>
+       clang++ -std=c++11 toy.cpp -g -O0 -rdynamic -fno-rtti `llvm-config --cppflags --ldflags --system-libs --libs core orcjit native` -o toy<br>
+<br>
+.PHONY: clean<br>
+clean:<br>
+       rm -f toy<br>
<br>
Added: llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt?rev=228456&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt?rev=228456&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt (added)<br>
+++ llvm/trunk/examples/Kaleidoscope/Orc/initial/README.txt Fri Feb  6 16:52:04 2015<br>
@@ -0,0 +1,13 @@<br>
+//===----------------------------------------------------------------------===/<br>
+//                 Kaleidoscope with Orc - Initial Version<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+This version of Kaleidoscope with Orc demonstrates fully eager compilation. When<br>
+a function definition or top-level expression is entered it is immediately<br>
+translated (IRGen'd) to LLVM IR and added to the JIT, where it is code-gen'd to<br>
+native code and either stored (for function definitions) or executed (for<br>
+top-level expressions).<br>
+<br>
+This directory contain a Makefile that allow the code to be built in a<br>
+standalone manner, independent of the larger LLVM build infrastructure. To build<br>
+the program you will need to have 'clang++' and 'llvm-config' in your path.<br>
<br>
Added: llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp?rev=228456&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp?rev=228456&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp (added)<br>
+++ llvm/trunk/examples/Kaleidoscope/Orc/initial/toy.cpp Fri Feb  6 16:52:04 2015<br>
@@ -0,0 +1,1319 @@<br>
+#include "llvm/Analysis/Passes.h"<br>
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"<br>
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"<br>
+#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"<br>
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"<br>
+#include "llvm/IR/DataLayout.h"<br>
+#include "llvm/IR/DerivedTypes.h"<br>
+#include "llvm/IR/IRBuilder.h"<br>
+#include "llvm/IR/LLVMContext.h"<br>
+#include "llvm/IR/Module.h"<br>
+#include "llvm/IR/Verifier.h"<br>
+#include "llvm/PassManager.h"<br>
+#include "llvm/Support/TargetSelect.h"<br>
+#include "llvm/Transforms/Scalar.h"<br>
+#include <cctype><br>
+#include <cstdio><br>
+#include <map><br>
+#include <string><br>
+#include <vector><br>
+using namespace llvm;<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Lexer<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one<br>
+// of these for known things.<br>
+enum Token {<br>
+  tok_eof = -1,<br>
+<br>
+  // commands<br>
+  tok_def = -2, tok_extern = -3,<br>
+<br>
+  // primary<br>
+  tok_identifier = -4, tok_number = -5,<br>
+<br>
+  // control<br>
+  tok_if = -6, tok_then = -7, tok_else = -8,<br>
+  tok_for = -9, tok_in = -10,<br>
+<br>
+  // operators<br>
+  tok_binary = -11, tok_unary = -12,<br>
+<br>
+  // var definition<br>
+  tok_var = -13<br>
+};<br>
+<br>
+static std::string IdentifierStr;  // Filled in if tok_identifier<br>
+static double NumVal;              // Filled in if tok_number<br>
+<br>
+/// gettok - Return the next token from standard input.<br>
+static int gettok() {<br>
+  static int LastChar = ' ';<br>
+<br>
+  // Skip any whitespace.<br>
+  while (isspace(LastChar))<br>
+    LastChar = getchar();<br>
+<br>
+  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*<br>
+    IdentifierStr = LastChar;<br>
+    while (isalnum((LastChar = getchar())))<br>
+      IdentifierStr += LastChar;<br>
+<br>
+    if (IdentifierStr == "def") return tok_def;<br>
+    if (IdentifierStr == "extern") return tok_extern;<br>
+    if (IdentifierStr == "if") return tok_if;<br>
+    if (IdentifierStr == "then") return tok_then;<br>
+    if (IdentifierStr == "else") return tok_else;<br>
+    if (IdentifierStr == "for") return tok_for;<br>
+    if (IdentifierStr == "in") return tok_in;<br>
+    if (IdentifierStr == "binary") return tok_binary;<br>
+    if (IdentifierStr == "unary") return tok_unary;<br>
+    if (IdentifierStr == "var") return tok_var;<br>
+    return tok_identifier;<br>
+  }<br>
+<br>
+  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+<br>
+    std::string NumStr;<br>
+    do {<br>
+      NumStr += LastChar;<br>
+      LastChar = getchar();<br>
+    } while (isdigit(LastChar) || LastChar == '.');<br>
+<br>
+    NumVal = strtod(NumStr.c_str(), 0);<br>
+    return tok_number;<br>
+  }<br>
+<br>
+  if (LastChar == '#') {<br>
+    // Comment until end of line.<br>
+    do LastChar = getchar();<br>
+    while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');<br>
+<br>
+    if (LastChar != EOF)<br>
+      return gettok();<br>
+  }<br>
+<br>
+  // Check for end of file.  Don't eat the EOF.<br>
+  if (LastChar == EOF)<br>
+    return tok_eof;<br>
+<br>
+  // Otherwise, just return the character as its ascii value.<br>
+  int ThisChar = LastChar;<br>
+  LastChar = getchar();<br>
+  return ThisChar;<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Abstract Syntax Tree (aka Parse Tree)<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+class IRGenContext;<br>
+<br>
+/// ExprAST - Base class for all expression nodes.<br>
+struct ExprAST {<br>
+  virtual ~ExprAST() {}<br>
+  virtual Value* IRGen(IRGenContext &C) = 0;<br>
+};<br>
+<br>
+/// NumberExprAST - Expression class for numeric literals like "1.0".<br>
+struct NumberExprAST : public ExprAST {<br>
+  NumberExprAST(double Val) : Val(Val) {}<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  double Val;<br>
+};<br>
+<br>
+/// VariableExprAST - Expression class for referencing a variable, like "a".<br>
+struct VariableExprAST : public ExprAST {<br>
+  VariableExprAST(std::string Name) : Name(std::move(Name)) {}<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  std::string Name;<br>
+};<br>
+<br>
+/// UnaryExprAST - Expression class for a unary operator.<br>
+struct UnaryExprAST : public ExprAST {<br>
+  UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)<br>
+    : Opcode(std::move(Opcode)), Operand(std::move(Operand)) {}<br>
+<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  char Opcode;<br>
+  std::unique_ptr<ExprAST> Operand;<br>
+};<br>
+<br>
+/// BinaryExprAST - Expression class for a binary operator.<br>
+struct BinaryExprAST : public ExprAST {<br>
+  BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,<br>
+                std::unique_ptr<ExprAST> RHS)<br>
+    : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}<br>
+<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  char Op;<br>
+  std::unique_ptr<ExprAST> LHS, RHS;<br>
+};<br>
+<br>
+/// CallExprAST - Expression class for function calls.<br>
+struct CallExprAST : public ExprAST {<br>
+  CallExprAST(std::string CalleeName,<br>
+              std::vector<std::unique_ptr<ExprAST>> Args)<br>
+    : CalleeName(std::move(CalleeName)), Args(std::move(Args)) {}<br>
+<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  std::string CalleeName;<br>
+  std::vector<std::unique_ptr<ExprAST>> Args;<br>
+};<br>
+<br>
+/// IfExprAST - Expression class for if/then/else.<br>
+struct IfExprAST : public ExprAST {<br>
+  IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,<br>
+            std::unique_ptr<ExprAST> Else)<br>
+    : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  std::unique_ptr<ExprAST> Cond, Then, Else;<br>
+};<br>
+<br>
+/// ForExprAST - Expression class for for/in.<br>
+struct ForExprAST : public ExprAST {<br>
+  ForExprAST(std::string VarName, std::unique_ptr<ExprAST> Start,<br>
+             std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,<br>
+             std::unique_ptr<ExprAST> Body)<br>
+    : VarName(std::move(VarName)), Start(std::move(Start)), End(std::move(End)),<br>
+      Step(std::move(Step)), Body(std::move(Body)) {}<br>
+<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  std::string VarName;<br>
+  std::unique_ptr<ExprAST> Start, End, Step, Body;<br>
+};<br>
+<br>
+/// VarExprAST - Expression class for var/in<br>
+struct VarExprAST : public ExprAST {<br>
+  typedef std::pair<std::string, std::unique_ptr<ExprAST>> Binding;<br>
+  typedef std::vector<Binding> BindingList;<br>
+<br>
+  VarExprAST(BindingList VarBindings, std::unique_ptr<ExprAST> Body)<br>
+    : VarBindings(std::move(VarBindings)), Body(std::move(Body)) {}<br>
+<br>
+  Value* IRGen(IRGenContext &C) override;<br>
+<br>
+  BindingList VarBindings;<br>
+  std::unique_ptr<ExprAST> Body;<br>
+};<br>
+<br>
+/// PrototypeAST - This class represents the "prototype" for a function,<br>
+/// which captures its argument names as well as if it is an operator.<br>
+struct PrototypeAST {<br>
+  PrototypeAST(std::string Name, std::vector<std::string> Args,<br>
+               bool IsOperator = false, unsigned Precedence = 0)<br>
+    : Name(std::move(Name)), Args(std::move(Args)), IsOperator(IsOperator),<br>
+      Precedence(Precedence) {}<br>
+<br>
+  Function* IRGen(IRGenContext &C);<br>
+  void CreateArgumentAllocas(Function *F, IRGenContext &C);<br>
+<br>
+  bool isUnaryOp() const { return IsOperator && Args.size() == 1; }<br>
+  bool isBinaryOp() const { return IsOperator && Args.size() == 2; }<br>
+<br>
+  char getOperatorName() const {<br>
+    assert(isUnaryOp() || isBinaryOp());<br>
+    return Name[Name.size()-1];<br>
+  }<br>
+<br>
+  std::string Name;<br>
+  std::vector<std::string> Args;<br>
+  bool IsOperator;<br>
+  unsigned Precedence;  // Precedence if a binary op.<br>
+};<br>
+<br>
+/// FunctionAST - This class represents a function definition itself.<br>
+struct FunctionAST {<br>
+  FunctionAST(std::unique_ptr<PrototypeAST> Proto,<br>
+              std::unique_ptr<ExprAST> Body)<br>
+    : Proto(std::move(Proto)), Body(std::move(Body)) {}<br>
+<br>
+  Function* IRGen(IRGenContext &C);<br>
+<br>
+  std::unique_ptr<PrototypeAST> Proto;<br>
+  std::unique_ptr<ExprAST> Body;<br>
+};<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Parser<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current<br>
+/// token the parser is looking at.  getNextToken reads another token from the<br>
+/// lexer and updates CurTok with its results.<br>
+static int CurTok;<br>
+static int getNextToken() {<br>
+  return CurTok = gettok();<br>
+}<br>
+<br>
+/// BinopPrecedence - This holds the precedence for each binary operator that is<br>
+/// defined.<br>
+static std::map<char, int> BinopPrecedence;<br>
+<br>
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.<br>
+static int GetTokPrecedence() {<br>
+  if (!isascii(CurTok))<br>
+    return -1;<br>
+<br>
+  // Make sure it's a declared binop.<br>
+  int TokPrec = BinopPrecedence[CurTok];<br>
+  if (TokPrec <= 0) return -1;<br>
+  return TokPrec;<br>
+}<br>
+<br>
+template <typename T><br>
+std::unique_ptr<T> ErrorU(const char *Str) {<br>
+  fprintf(stderr, "Error: %s\n", Str);<br>
+  return nullptr;<br>
+}<br>
+<br>
+template <typename T><br>
+T* ErrorP(const char *Str) {<br>
+  fprintf(stderr, "Error: %s\n", Str);<br>
+  return nullptr;<br>
+}<br>
+<br>
+static std::unique_ptr<ExprAST> ParseExpression();<br>
+<br>
+/// identifierexpr<br>
+///   ::= identifier<br>
+///   ::= identifier '(' expression* ')'<br>
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {<br>
+  std::string IdName = IdentifierStr;<br>
+<br>
+  getNextToken();  // eat identifier.<br>
+<br>
+  if (CurTok != '(') // Simple variable ref.<br>
+    return llvm::make_unique<VariableExprAST>(IdName);<br>
+<br>
+  // Call.<br>
+  getNextToken();  // eat (<br>
+  std::vector<std::unique_ptr<ExprAST>> Args;<br>
+  if (CurTok != ')') {<br>
+    while (1) {<br>
+      auto Arg = ParseExpression();<br>
+      if (!Arg) return nullptr;<br>
+      Args.push_back(std::move(Arg));<br>
+<br>
+      if (CurTok == ')') break;<br>
+<br>
+      if (CurTok != ',')<br>
+        return ErrorU<CallExprAST>("Expected ')' or ',' in argument list");<br>
+      getNextToken();<br>
+    }<br>
+  }<br>
+<br>
+  // Eat the ')'.<br>
+  getNextToken();<br>
+<br>
+  return llvm::make_unique<CallExprAST>(IdName, std::move(Args));<br>
+}<br>
+<br>
+/// numberexpr ::= number<br>
+static std::unique_ptr<NumberExprAST> ParseNumberExpr() {<br>
+  auto Result = llvm::make_unique<NumberExprAST>(NumVal);<br>
+  getNextToken(); // consume the number<br>
+  return Result;<br>
+}<br>
+<br>
+/// parenexpr ::= '(' expression ')'<br>
+static std::unique_ptr<ExprAST> ParseParenExpr() {<br>
+  getNextToken();  // eat (.<br>
+  auto V = ParseExpression();<br>
+  if (!V)<br>
+    return nullptr;<br>
+<br>
+  if (CurTok != ')')<br>
+    return ErrorU<ExprAST>("expected ')'");<br>
+  getNextToken();  // eat ).<br>
+  return V;<br>
+}<br>
+<br>
+/// ifexpr ::= 'if' expression 'then' expression 'else' expression<br>
+static std::unique_ptr<ExprAST> ParseIfExpr() {<br>
+  getNextToken();  // eat the if.<br>
+<br>
+  // condition.<br>
+  auto Cond = ParseExpression();<br>
+  if (!Cond)<br>
+    return nullptr;<br>
+<br>
+  if (CurTok != tok_then)<br>
+    return ErrorU<ExprAST>("expected then");<br>
+  getNextToken();  // eat the then<br>
+<br>
+  auto Then = ParseExpression();<br>
+  if (!Then)<br>
+    return nullptr;<br>
+<br>
+  if (CurTok != tok_else)<br>
+    return ErrorU<ExprAST>("expected else");<br>
+<br>
+  getNextToken();<br>
+<br>
+  auto Else = ParseExpression();<br>
+  if (!Else)<br>
+    return nullptr;<br>
+<br>
+  return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),<br>
+                                      std::move(Else));<br>
+}<br>
+<br>
+/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression<br>
+static std::unique_ptr<ForExprAST> ParseForExpr() {<br>
+  getNextToken();  // eat the for.<br>
+<br>
+  if (CurTok != tok_identifier)<br>
+    return ErrorU<ForExprAST>("expected identifier after for");<br>
+<br>
+  std::string IdName = IdentifierStr;<br>
+  getNextToken();  // eat identifier.<br>
+<br>
+  if (CurTok != '=')<br>
+    return ErrorU<ForExprAST>("expected '=' after for");<br>
+  getNextToken();  // eat '='.<br>
+<br>
+<br>
+  auto Start = ParseExpression();<br>
+  if (!Start)<br>
+    return nullptr;<br>
+  if (CurTok != ',')<br>
+    return ErrorU<ForExprAST>("expected ',' after for start value");<br>
+  getNextToken();<br>
+<br>
+  auto End = ParseExpression();<br>
+  if (!End)<br>
+    return nullptr;<br>
+<br>
+  // The step value is optional.<br>
+  std::unique_ptr<ExprAST> Step;<br>
+  if (CurTok == ',') {<br>
+    getNextToken();<br>
+    Step = ParseExpression();<br>
+    if (!Step)<br>
+      return nullptr;<br>
+  }<br>
+<br>
+  if (CurTok != tok_in)<br>
+    return ErrorU<ForExprAST>("expected 'in' after for");<br>
+  getNextToken();  // eat 'in'.<br>
+<br>
+  auto Body = ParseExpression();<br>
+  if (Body)<br>
+    return nullptr;<br>
+<br>
+  return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),<br>
+                                       std::move(Step), std::move(Body));<br>
+}<br>
+<br>
+/// varexpr ::= 'var' identifier ('=' expression)?<br>
+//                    (',' identifier ('=' expression)?)* 'in' expression<br>
+static std::unique_ptr<VarExprAST> ParseVarExpr() {<br>
+  getNextToken();  // eat the var.<br>
+<br>
+  VarExprAST::BindingList VarBindings;<br>
+<br>
+  // At least one variable name is required.<br>
+  if (CurTok != tok_identifier)<br>
+    return ErrorU<VarExprAST>("expected identifier after var");<br>
+<br>
+  while (1) {<br>
+    std::string Name = IdentifierStr;<br>
+    getNextToken();  // eat identifier.<br>
+<br>
+    // Read the optional initializer.<br>
+    std::unique_ptr<ExprAST> Init;<br>
+    if (CurTok == '=') {<br>
+      getNextToken(); // eat the '='.<br>
+<br>
+      Init = ParseExpression();<br>
+      if (!Init)<br>
+        return nullptr;<br>
+    }<br>
+<br>
+    VarBindings.push_back(VarExprAST::Binding(Name, std::move(Init)));<br>
+<br>
+    // End of var list, exit loop.<br>
+    if (CurTok != ',') break;<br>
+    getNextToken(); // eat the ','.<br>
+<br>
+    if (CurTok != tok_identifier)<br>
+      return ErrorU<VarExprAST>("expected identifier list after var");<br>
+  }<br>
+<br>
+  // At this point, we have to have 'in'.<br>
+  if (CurTok != tok_in)<br>
+    return ErrorU<VarExprAST>("expected 'in' keyword after 'var'");<br>
+  getNextToken();  // eat 'in'.<br>
+<br>
+  auto Body = ParseExpression();<br>
+  if (!Body)<br>
+    return nullptr;<br>
+<br>
+  return llvm::make_unique<VarExprAST>(std::move(VarBindings), std::move(Body));<br>
+}<br>
+<br>
+/// primary<br>
+///   ::= identifierexpr<br>
+///   ::= numberexpr<br>
+///   ::= parenexpr<br>
+///   ::= ifexpr<br>
+///   ::= forexpr<br>
+///   ::= varexpr<br>
+static std::unique_ptr<ExprAST> ParsePrimary() {<br>
+  switch (CurTok) {<br>
+  default: return ErrorU<ExprAST>("unknown token when expecting an expression");<br>
+  case tok_identifier: return ParseIdentifierExpr();<br>
+  case tok_number:     return ParseNumberExpr();<br>
+  case '(':            return ParseParenExpr();<br>
+  case tok_if:         return ParseIfExpr();<br>
+  case tok_for:        return ParseForExpr();<br>
+  case tok_var:        return ParseVarExpr();<br>
+  }<br>
+}<br>
+<br>
+/// unary<br>
+///   ::= primary<br>
+///   ::= '!' unary<br>
+static std::unique_ptr<ExprAST> ParseUnary() {<br>
+  // If the current token is not an operator, it must be a primary expr.<br>
+  if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')<br>
+    return ParsePrimary();<br>
+<br>
+  // If this is a unary operator, read it.<br>
+  int Opc = CurTok;<br>
+  getNextToken();<br>
+  if (auto Operand = ParseUnary())<br>
+    return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));<br>
+  return nullptr;<br>
+}<br>
+<br>
+/// binoprhs<br>
+///   ::= ('+' unary)*<br>
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,<br>
+                                              std::unique_ptr<ExprAST> LHS) {<br>
+  // If this is a binop, find its precedence.<br>
+  while (1) {<br>
+    int TokPrec = GetTokPrecedence();<br>
+<br>
+    // If this is a binop that binds at least as tightly as the current binop,<br>
+    // consume it, otherwise we are done.<br>
+    if (TokPrec < ExprPrec)<br>
+      return LHS;<br>
+<br>
+    // Okay, we know this is a binop.<br>
+    int BinOp = CurTok;<br>
+    getNextToken();  // eat binop<br>
+<br>
+    // Parse the unary expression after the binary operator.<br>
+    auto RHS = ParseUnary();<br>
+    if (!RHS)<br>
+      return nullptr;<br>
+<br>
+    // If BinOp binds less tightly with RHS than the operator after RHS, let<br>
+    // the pending operator take RHS as its LHS.<br>
+    int NextPrec = GetTokPrecedence();<br>
+    if (TokPrec < NextPrec) {<br>
+      RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));<br>
+      if (!RHS)<br>
+        return nullptr;<br>
+    }<br>
+<br>
+    // Merge LHS/RHS.<br>
+    LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));<br>
+  }<br>
+}<br>
+<br>
+/// expression<br>
+///   ::= unary binoprhs<br>
+///<br>
+static std::unique_ptr<ExprAST> ParseExpression() {<br>
+  auto LHS = ParseUnary();<br>
+  if (!LHS)<br>
+    return nullptr;<br>
+<br>
+  return ParseBinOpRHS(0, std::move(LHS));<br>
+}<br>
+<br>
+/// prototype<br>
+///   ::= id '(' id* ')'<br>
+///   ::= binary LETTER number? (id, id)<br>
+///   ::= unary LETTER (id)<br>
+static std::unique_ptr<PrototypeAST> ParsePrototype() {<br>
+  std::string FnName;<br>
+<br>
+  unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.<br>
+  unsigned BinaryPrecedence = 30;<br>
+<br>
+  switch (CurTok) {<br>
+  default:<br>
+    return ErrorU<PrototypeAST>("Expected function name in prototype");<br>
+  case tok_identifier:<br>
+    FnName = IdentifierStr;<br>
+    Kind = 0;<br>
+    getNextToken();<br>
+    break;<br>
+  case tok_unary:<br>
+    getNextToken();<br>
+    if (!isascii(CurTok))<br>
+      return ErrorU<PrototypeAST>("Expected unary operator");<br>
+    FnName = "unary";<br>
+    FnName += (char)CurTok;<br>
+    Kind = 1;<br>
+    getNextToken();<br>
+    break;<br>
+  case tok_binary:<br>
+    getNextToken();<br>
+    if (!isascii(CurTok))<br>
+      return ErrorU<PrototypeAST>("Expected binary operator");<br>
+    FnName = "binary";<br>
+    FnName += (char)CurTok;<br>
+    Kind = 2;<br>
+    getNextToken();<br>
+<br>
+    // Read the precedence if present.<br>
+    if (CurTok == tok_number) {<br>
+      if (NumVal < 1 || NumVal > 100)<br>
+        return ErrorU<PrototypeAST>("Invalid precedecnce: must be 1..100");<br>
+      BinaryPrecedence = (unsigned)NumVal;<br>
+      getNextToken();<br>
+    }<br>
+    break;<br>
+  }<br>
+<br>
+  if (CurTok != '(')<br>
+    return ErrorU<PrototypeAST>("Expected '(' in prototype");<br>
+<br>
+  std::vector<std::string> ArgNames;<br>
+  while (getNextToken() == tok_identifier)<br>
+    ArgNames.push_back(IdentifierStr);<br>
+  if (CurTok != ')')<br>
+    return ErrorU<PrototypeAST>("Expected ')' in prototype");<br>
+<br>
+  // success.<br>
+  getNextToken();  // eat ')'.<br>
+<br>
+  // Verify right number of names for operator.<br>
+  if (Kind && ArgNames.size() != Kind)<br>
+    return ErrorU<PrototypeAST>("Invalid number of operands for operator");<br>
+<br>
+  return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,<br>
+                                         BinaryPrecedence);<br>
+}<br>
+<br>
+/// definition ::= 'def' prototype expression<br>
+static std::unique_ptr<FunctionAST> ParseDefinition() {<br>
+  getNextToken();  // eat def.<br>
+  auto Proto = ParsePrototype();<br>
+  if (!Proto)<br>
+    return nullptr;<br>
+<br>
+  if (auto Body = ParseExpression())<br>
+    return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(Body));<br>
+  return nullptr;<br>
+}<br>
+<br>
+/// toplevelexpr ::= expression<br>
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {<br>
+  if (auto E = ParseExpression()) {<br>
+    // Make an anonymous proto.<br>
+    auto Proto =<br>
+      llvm::make_unique<PrototypeAST>("__anon_expr", std::vector<std::string>());<br>
+    return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));<br>
+  }<br>
+  return nullptr;<br>
+}<br>
+<br>
+/// external ::= 'extern' prototype<br>
+static std::unique_ptr<PrototypeAST> ParseExtern() {<br>
+  getNextToken();  // eat extern.<br>
+  return ParsePrototype();<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Code Generation<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// FIXME: Obviously we can do better than this<br>
+std::string GenerateUniqueName(const char *root)<br>
+{<br>
+  static int i = 0;<br>
+  char s[16];<br>
+  sprintf(s, "%s%d", root, i++);<br>
+  std::string S = s;<br>
+  return S;<br>
+}<br>
+<br>
+std::string MakeLegalFunctionName(std::string Name)<br>
+{<br>
+  std::string NewName;<br>
+  assert(!Name.empty() && "Base name must not be empty");<br>
+<br>
+  // Start with what we have<br>
+  NewName = Name;<br>
+<br>
+  // Look for a numberic first character<br>
+  if (NewName.find_first_of("0123456789") == 0) {<br>
+    NewName.insert(0, 1, 'n');<br>
+  }<br>
+<br>
+  // Replace illegal characters with their ASCII equivalent<br>
+  std::string legal_elements = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";<br>
+  size_t pos;<br>
+  while ((pos = NewName.find_first_not_of(legal_elements)) != std::string::npos) {<br>
+    char old_c = NewName.at(pos);<br>
+    char new_str[16];<br>
+    sprintf(new_str, "%d", (int)old_c);<br>
+    NewName = NewName.replace(pos, 1, new_str);<br>
+  }<br>
+<br>
+  return NewName;<br>
+}<br>
+<br>
+class SessionContext {<br>
+public:<br>
+  SessionContext(LLVMContext &C) : Context(C) {}<br>
+  LLVMContext& getLLVMContext() const { return Context; }<br>
+  void addPrototypeAST(std::unique_ptr<PrototypeAST> P);<br>
+  PrototypeAST* getPrototypeAST(const std::string &Name);<br>
+private:<br>
+  typedef std::map<std::string, std::unique_ptr<PrototypeAST>> PrototypeMap;<br>
+  LLVMContext &Context;<br>
+  PrototypeMap Prototypes;<br>
+};<br>
+<br>
+void SessionContext::addPrototypeAST(std::unique_ptr<PrototypeAST> P) {<br>
+  Prototypes[P->Name] = std::move(P);<br>
+}<br>
+<br>
+PrototypeAST* SessionContext::getPrototypeAST(const std::string &Name) {<br>
+  PrototypeMap::iterator I = Prototypes.find(Name);<br>
+  if (I != Prototypes.end())<br>
+    return I->second.get();<br>
+  return nullptr;<br>
+}<br>
+<br>
+class IRGenContext {<br>
+public:<br>
+<br>
+  IRGenContext(SessionContext &S)<br>
+    : Session(S),<br>
+      M(new Module(GenerateUniqueName("jit_module_"),<br>
+                   Session.getLLVMContext())),<br>
+      Builder(Session.getLLVMContext()) {}<br>
+<br>
+  SessionContext& getSession() { return Session; }<br>
+  Module& getM() const { return *M; }<br>
+  std::unique_ptr<Module> takeM() { return std::move(M); }<br>
+  IRBuilder<>& getBuilder() { return Builder; }<br>
+  LLVMContext& getLLVMContext() { return Session.getLLVMContext(); }<br>
+  Function* getPrototype(const std::string &Name);<br>
+<br>
+  std::map<std::string, AllocaInst*> NamedValues;<br>
+private:<br>
+  SessionContext &Session;<br>
+  std::unique_ptr<Module> M;<br>
+  IRBuilder<> Builder;<br>
+};<br>
+<br>
+Function* IRGenContext::getPrototype(const std::string &Name) {<br>
+  if (Function *ExistingProto = M->getFunction(Name))<br>
+    return ExistingProto;<br>
+  if (PrototypeAST *ProtoAST = Session.getPrototypeAST(Name))<br>
+    return ProtoAST->IRGen(*this);<br>
+  return nullptr;<br>
+}<br>
+<br>
+/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of<br>
+/// the function.  This is used for mutable variables etc.<br>
+static AllocaInst *CreateEntryBlockAlloca(Function *TheFunction,<br>
+                                          const std::string &VarName) {<br>
+  IRBuilder<> TmpB(&TheFunction->getEntryBlock(),<br>
+                 TheFunction->getEntryBlock().begin());<br>
+  return TmpB.CreateAlloca(Type::getDoubleTy(getGlobalContext()), 0,<br>
+                           VarName.c_str());<br>
+}<br>
+<br>
+Value *NumberExprAST::IRGen(IRGenContext &C) {<br>
+  return ConstantFP::get(C.getLLVMContext(), APFloat(Val));<br>
+}<br>
+<br>
+Value *VariableExprAST::IRGen(IRGenContext &C) {<br>
+  // Look this variable up in the function.<br>
+  Value *V = C.NamedValues[Name];<br>
+<br>
+  if (V == 0) {<br>
+    char ErrStr[256];<br>
+    sprintf(ErrStr, "Unknown variable name %s", Name.c_str());<br>
+    return ErrorP<Value>(ErrStr);<br>
+  }<br>
+<br>
+  // Load the value.<br>
+  return C.getBuilder().CreateLoad(V, Name.c_str());<br>
+}<br>
+<br>
+Value *UnaryExprAST::IRGen(IRGenContext &C) {<br>
+  if (Value *OperandV = Operand->IRGen(C)) {<br>
+    std::string FnName = MakeLegalFunctionName(std::string("unary")+Opcode);<br>
+    if (Function *F = C.getPrototype(FnName))<br>
+      return C.getBuilder().CreateCall(F, OperandV, "unop");<br>
+    return ErrorP<Value>("Unknown unary operator");<br>
+  }<br>
+<br>
+  // Could not codegen operand - return null.<br>
+  return nullptr;<br>
+}<br>
+<br>
+Value *BinaryExprAST::IRGen(IRGenContext &C) {<br>
+  // Special case '=' because we don't want to emit the LHS as an expression.<br>
+  if (Op == '=') {<br>
+    // Assignment requires the LHS to be an identifier.<br>
+    auto LHSVar = static_cast<VariableExprAST&>(*LHS);<br>
+    // Codegen the RHS.<br>
+    Value *Val = RHS->IRGen(C);<br>
+    if (!Val) return nullptr;<br>
+<br>
+    // Look up the name.<br>
+    if (auto Variable = C.NamedValues[LHSVar.Name]) {<br>
+      C.getBuilder().CreateStore(Val, Variable);<br>
+      return Val;<br>
+    }<br>
+    return ErrorP<Value>("Unknown variable name");<br>
+  }<br>
+<br>
+  Value *L = LHS->IRGen(C);<br>
+  Value *R = RHS->IRGen(C);<br>
+  if (!L || !R) return nullptr;<br>
+<br>
+  switch (Op) {<br>
+  case '+': return C.getBuilder().CreateFAdd(L, R, "addtmp");<br>
+  case '-': return C.getBuilder().CreateFSub(L, R, "subtmp");<br>
+  case '*': return C.getBuilder().CreateFMul(L, R, "multmp");<br>
+  case '/': return C.getBuilder().CreateFDiv(L, R, "divtmp");<br>
+  case '<':<br>
+    L = C.getBuilder().CreateFCmpULT(L, R, "cmptmp");<br>
+    // Convert bool 0/1 to double 0.0 or 1.0<br>
+    return C.getBuilder().CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),<br>
+                                "booltmp");<br>
+  default: break;<br>
+  }<br>
+<br>
+  // If it wasn't a builtin binary operator, it must be a user defined one. Emit<br>
+  // a call to it.<br>
+  std::string FnName = MakeLegalFunctionName(std::string("binary")+Op);<br>
+  if (Function *F = C.getPrototype(FnName)) {<br>
+    Value *Ops[] = { L, R };<br>
+    return C.getBuilder().CreateCall(F, Ops, "binop");<br>
+  }<br>
+<br>
+  return ErrorP<Value>("Unknown binary operator");<br>
+}<br>
+<br>
+Value *CallExprAST::IRGen(IRGenContext &C) {<br>
+  // Look up the name in the global module table.<br>
+  if (auto CalleeF = C.getPrototype(CalleeName)) {<br>
+    // If argument mismatch error.<br>
+    if (CalleeF->arg_size() != Args.size())<br>
+      return ErrorP<Value>("Incorrect # arguments passed");<br>
+<br>
+    std::vector<Value*> ArgsV;<br>
+    for (unsigned i = 0, e = Args.size(); i != e; ++i) {<br>
+      ArgsV.push_back(Args[i]->IRGen(C));<br>
+      if (!ArgsV.back()) return nullptr;<br>
+    }<br>
+<br>
+    return C.getBuilder().CreateCall(CalleeF, ArgsV, "calltmp");<br>
+  }<br>
+<br>
+  return ErrorP<Value>("Unknown function referenced");<br>
+}<br>
+<br>
+Value *IfExprAST::IRGen(IRGenContext &C) {<br>
+  Value *CondV = Cond->IRGen(C);<br>
+  if (!CondV) return nullptr;<br>
+<br>
+  // Convert condition to a bool by comparing equal to 0.0.<br>
+  ConstantFP *FPZero =<br>
+    ConstantFP::get(C.getLLVMContext(), APFloat(0.0));<br>
+  CondV = C.getBuilder().CreateFCmpONE(CondV, FPZero, "ifcond");<br>
+<br>
+  Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();<br>
+<br>
+  // Create blocks for the then and else cases.  Insert the 'then' block at the<br>
+  // end of the function.<br>
+  BasicBlock *ThenBB = BasicBlock::Create(C.getLLVMContext(), "then", TheFunction);<br>
+  BasicBlock *ElseBB = BasicBlock::Create(C.getLLVMContext(), "else");<br>
+  BasicBlock *MergeBB = BasicBlock::Create(C.getLLVMContext(), "ifcont");<br>
+<br>
+  C.getBuilder().CreateCondBr(CondV, ThenBB, ElseBB);<br>
+<br>
+  // Emit then value.<br>
+  C.getBuilder().SetInsertPoint(ThenBB);<br>
+<br>
+  Value *ThenV = Then->IRGen(C);<br>
+  if (!ThenV) return nullptr;<br>
+<br>
+  C.getBuilder().CreateBr(MergeBB);<br>
+  // Codegen of 'Then' can change the current block, update ThenBB for the PHI.<br>
+  ThenBB = C.getBuilder().GetInsertBlock();<br>
+<br>
+  // Emit else block.<br>
+  TheFunction->getBasicBlockList().push_back(ElseBB);<br>
+  C.getBuilder().SetInsertPoint(ElseBB);<br>
+<br>
+  Value *ElseV = Else->IRGen(C);<br>
+  if (!ElseV) return nullptr;<br>
+<br>
+  C.getBuilder().CreateBr(MergeBB);<br>
+  // Codegen of 'Else' can change the current block, update ElseBB for the PHI.<br>
+  ElseBB = C.getBuilder().GetInsertBlock();<br>
+<br>
+  // Emit merge block.<br>
+  TheFunction->getBasicBlockList().push_back(MergeBB);<br>
+  C.getBuilder().SetInsertPoint(MergeBB);<br>
+  PHINode *PN = C.getBuilder().CreatePHI(Type::getDoubleTy(getGlobalContext()), 2,<br>
+                                  "iftmp");<br>
+<br>
+  PN->addIncoming(ThenV, ThenBB);<br>
+  PN->addIncoming(ElseV, ElseBB);<br>
+  return PN;<br>
+}<br>
+<br>
+Value *ForExprAST::IRGen(IRGenContext &C) {<br>
+  // Output this as:<br>
+  //   var = alloca double<br>
+  //   ...<br>
+  //   start = startexpr<br>
+  //   store start -> var<br>
+  //   goto loop<br>
+  // loop:<br>
+  //   ...<br>
+  //   bodyexpr<br>
+  //   ...<br>
+  // loopend:<br>
+  //   step = stepexpr<br>
+  //   endcond = endexpr<br>
+  //<br>
+  //   curvar = load var<br>
+  //   nextvar = curvar + step<br>
+  //   store nextvar -> var<br>
+  //   br endcond, loop, endloop<br>
+  // outloop:<br>
+<br>
+  Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();<br>
+<br>
+  // Create an alloca for the variable in the entry block.<br>
+  AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);<br>
+<br>
+  // Emit the start code first, without 'variable' in scope.<br>
+  Value *StartVal = Start->IRGen(C);<br>
+  if (!StartVal) return nullptr;<br>
+<br>
+  // Store the value into the alloca.<br>
+  C.getBuilder().CreateStore(StartVal, Alloca);<br>
+<br>
+  // Make the new basic block for the loop header, inserting after current<br>
+  // block.<br>
+  BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction);<br>
+<br>
+  // Insert an explicit fall through from the current block to the LoopBB.<br>
+  C.getBuilder().CreateBr(LoopBB);<br>
+<br>
+  // Start insertion in LoopBB.<br>
+  C.getBuilder().SetInsertPoint(LoopBB);<br>
+<br>
+  // Within the loop, the variable is defined equal to the PHI node.  If it<br>
+  // shadows an existing variable, we have to restore it, so save it now.<br>
+  AllocaInst *OldVal = C.NamedValues[VarName];<br>
+  C.NamedValues[VarName] = Alloca;<br>
+<br>
+  // Emit the body of the loop.  This, like any other expr, can change the<br>
+  // current BB.  Note that we ignore the value computed by the body, but don't<br>
+  // allow an error.<br>
+  if (!Body->IRGen(C))<br>
+    return nullptr;<br>
+<br>
+  // Emit the step value.<br>
+  Value *StepVal;<br>
+  if (Step) {<br>
+    StepVal = Step->IRGen(C);<br>
+    if (!StepVal) return nullptr;<br>
+  } else {<br>
+    // If not specified, use 1.0.<br>
+    StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));<br>
+  }<br>
+<br>
+  // Compute the end condition.<br>
+  Value *EndCond = End->IRGen(C);<br>
+  if (EndCond == 0) return EndCond;<br>
+<br>
+  // Reload, increment, and restore the alloca.  This handles the case where<br>
+  // the body of the loop mutates the variable.<br>
+  Value *CurVar = C.getBuilder().CreateLoad(Alloca, VarName.c_str());<br>
+  Value *NextVar = C.getBuilder().CreateFAdd(CurVar, StepVal, "nextvar");<br>
+  C.getBuilder().CreateStore(NextVar, Alloca);<br>
+<br>
+  // Convert condition to a bool by comparing equal to 0.0.<br>
+  EndCond = C.getBuilder().CreateFCmpONE(EndCond,<br>
+                              ConstantFP::get(getGlobalContext(), APFloat(0.0)),<br>
+                                  "loopcond");<br>
+<br>
+  // Create the "after loop" block and insert it.<br>
+  BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);<br>
+<br>
+  // Insert the conditional branch into the end of LoopEndBB.<br>
+  C.getBuilder().CreateCondBr(EndCond, LoopBB, AfterBB);<br>
+<br>
+  // Any new code will be inserted in AfterBB.<br>
+  C.getBuilder().SetInsertPoint(AfterBB);<br>
+<br>
+  // Restore the unshadowed variable.<br>
+  if (OldVal)<br>
+    C.NamedValues[VarName] = OldVal;<br>
+  else<br>
+    C.NamedValues.erase(VarName);<br>
+<br>
+<br>
+  // for expr always returns 0.0.<br>
+  return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));<br>
+}<br>
+<br>
+Value *VarExprAST::IRGen(IRGenContext &C) {<br>
+  std::vector<AllocaInst *> OldBindings;<br>
+<br>
+  Function *TheFunction = C.getBuilder().GetInsertBlock()->getParent();<br>
+<br>
+  // Register all variables and emit their initializer.<br>
+  for (unsigned i = 0, e = VarBindings.size(); i != e; ++i) {<br>
+    auto &VarName = VarBindings[i].first;<br>
+    auto &Init = VarBindings[i].second;<br>
+<br>
+    // Emit the initializer before adding the variable to scope, this prevents<br>
+    // the initializer from referencing the variable itself, and permits stuff<br>
+    // like this:<br>
+    //  var a = 1 in<br>
+    //    var a = a in ...   # refers to outer 'a'.<br>
+    Value *InitVal;<br>
+    if (Init) {<br>
+      InitVal = Init->IRGen(C);<br>
+      if (!InitVal) return nullptr;<br>
+    } else // If not specified, use 0.0.<br>
+      InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));<br>
+<br>
+    AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName);<br>
+    C.getBuilder().CreateStore(InitVal, Alloca);<br>
+<br>
+    // Remember the old variable binding so that we can restore the binding when<br>
+    // we unrecurse.<br>
+    OldBindings.push_back(C.NamedValues[VarName]);<br>
+<br>
+    // Remember this binding.<br>
+    C.NamedValues[VarName] = Alloca;<br>
+  }<br>
+<br>
+  // Codegen the body, now that all vars are in scope.<br>
+  Value *BodyVal = Body->IRGen(C);<br>
+  if (!BodyVal) return nullptr;<br>
+<br>
+  // Pop all our variables from scope.<br>
+  for (unsigned i = 0, e = VarBindings.size(); i != e; ++i)<br>
+    C.NamedValues[VarBindings[i].first] = OldBindings[i];<br>
+<br>
+  // Return the body computation.<br>
+  return BodyVal;<br>
+}<br>
+<br>
+Function *PrototypeAST::IRGen(IRGenContext &C) {<br>
+  std::string FnName = MakeLegalFunctionName(Name);<br>
+<br>
+  // Make the function type:  double(double,double) etc.<br>
+  std::vector<Type*> Doubles(Args.size(),<br>
+                             Type::getDoubleTy(getGlobalContext()));<br>
+  FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),<br>
+                                       Doubles, false);<br>
+  Function *F = Function::Create(FT, Function::ExternalLinkage, FnName,<br>
+                                 &C.getM());<br>
+<br>
+  // If F conflicted, there was already something named 'FnName'.  If it has a<br>
+  // body, don't allow redefinition or reextern.<br>
+  if (F->getName() != FnName) {<br>
+    // Delete the one we just made and get the existing one.<br>
+    F->eraseFromParent();<br>
+    F = C.getM().getFunction(Name);<br>
+<br>
+    // If F already has a body, reject this.<br>
+    if (!F->empty()) {<br>
+      ErrorP<Function>("redefinition of function");<br>
+      return nullptr;<br>
+    }<br>
+<br>
+    // If F took a different number of args, reject.<br>
+    if (F->arg_size() != Args.size()) {<br>
+      ErrorP<Function>("redefinition of function with different # args");<br>
+      return nullptr;<br>
+    }<br>
+  }<br>
+<br>
+  // Set names for all arguments.<br>
+  unsigned Idx = 0;<br>
+  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();<br>
+       ++AI, ++Idx)<br>
+    AI->setName(Args[Idx]);<br>
+<br>
+  return F;<br>
+}<br>
+<br>
+/// CreateArgumentAllocas - Create an alloca for each argument and register the<br>
+/// argument in the symbol table so that references to it will succeed.<br>
+void PrototypeAST::CreateArgumentAllocas(Function *F, IRGenContext &C) {<br>
+  Function::arg_iterator AI = F->arg_begin();<br>
+  for (unsigned Idx = 0, e = Args.size(); Idx != e; ++Idx, ++AI) {<br>
+    // Create an alloca for this variable.<br>
+    AllocaInst *Alloca = CreateEntryBlockAlloca(F, Args[Idx]);<br>
+<br>
+    // Store the initial value into the alloca.<br>
+    C.getBuilder().CreateStore(AI, Alloca);<br>
+<br>
+    // Add arguments to variable symbol table.<br>
+    C.NamedValues[Args[Idx]] = Alloca;<br>
+  }<br>
+}<br>
+<br>
+Function *FunctionAST::IRGen(IRGenContext &C) {<br>
+  C.NamedValues.clear();<br>
+<br>
+  Function *TheFunction = Proto->IRGen(C);<br>
+  if (!TheFunction)<br>
+    return nullptr;<br>
+<br>
+  // If this is an operator, install it.<br>
+  if (Proto->isBinaryOp())<br>
+    BinopPrecedence[Proto->getOperatorName()] = Proto->Precedence;<br>
+<br>
+  // Create a new basic block to start insertion into.<br>
+  BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);<br>
+  C.getBuilder().SetInsertPoint(BB);<br>
+<br>
+  // Add all arguments to the symbol table and create their allocas.<br>
+  Proto->CreateArgumentAllocas(TheFunction, C);<br>
+<br>
+  if (Value *RetVal = Body->IRGen(C)) {<br>
+    // Finish off the function.<br>
+    C.getBuilder().CreateRet(RetVal);<br>
+<br>
+    // Validate the generated code, checking for consistency.<br>
+    verifyFunction(*TheFunction);<br>
+<br>
+    return TheFunction;<br>
+  }<br>
+<br>
+  // Error reading body, remove function.<br>
+  TheFunction->eraseFromParent();<br>
+<br>
+  if (Proto->isBinaryOp())<br>
+    BinopPrecedence.erase(Proto->getOperatorName());<br>
+  return nullptr;<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Top-Level parsing and JIT Driver<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+class KaleidoscopeJIT {<br>
+public:<br>
+  typedef ObjectLinkingLayer<> ObjLayerT;<br>
+  typedef IRCompileLayer<ObjLayerT> CompileLayerT;<br>
+<br>
+  typedef CompileLayerT::ModuleSetHandleT ModuleHandleT;<br>
+<br>
+  KaleidoscopeJIT()<br>
+    : TM(EngineBuilder().selectTarget()),<br>
+      Mang(TM->getDataLayout()),<br>
+      CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {}<br>
+<br>
+  ModuleHandleT addModule(std::unique_ptr<Module> M) {<br>
+    if (!M->getDataLayout())<br>
+      M->setDataLayout(TM->getDataLayout());<br>
+<br>
+    // The LazyEmitLayer takes lists of modules, rather than single modules, so<br>
+    // we'll just build a single-element list.<br>
+    std::vector<std::unique_ptr<Module>> S;<br>
+    S.push_back(std::move(M));<br>
+<br>
+    // We need a memory manager to allocate memory and resolve symbols for this<br>
+    // new module. Create one that resolves symbols by looking back into the JIT.<br>
+    auto MM = createLookasideRTDyldMM<SectionMemoryManager>(<br>
+                [&](const std::string &S) {<br>
+                  return getUnmangledSymbolAddress(S);<br>
+                },<br>
+                [](const std::string &S) { return 0; } );<br>
+<br>
+    return CompileLayer.addModuleSet(std::move(S), std::move(MM));<br>
+  }<br>
+<br>
+  void removeModule(ModuleHandleT H) { CompileLayer.removeModuleSet(H); }<br>
+<br>
+  uint64_t getUnmangledSymbolAddress(const std::string &Name) {<br>
+    return CompileLayer.getSymbolAddress(Name, false);<br>
+  }<br>
+<br>
+  uint64_t getSymbolAddress(const std::string Name) {<br>
+    std::string MangledName;<br>
+    {<br>
+      raw_string_ostream MangledNameStream(MangledName);<br>
+      Mang.getNameWithPrefix(MangledNameStream, Name);<br>
+    }<br>
+    return getUnmangledSymbolAddress(MangledName);<br>
+  }<br>
+<br>
+private:<br>
+<br>
+  std::unique_ptr<TargetMachine> TM;<br>
+  Mangler Mang;<br>
+<br>
+  ObjLayerT ObjectLayer;<br>
+  CompileLayerT CompileLayer;<br>
+};<br>
+<br>
+static void HandleDefinition(SessionContext &S, KaleidoscopeJIT &J) {<br>
+  if (auto F = ParseDefinition()) {<br>
+    IRGenContext C(S);<br>
+    if (auto LF = F->IRGen(C)) {<br>
+#ifndef MINIMAL_STDERR_OUTPUT<br>
+      fprintf(stderr, "Read function definition:");<br>
+      LF->dump();<br>
+#endif<br>
+      J.addModule(C.takeM());<br>
+      S.addPrototypeAST(llvm::make_unique<PrototypeAST>(*F->Proto));<br>
+    }<br>
+  } else {<br>
+    // Skip token for error recovery.<br>
+    getNextToken();<br>
+  }<br>
+}<br>
+<br>
+static void HandleExtern(SessionContext &S) {<br>
+  if (auto P = ParseExtern())<br>
+    S.addPrototypeAST(std::move(P));<br>
+  else {<br>
+    // Skip token for error recovery.<br>
+    getNextToken();<br>
+  }<br>
+}<br>
+<br>
+static void HandleTopLevelExpression(SessionContext &S, KaleidoscopeJIT &J) {<br>
+  // Evaluate a top-level expression into an anonymous function.<br>
+  if (auto F = ParseTopLevelExpr()) {<br>
+    IRGenContext C(S);<br>
+    if (auto ExprFunc = F->IRGen(C)) {<br>
+#ifndef MINIMAL_STDERR_OUTPUT<br>
+      fprintf(stderr, "Expression function:\n");<br>
+      ExprFunc->dump();<br>
+#endif<br>
+      // Add the CodeGen'd module to the JIT. Keep a handle to it: We can remove<br>
+      // this module as soon as we've executed Function ExprFunc.<br>
+      auto H = J.addModule(C.takeM());<br>
+<br>
+      // Get the address of the JIT'd function in memory.<br>
+      uint64_t ExprFuncAddr = J.getSymbolAddress("__anon_expr");<br>
+<br>
+      // Cast it to the right type (takes no arguments, returns a double) so we<br>
+      // can call it as a native function.<br>
+      double (*FP)() = (double (*)())(intptr_t)ExprFuncAddr;<br>
+#ifdef MINIMAL_STDERR_OUTPUT<br>
+      FP();<br>
+#else<br>
+      fprintf(stderr, "Evaluated to %f\n", FP());<br>
+#endif<br>
+<br>
+      // Remove the function.<br>
+      J.removeModule(H);<br>
+    }<br>
+  } else {<br>
+    // Skip token for error recovery.<br>
+    getNextToken();<br>
+  }<br>
+}<br>
+<br>
+/// top ::= definition | external | expression | ';'<br>
+static void MainLoop() {<br>
+  KaleidoscopeJIT J;<br>
+  SessionContext S(getGlobalContext());<br>
+<br>
+  while (1) {<br>
+#ifndef MINIMAL_STDERR_OUTPUT<br>
+    fprintf(stderr, "ready> ");<br>
+#endif<br>
+    switch (CurTok) {<br>
+    case tok_eof:    return;<br>
+    case ';':        getNextToken(); break;  // ignore top-level semicolons.<br>
+    case tok_def:    HandleDefinition(S, J); break;<br>
+    case tok_extern: HandleExtern(S); break;<br>
+    default:         HandleTopLevelExpression(S, J); break;<br>
+    }<br>
+  }<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// "Library" functions that can be "extern'd" from user code.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+/// putchard - putchar that takes a double and returns 0.<br>
+extern "C"<br>
+double putchard(double X) {<br>
+  putchar((char)X);<br>
+  return 0;<br>
+}<br>
+<br>
+/// printd - printf that takes a double prints it as "%f\n", returning 0.<br>
+extern "C"<br>
+double printd(double X) {<br>
+  printf("%f", X);<br>
+  return 0;<br>
+}<br>
+<br>
+extern "C"<br>
+double printlf() {<br>
+  printf("\n");<br>
+  return 0;<br>
+}<br>
+<br>
+//===----------------------------------------------------------------------===//<br>
+// Main driver code.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+int main() {<br>
+  InitializeNativeTarget();<br>
+  InitializeNativeTargetAsmPrinter();<br>
+  InitializeNativeTargetAsmParser();<br>
+  LLVMContext &Context = getGlobalContext();<br>
+<br>
+  // Install standard binary operators.<br>
+  // 1 is lowest precedence.<br>
+  BinopPrecedence['='] = 2;<br>
+  BinopPrecedence['<'] = 10;<br>
+  BinopPrecedence['+'] = 20;<br>
+  BinopPrecedence['-'] = 20;<br>
+  BinopPrecedence['/'] = 40;<br>
+  BinopPrecedence['*'] = 40;  // highest.<br>
+<br>
+  // Prime the first token.<br>
+#ifndef MINIMAL_STDERR_OUTPUT<br>
+  fprintf(stderr, "ready> ");<br>
+#endif<br>
+  getNextToken();<br>
+<br>
+  // Run the main "interpreter loop" now.<br>
+  MainLoop();<br>
+<br>
+  return 0;<br>
+}<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>