1d80f118eSChris Lattner============================================================
2d80f118eSChris LattnerKaleidoscope: Extending the Language: User-defined Operators
3d80f118eSChris Lattner============================================================
4d80f118eSChris Lattner
5d80f118eSChris Lattner.. contents::
6d80f118eSChris Lattner   :local:
7d80f118eSChris Lattner
8d80f118eSChris LattnerChapter 6 Introduction
9d80f118eSChris Lattner======================
10d80f118eSChris Lattner
11d80f118eSChris LattnerWelcome to Chapter 6 of the "`Implementing a language with
12d80f118eSChris LattnerLLVM <index.html>`_" tutorial. At this point in our tutorial, we now
13d80f118eSChris Lattnerhave a fully functional language that is fairly minimal, but also
14d80f118eSChris Lattneruseful. There is still one big problem with it, however. Our language
15d80f118eSChris Lattnerdoesn't have many useful operators (like division, logical negation, or
16d80f118eSChris Lattnereven any comparisons besides less-than).
17d80f118eSChris Lattner
18d80f118eSChris LattnerThis chapter of the tutorial takes a wild digression into adding
19d80f118eSChris Lattneruser-defined operators to the simple and beautiful Kaleidoscope
20d80f118eSChris Lattnerlanguage. This digression now gives us a simple and ugly language in
21d80f118eSChris Lattnersome ways, but also a powerful one at the same time. One of the great
22d80f118eSChris Lattnerthings about creating your own language is that you get to decide what
23d80f118eSChris Lattneris good or bad. In this tutorial we'll assume that it is okay to use
24d80f118eSChris Lattnerthis as a way to show some interesting parsing techniques.
25d80f118eSChris Lattner
26d80f118eSChris LattnerAt the end of this tutorial, we'll run through an example Kaleidoscope
27d80f118eSChris Lattnerapplication that `renders the Mandelbrot set <#kicking-the-tires>`_. This gives an
28d80f118eSChris Lattnerexample of what you can build with Kaleidoscope and its feature set.
29d80f118eSChris Lattner
30d80f118eSChris LattnerUser-defined Operators: the Idea
31d80f118eSChris Lattner================================
32d80f118eSChris Lattner
33d80f118eSChris LattnerThe "operator overloading" that we will add to Kaleidoscope is more
34d80f118eSChris Lattnergeneral than in languages like C++. In C++, you are only allowed to
35d80f118eSChris Lattnerredefine existing operators: you can't programmatically change the
36d80f118eSChris Lattnergrammar, introduce new operators, change precedence levels, etc. In this
37d80f118eSChris Lattnerchapter, we will add this capability to Kaleidoscope, which will let the
38d80f118eSChris Lattneruser round out the set of operators that are supported.
39d80f118eSChris Lattner
40d80f118eSChris LattnerThe point of going into user-defined operators in a tutorial like this
41d80f118eSChris Lattneris to show the power and flexibility of using a hand-written parser.
42d80f118eSChris LattnerThus far, the parser we have been implementing uses recursive descent
43d80f118eSChris Lattnerfor most parts of the grammar and operator precedence parsing for the
44d80f118eSChris Lattnerexpressions. See `Chapter 2 <LangImpl02.html>`_ for details. By
45d80f118eSChris Lattnerusing operator precedence parsing, it is very easy to allow
46d80f118eSChris Lattnerthe programmer to introduce new operators into the grammar: the grammar
47d80f118eSChris Lattneris dynamically extensible as the JIT runs.
48d80f118eSChris Lattner
49d80f118eSChris LattnerThe two specific features we'll add are programmable unary operators
50d80f118eSChris Lattner(right now, Kaleidoscope has no unary operators at all) as well as
51d80f118eSChris Lattnerbinary operators. An example of this is:
52d80f118eSChris Lattner
53d80f118eSChris Lattner::
54d80f118eSChris Lattner
55d80f118eSChris Lattner    # Logical unary not.
56d80f118eSChris Lattner    def unary!(v)
57d80f118eSChris Lattner      if v then
58d80f118eSChris Lattner        0
59d80f118eSChris Lattner      else
60d80f118eSChris Lattner        1;
61d80f118eSChris Lattner
62d80f118eSChris Lattner    # Define > with the same precedence as <.
63d80f118eSChris Lattner    def binary> 10 (LHS RHS)
64d80f118eSChris Lattner      RHS < LHS;
65d80f118eSChris Lattner
66d80f118eSChris Lattner    # Binary "logical or", (note that it does not "short circuit")
67d80f118eSChris Lattner    def binary| 5 (LHS RHS)
68d80f118eSChris Lattner      if LHS then
69d80f118eSChris Lattner        1
70d80f118eSChris Lattner      else if RHS then
71d80f118eSChris Lattner        1
72d80f118eSChris Lattner      else
73d80f118eSChris Lattner        0;
74d80f118eSChris Lattner
75d80f118eSChris Lattner    # Define = with slightly lower precedence than relationals.
76d80f118eSChris Lattner    def binary= 9 (LHS RHS)
77d80f118eSChris Lattner      !(LHS < RHS | LHS > RHS);
78d80f118eSChris Lattner
79d80f118eSChris LattnerMany languages aspire to being able to implement their standard runtime
80d80f118eSChris Lattnerlibrary in the language itself. In Kaleidoscope, we can implement
81d80f118eSChris Lattnersignificant parts of the language in the library!
82d80f118eSChris Lattner
83d80f118eSChris LattnerWe will break down implementation of these features into two parts:
84d80f118eSChris Lattnerimplementing support for user-defined binary operators and adding unary
85d80f118eSChris Lattneroperators.
86d80f118eSChris Lattner
87d80f118eSChris LattnerUser-defined Binary Operators
88d80f118eSChris Lattner=============================
89d80f118eSChris Lattner
90d80f118eSChris LattnerAdding support for user-defined binary operators is pretty simple with
91d80f118eSChris Lattnerour current framework. We'll first add support for the unary/binary
92d80f118eSChris Lattnerkeywords:
93d80f118eSChris Lattner
94d80f118eSChris Lattner.. code-block:: c++
95d80f118eSChris Lattner
96d80f118eSChris Lattner    enum Token {
97d80f118eSChris Lattner      ...
98d80f118eSChris Lattner      // operators
99d80f118eSChris Lattner      tok_binary = -11,
100d80f118eSChris Lattner      tok_unary = -12
101d80f118eSChris Lattner    };
102d80f118eSChris Lattner    ...
103d80f118eSChris Lattner    static int gettok() {
104d80f118eSChris Lattner    ...
105d80f118eSChris Lattner        if (IdentifierStr == "for")
106d80f118eSChris Lattner          return tok_for;
107d80f118eSChris Lattner        if (IdentifierStr == "in")
108d80f118eSChris Lattner          return tok_in;
109d80f118eSChris Lattner        if (IdentifierStr == "binary")
110d80f118eSChris Lattner          return tok_binary;
111d80f118eSChris Lattner        if (IdentifierStr == "unary")
112d80f118eSChris Lattner          return tok_unary;
113d80f118eSChris Lattner        return tok_identifier;
114d80f118eSChris Lattner
115d80f118eSChris LattnerThis just adds lexer support for the unary and binary keywords, like we
1166bfd10ffSJonathan Roelofsdid in `previous chapters <LangImpl05.html#lexer-extensions-for-if-then-else>`_. One nice thing
117d80f118eSChris Lattnerabout our current AST, is that we represent binary operators with full
118d80f118eSChris Lattnergeneralisation by using their ASCII code as the opcode. For our extended
119d80f118eSChris Lattneroperators, we'll use this same representation, so we don't need any new
120d80f118eSChris LattnerAST or parser support.
121d80f118eSChris Lattner
122d80f118eSChris LattnerOn the other hand, we have to be able to represent the definitions of
123d80f118eSChris Lattnerthese new operators, in the "def binary\| 5" part of the function
124d80f118eSChris Lattnerdefinition. In our grammar so far, the "name" for the function
125d80f118eSChris Lattnerdefinition is parsed as the "prototype" production and into the
126d80f118eSChris Lattner``PrototypeAST`` AST node. To represent our new user-defined operators
127d80f118eSChris Lattneras prototypes, we have to extend the ``PrototypeAST`` AST node like
128d80f118eSChris Lattnerthis:
129d80f118eSChris Lattner
130d80f118eSChris Lattner.. code-block:: c++
131d80f118eSChris Lattner
132d80f118eSChris Lattner    /// PrototypeAST - This class represents the "prototype" for a function,
133d80f118eSChris Lattner    /// which captures its argument names as well as if it is an operator.
134d80f118eSChris Lattner    class PrototypeAST {
135d80f118eSChris Lattner      std::string Name;
136d80f118eSChris Lattner      std::vector<std::string> Args;
137d80f118eSChris Lattner      bool IsOperator;
138d80f118eSChris Lattner      unsigned Precedence;  // Precedence if a binary op.
139d80f118eSChris Lattner
140d80f118eSChris Lattner    public:
141d80f118eSChris Lattner      PrototypeAST(const std::string &name, std::vector<std::string> Args,
142d80f118eSChris Lattner                   bool IsOperator = false, unsigned Prec = 0)
143d80f118eSChris Lattner      : Name(name), Args(std::move(Args)), IsOperator(IsOperator),
144d80f118eSChris Lattner        Precedence(Prec) {}
145d80f118eSChris Lattner
146d80f118eSChris Lattner      Function *codegen();
147d80f118eSChris Lattner      const std::string &getName() const { return Name; }
148d80f118eSChris Lattner
149d80f118eSChris Lattner      bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
150d80f118eSChris Lattner      bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
151d80f118eSChris Lattner
152d80f118eSChris Lattner      char getOperatorName() const {
153d80f118eSChris Lattner        assert(isUnaryOp() || isBinaryOp());
154d80f118eSChris Lattner        return Name[Name.size() - 1];
155d80f118eSChris Lattner      }
156d80f118eSChris Lattner
157d80f118eSChris Lattner      unsigned getBinaryPrecedence() const { return Precedence; }
158d80f118eSChris Lattner    };
159d80f118eSChris Lattner
160d80f118eSChris LattnerBasically, in addition to knowing a name for the prototype, we now keep
161d80f118eSChris Lattnertrack of whether it was an operator, and if it was, what precedence
162d80f118eSChris Lattnerlevel the operator is at. The precedence is only used for binary
163d80f118eSChris Lattneroperators (as you'll see below, it just doesn't apply for unary
164d80f118eSChris Lattneroperators). Now that we have a way to represent the prototype for a
165d80f118eSChris Lattneruser-defined operator, we need to parse it:
166d80f118eSChris Lattner
167d80f118eSChris Lattner.. code-block:: c++
168d80f118eSChris Lattner
169d80f118eSChris Lattner    /// prototype
170d80f118eSChris Lattner    ///   ::= id '(' id* ')'
171d80f118eSChris Lattner    ///   ::= binary LETTER number? (id, id)
172d80f118eSChris Lattner    static std::unique_ptr<PrototypeAST> ParsePrototype() {
173d80f118eSChris Lattner      std::string FnName;
174d80f118eSChris Lattner
175d80f118eSChris Lattner      unsigned Kind = 0;  // 0 = identifier, 1 = unary, 2 = binary.
176d80f118eSChris Lattner      unsigned BinaryPrecedence = 30;
177d80f118eSChris Lattner
178d80f118eSChris Lattner      switch (CurTok) {
179d80f118eSChris Lattner      default:
180d80f118eSChris Lattner        return LogErrorP("Expected function name in prototype");
181d80f118eSChris Lattner      case tok_identifier:
182d80f118eSChris Lattner        FnName = IdentifierStr;
183d80f118eSChris Lattner        Kind = 0;
184d80f118eSChris Lattner        getNextToken();
185d80f118eSChris Lattner        break;
186d80f118eSChris Lattner      case tok_binary:
187d80f118eSChris Lattner        getNextToken();
188d80f118eSChris Lattner        if (!isascii(CurTok))
189d80f118eSChris Lattner          return LogErrorP("Expected binary operator");
190d80f118eSChris Lattner        FnName = "binary";
191d80f118eSChris Lattner        FnName += (char)CurTok;
192d80f118eSChris Lattner        Kind = 2;
193d80f118eSChris Lattner        getNextToken();
194d80f118eSChris Lattner
195d80f118eSChris Lattner        // Read the precedence if present.
196d80f118eSChris Lattner        if (CurTok == tok_number) {
197d80f118eSChris Lattner          if (NumVal < 1 || NumVal > 100)
198d80f118eSChris Lattner            return LogErrorP("Invalid precedence: must be 1..100");
199d80f118eSChris Lattner          BinaryPrecedence = (unsigned)NumVal;
200d80f118eSChris Lattner          getNextToken();
201d80f118eSChris Lattner        }
202d80f118eSChris Lattner        break;
203d80f118eSChris Lattner      }
204d80f118eSChris Lattner
205d80f118eSChris Lattner      if (CurTok != '(')
206d80f118eSChris Lattner        return LogErrorP("Expected '(' in prototype");
207d80f118eSChris Lattner
208d80f118eSChris Lattner      std::vector<std::string> ArgNames;
209d80f118eSChris Lattner      while (getNextToken() == tok_identifier)
210d80f118eSChris Lattner        ArgNames.push_back(IdentifierStr);
211d80f118eSChris Lattner      if (CurTok != ')')
212d80f118eSChris Lattner        return LogErrorP("Expected ')' in prototype");
213d80f118eSChris Lattner
214d80f118eSChris Lattner      // success.
215d80f118eSChris Lattner      getNextToken();  // eat ')'.
216d80f118eSChris Lattner
217d80f118eSChris Lattner      // Verify right number of names for operator.
218d80f118eSChris Lattner      if (Kind && ArgNames.size() != Kind)
219d80f118eSChris Lattner        return LogErrorP("Invalid number of operands for operator");
220d80f118eSChris Lattner
2210eaee545SJonas Devlieghere      return std::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
222d80f118eSChris Lattner                                             BinaryPrecedence);
223d80f118eSChris Lattner    }
224d80f118eSChris Lattner
225d80f118eSChris LattnerThis is all fairly straightforward parsing code, and we have already
226d80f118eSChris Lattnerseen a lot of similar code in the past. One interesting part about the
227d80f118eSChris Lattnercode above is the couple lines that set up ``FnName`` for binary
228d80f118eSChris Lattneroperators. This builds names like "binary@" for a newly defined "@"
229d80f118eSChris Lattneroperator. It then takes advantage of the fact that symbol names in the
230d80f118eSChris LattnerLLVM symbol table are allowed to have any character in them, including
231d80f118eSChris Lattnerembedded nul characters.
232d80f118eSChris Lattner
233d80f118eSChris LattnerThe next interesting thing to add, is codegen support for these binary
234d80f118eSChris Lattneroperators. Given our current structure, this is a simple addition of a
235d80f118eSChris Lattnerdefault case for our existing binary operator node:
236d80f118eSChris Lattner
237d80f118eSChris Lattner.. code-block:: c++
238d80f118eSChris Lattner
239d80f118eSChris Lattner    Value *BinaryExprAST::codegen() {
240d80f118eSChris Lattner      Value *L = LHS->codegen();
241d80f118eSChris Lattner      Value *R = RHS->codegen();
242d80f118eSChris Lattner      if (!L || !R)
243d80f118eSChris Lattner        return nullptr;
244d80f118eSChris Lattner
245d80f118eSChris Lattner      switch (Op) {
246d80f118eSChris Lattner      case '+':
247d80f118eSChris Lattner        return Builder.CreateFAdd(L, R, "addtmp");
248d80f118eSChris Lattner      case '-':
249d80f118eSChris Lattner        return Builder.CreateFSub(L, R, "subtmp");
250d80f118eSChris Lattner      case '*':
251d80f118eSChris Lattner        return Builder.CreateFMul(L, R, "multmp");
252d80f118eSChris Lattner      case '<':
253d80f118eSChris Lattner        L = Builder.CreateFCmpULT(L, R, "cmptmp");
254d80f118eSChris Lattner        // Convert bool 0/1 to double 0.0 or 1.0
255d80f118eSChris Lattner        return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext),
256d80f118eSChris Lattner                                    "booltmp");
257d80f118eSChris Lattner      default:
258d80f118eSChris Lattner        break;
259d80f118eSChris Lattner      }
260d80f118eSChris Lattner
261d80f118eSChris Lattner      // If it wasn't a builtin binary operator, it must be a user defined one. Emit
262d80f118eSChris Lattner      // a call to it.
263d80f118eSChris Lattner      Function *F = getFunction(std::string("binary") + Op);
264d80f118eSChris Lattner      assert(F && "binary operator not found!");
265d80f118eSChris Lattner
266d80f118eSChris Lattner      Value *Ops[2] = { L, R };
267d80f118eSChris Lattner      return Builder.CreateCall(F, Ops, "binop");
268d80f118eSChris Lattner    }
269d80f118eSChris Lattner
270d80f118eSChris LattnerAs you can see above, the new code is actually really simple. It just
271d80f118eSChris Lattnerdoes a lookup for the appropriate operator in the symbol table and
272d80f118eSChris Lattnergenerates a function call to it. Since user-defined operators are just
273d80f118eSChris Lattnerbuilt as normal functions (because the "prototype" boils down to a
274d80f118eSChris Lattnerfunction with the right name) everything falls into place.
275d80f118eSChris Lattner
276d80f118eSChris LattnerThe final piece of code we are missing, is a bit of top-level magic:
277d80f118eSChris Lattner
278d80f118eSChris Lattner.. code-block:: c++
279d80f118eSChris Lattner
280d80f118eSChris Lattner    Function *FunctionAST::codegen() {
281d80f118eSChris Lattner      // Transfer ownership of the prototype to the FunctionProtos map, but keep a
282d80f118eSChris Lattner      // reference to it for use below.
283d80f118eSChris Lattner      auto &P = *Proto;
284d80f118eSChris Lattner      FunctionProtos[Proto->getName()] = std::move(Proto);
285d80f118eSChris Lattner      Function *TheFunction = getFunction(P.getName());
286d80f118eSChris Lattner      if (!TheFunction)
287d80f118eSChris Lattner        return nullptr;
288d80f118eSChris Lattner
289d80f118eSChris Lattner      // If this is an operator, install it.
290d80f118eSChris Lattner      if (P.isBinaryOp())
291d80f118eSChris Lattner        BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
292d80f118eSChris Lattner
293d80f118eSChris Lattner      // Create a new basic block to start insertion into.
294d80f118eSChris Lattner      BasicBlock *BB = BasicBlock::Create(TheContext, "entry", TheFunction);
295d80f118eSChris Lattner      ...
296d80f118eSChris Lattner
297d80f118eSChris LattnerBasically, before codegening a function, if it is a user-defined
298d80f118eSChris Lattneroperator, we register it in the precedence table. This allows the binary
299d80f118eSChris Lattneroperator parsing logic we already have in place to handle it. Since we
300d80f118eSChris Lattnerare working on a fully-general operator precedence parser, this is all
301d80f118eSChris Lattnerwe need to do to "extend the grammar".
302d80f118eSChris Lattner
303d80f118eSChris LattnerNow we have useful user-defined binary operators. This builds a lot on
304d80f118eSChris Lattnerthe previous framework we built for other operators. Adding unary
305d80f118eSChris Lattneroperators is a bit more challenging, because we don't have any framework
306d80f118eSChris Lattnerfor it yet - let's see what it takes.
307d80f118eSChris Lattner
308d80f118eSChris LattnerUser-defined Unary Operators
309d80f118eSChris Lattner============================
310d80f118eSChris Lattner
311d80f118eSChris LattnerSince we don't currently support unary operators in the Kaleidoscope
312d80f118eSChris Lattnerlanguage, we'll need to add everything to support them. Above, we added
313d80f118eSChris Lattnersimple support for the 'unary' keyword to the lexer. In addition to
314d80f118eSChris Lattnerthat, we need an AST node:
315d80f118eSChris Lattner
316d80f118eSChris Lattner.. code-block:: c++
317d80f118eSChris Lattner
318d80f118eSChris Lattner    /// UnaryExprAST - Expression class for a unary operator.
319d80f118eSChris Lattner    class UnaryExprAST : public ExprAST {
320d80f118eSChris Lattner      char Opcode;
321d80f118eSChris Lattner      std::unique_ptr<ExprAST> Operand;
322d80f118eSChris Lattner
323d80f118eSChris Lattner    public:
324d80f118eSChris Lattner      UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
325d80f118eSChris Lattner        : Opcode(Opcode), Operand(std::move(Operand)) {}
326d80f118eSChris Lattner
327d80f118eSChris Lattner      Value *codegen() override;
328d80f118eSChris Lattner    };
329d80f118eSChris Lattner
330d80f118eSChris LattnerThis AST node is very simple and obvious by now. It directly mirrors the
331d80f118eSChris Lattnerbinary operator AST node, except that it only has one child. With this,
332d80f118eSChris Lattnerwe need to add the parsing logic. Parsing a unary operator is pretty
333d80f118eSChris Lattnersimple: we'll add a new function to do it:
334d80f118eSChris Lattner
335d80f118eSChris Lattner.. code-block:: c++
336d80f118eSChris Lattner
337d80f118eSChris Lattner    /// unary
338d80f118eSChris Lattner    ///   ::= primary
339d80f118eSChris Lattner    ///   ::= '!' unary
340d80f118eSChris Lattner    static std::unique_ptr<ExprAST> ParseUnary() {
341d80f118eSChris Lattner      // If the current token is not an operator, it must be a primary expr.
342d80f118eSChris Lattner      if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
343d80f118eSChris Lattner        return ParsePrimary();
344d80f118eSChris Lattner
345d80f118eSChris Lattner      // If this is a unary operator, read it.
346d80f118eSChris Lattner      int Opc = CurTok;
347d80f118eSChris Lattner      getNextToken();
348d80f118eSChris Lattner      if (auto Operand = ParseUnary())
3490eaee545SJonas Devlieghere        return std::make_unique<UnaryExprAST>(Opc, std::move(Operand));
350d80f118eSChris Lattner      return nullptr;
351d80f118eSChris Lattner    }
352d80f118eSChris Lattner
353d80f118eSChris LattnerThe grammar we add is pretty straightforward here. If we see a unary
354d80f118eSChris Lattneroperator when parsing a primary operator, we eat the operator as a
355d80f118eSChris Lattnerprefix and parse the remaining piece as another unary operator. This
356d80f118eSChris Lattnerallows us to handle multiple unary operators (e.g. "!!x"). Note that
357d80f118eSChris Lattnerunary operators can't have ambiguous parses like binary operators can,
358d80f118eSChris Lattnerso there is no need for precedence information.
359d80f118eSChris Lattner
360d80f118eSChris LattnerThe problem with this function, is that we need to call ParseUnary from
361d80f118eSChris Lattnersomewhere. To do this, we change previous callers of ParsePrimary to
362d80f118eSChris Lattnercall ParseUnary instead:
363d80f118eSChris Lattner
364d80f118eSChris Lattner.. code-block:: c++
365d80f118eSChris Lattner
366d80f118eSChris Lattner    /// binoprhs
367d80f118eSChris Lattner    ///   ::= ('+' unary)*
368d80f118eSChris Lattner    static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
369d80f118eSChris Lattner                                                  std::unique_ptr<ExprAST> LHS) {
370d80f118eSChris Lattner      ...
371d80f118eSChris Lattner        // Parse the unary expression after the binary operator.
372d80f118eSChris Lattner        auto RHS = ParseUnary();
373d80f118eSChris Lattner        if (!RHS)
374d80f118eSChris Lattner          return nullptr;
375d80f118eSChris Lattner      ...
376d80f118eSChris Lattner    }
377d80f118eSChris Lattner    /// expression
378d80f118eSChris Lattner    ///   ::= unary binoprhs
379d80f118eSChris Lattner    ///
380d80f118eSChris Lattner    static std::unique_ptr<ExprAST> ParseExpression() {
381d80f118eSChris Lattner      auto LHS = ParseUnary();
382d80f118eSChris Lattner      if (!LHS)
383d80f118eSChris Lattner        return nullptr;
384d80f118eSChris Lattner
385d80f118eSChris Lattner      return ParseBinOpRHS(0, std::move(LHS));
386d80f118eSChris Lattner    }
387d80f118eSChris Lattner
388d80f118eSChris LattnerWith these two simple changes, we are now able to parse unary operators
389d80f118eSChris Lattnerand build the AST for them. Next up, we need to add parser support for
390d80f118eSChris Lattnerprototypes, to parse the unary operator prototype. We extend the binary
391d80f118eSChris Lattneroperator code above with:
392d80f118eSChris Lattner
393d80f118eSChris Lattner.. code-block:: c++
394d80f118eSChris Lattner
395d80f118eSChris Lattner    /// prototype
396d80f118eSChris Lattner    ///   ::= id '(' id* ')'
397d80f118eSChris Lattner    ///   ::= binary LETTER number? (id, id)
398d80f118eSChris Lattner    ///   ::= unary LETTER (id)
399d80f118eSChris Lattner    static std::unique_ptr<PrototypeAST> ParsePrototype() {
400d80f118eSChris Lattner      std::string FnName;
401d80f118eSChris Lattner
402d80f118eSChris Lattner      unsigned Kind = 0;  // 0 = identifier, 1 = unary, 2 = binary.
403d80f118eSChris Lattner      unsigned BinaryPrecedence = 30;
404d80f118eSChris Lattner
405d80f118eSChris Lattner      switch (CurTok) {
406d80f118eSChris Lattner      default:
407d80f118eSChris Lattner        return LogErrorP("Expected function name in prototype");
408d80f118eSChris Lattner      case tok_identifier:
409d80f118eSChris Lattner        FnName = IdentifierStr;
410d80f118eSChris Lattner        Kind = 0;
411d80f118eSChris Lattner        getNextToken();
412d80f118eSChris Lattner        break;
413d80f118eSChris Lattner      case tok_unary:
414d80f118eSChris Lattner        getNextToken();
415d80f118eSChris Lattner        if (!isascii(CurTok))
416d80f118eSChris Lattner          return LogErrorP("Expected unary operator");
417d80f118eSChris Lattner        FnName = "unary";
418d80f118eSChris Lattner        FnName += (char)CurTok;
419d80f118eSChris Lattner        Kind = 1;
420d80f118eSChris Lattner        getNextToken();
421d80f118eSChris Lattner        break;
422d80f118eSChris Lattner      case tok_binary:
423d80f118eSChris Lattner        ...
424d80f118eSChris Lattner
425d80f118eSChris LattnerAs with binary operators, we name unary operators with a name that
426d80f118eSChris Lattnerincludes the operator character. This assists us at code generation
427d80f118eSChris Lattnertime. Speaking of, the final piece we need to add is codegen support for
428d80f118eSChris Lattnerunary operators. It looks like this:
429d80f118eSChris Lattner
430d80f118eSChris Lattner.. code-block:: c++
431d80f118eSChris Lattner
432d80f118eSChris Lattner    Value *UnaryExprAST::codegen() {
433d80f118eSChris Lattner      Value *OperandV = Operand->codegen();
434d80f118eSChris Lattner      if (!OperandV)
435d80f118eSChris Lattner        return nullptr;
436d80f118eSChris Lattner
437d80f118eSChris Lattner      Function *F = getFunction(std::string("unary") + Opcode);
438d80f118eSChris Lattner      if (!F)
439d80f118eSChris Lattner        return LogErrorV("Unknown unary operator");
440d80f118eSChris Lattner
441d80f118eSChris Lattner      return Builder.CreateCall(F, OperandV, "unop");
442d80f118eSChris Lattner    }
443d80f118eSChris Lattner
444d80f118eSChris LattnerThis code is similar to, but simpler than, the code for binary
445d80f118eSChris Lattneroperators. It is simpler primarily because it doesn't need to handle any
446d80f118eSChris Lattnerpredefined operators.
447d80f118eSChris Lattner
448d80f118eSChris LattnerKicking the Tires
449d80f118eSChris Lattner=================
450d80f118eSChris Lattner
451d80f118eSChris LattnerIt is somewhat hard to believe, but with a few simple extensions we've
452d80f118eSChris Lattnercovered in the last chapters, we have grown a real-ish language. With
453d80f118eSChris Lattnerthis, we can do a lot of interesting things, including I/O, math, and a
454d80f118eSChris Lattnerbunch of other things. For example, we can now add a nice sequencing
455d80f118eSChris Lattneroperator (printd is defined to print out the specified value and a
456d80f118eSChris Lattnernewline):
457d80f118eSChris Lattner
458d80f118eSChris Lattner::
459d80f118eSChris Lattner
460d80f118eSChris Lattner    ready> extern printd(x);
461d80f118eSChris Lattner    Read extern:
462d80f118eSChris Lattner    declare double @printd(double)
463d80f118eSChris Lattner
464d80f118eSChris Lattner    ready> def binary : 1 (x y) 0;  # Low-precedence operator that ignores operands.
465d80f118eSChris Lattner    ...
466d80f118eSChris Lattner    ready> printd(123) : printd(456) : printd(789);
467d80f118eSChris Lattner    123.000000
468d80f118eSChris Lattner    456.000000
469d80f118eSChris Lattner    789.000000
470d80f118eSChris Lattner    Evaluated to 0.000000
471d80f118eSChris Lattner
472d80f118eSChris LattnerWe can also define a bunch of other "primitive" operations, such as:
473d80f118eSChris Lattner
474d80f118eSChris Lattner::
475d80f118eSChris Lattner
476d80f118eSChris Lattner    # Logical unary not.
477d80f118eSChris Lattner    def unary!(v)
478d80f118eSChris Lattner      if v then
479d80f118eSChris Lattner        0
480d80f118eSChris Lattner      else
481d80f118eSChris Lattner        1;
482d80f118eSChris Lattner
483d80f118eSChris Lattner    # Unary negate.
484d80f118eSChris Lattner    def unary-(v)
485d80f118eSChris Lattner      0-v;
486d80f118eSChris Lattner
487d80f118eSChris Lattner    # Define > with the same precedence as <.
488d80f118eSChris Lattner    def binary> 10 (LHS RHS)
489d80f118eSChris Lattner      RHS < LHS;
490d80f118eSChris Lattner
491d80f118eSChris Lattner    # Binary logical or, which does not short circuit.
492d80f118eSChris Lattner    def binary| 5 (LHS RHS)
493d80f118eSChris Lattner      if LHS then
494d80f118eSChris Lattner        1
495d80f118eSChris Lattner      else if RHS then
496d80f118eSChris Lattner        1
497d80f118eSChris Lattner      else
498d80f118eSChris Lattner        0;
499d80f118eSChris Lattner
500d80f118eSChris Lattner    # Binary logical and, which does not short circuit.
501d80f118eSChris Lattner    def binary& 6 (LHS RHS)
502d80f118eSChris Lattner      if !LHS then
503d80f118eSChris Lattner        0
504d80f118eSChris Lattner      else
505d80f118eSChris Lattner        !!RHS;
506d80f118eSChris Lattner
507d80f118eSChris Lattner    # Define = with slightly lower precedence than relationals.
508d80f118eSChris Lattner    def binary = 9 (LHS RHS)
509d80f118eSChris Lattner      !(LHS < RHS | LHS > RHS);
510d80f118eSChris Lattner
511d80f118eSChris Lattner    # Define ':' for sequencing: as a low-precedence operator that ignores operands
512d80f118eSChris Lattner    # and just returns the RHS.
513d80f118eSChris Lattner    def binary : 1 (x y) y;
514d80f118eSChris Lattner
515d80f118eSChris LattnerGiven the previous if/then/else support, we can also define interesting
516d80f118eSChris Lattnerfunctions for I/O. For example, the following prints out a character
517d80f118eSChris Lattnerwhose "density" reflects the value passed in: the lower the value, the
518d80f118eSChris Lattnerdenser the character:
519d80f118eSChris Lattner
520d80f118eSChris Lattner::
521d80f118eSChris Lattner
522d80f118eSChris Lattner    ready> extern putchard(char);
523d80f118eSChris Lattner    ...
524d80f118eSChris Lattner    ready> def printdensity(d)
525d80f118eSChris Lattner      if d > 8 then
526d80f118eSChris Lattner        putchard(32)  # ' '
527d80f118eSChris Lattner      else if d > 4 then
528d80f118eSChris Lattner        putchard(46)  # '.'
529d80f118eSChris Lattner      else if d > 2 then
530d80f118eSChris Lattner        putchard(43)  # '+'
531d80f118eSChris Lattner      else
532d80f118eSChris Lattner        putchard(42); # '*'
533d80f118eSChris Lattner    ...
534d80f118eSChris Lattner    ready> printdensity(1): printdensity(2): printdensity(3):
535d80f118eSChris Lattner           printdensity(4): printdensity(5): printdensity(9):
536d80f118eSChris Lattner           putchard(10);
537d80f118eSChris Lattner    **++.
538d80f118eSChris Lattner    Evaluated to 0.000000
539d80f118eSChris Lattner
540d80f118eSChris LattnerBased on these simple primitive operations, we can start to define more
541d80f118eSChris Lattnerinteresting things. For example, here's a little function that determines
542d80f118eSChris Lattnerthe number of iterations it takes for a certain function in the complex
543d80f118eSChris Lattnerplane to diverge:
544d80f118eSChris Lattner
545d80f118eSChris Lattner::
546d80f118eSChris Lattner
547d80f118eSChris Lattner    # Determine whether the specific location diverges.
548d80f118eSChris Lattner    # Solve for z = z^2 + c in the complex plane.
549d80f118eSChris Lattner    def mandelconverger(real imag iters creal cimag)
550d80f118eSChris Lattner      if iters > 255 | (real*real + imag*imag > 4) then
551d80f118eSChris Lattner        iters
552d80f118eSChris Lattner      else
553d80f118eSChris Lattner        mandelconverger(real*real - imag*imag + creal,
554d80f118eSChris Lattner                        2*real*imag + cimag,
555d80f118eSChris Lattner                        iters+1, creal, cimag);
556d80f118eSChris Lattner
557d80f118eSChris Lattner    # Return the number of iterations required for the iteration to escape
558d80f118eSChris Lattner    def mandelconverge(real imag)
559d80f118eSChris Lattner      mandelconverger(real, imag, 0, real, imag);
560d80f118eSChris Lattner
561d80f118eSChris LattnerThis "``z = z2 + c``" function is a beautiful little creature that is
562d80f118eSChris Lattnerthe basis for computation of the `Mandelbrot
563d80f118eSChris LattnerSet <http://en.wikipedia.org/wiki/Mandelbrot_set>`_. Our
564d80f118eSChris Lattner``mandelconverge`` function returns the number of iterations that it
565d80f118eSChris Lattnertakes for a complex orbit to escape, saturating to 255. This is not a
566d80f118eSChris Lattnervery useful function by itself, but if you plot its value over a
567d80f118eSChris Lattnertwo-dimensional plane, you can see the Mandelbrot set. Given that we are
568d80f118eSChris Lattnerlimited to using putchard here, our amazing graphical output is limited,
569d80f118eSChris Lattnerbut we can whip together something using the density plotter above:
570d80f118eSChris Lattner
571d80f118eSChris Lattner::
572d80f118eSChris Lattner
573d80f118eSChris Lattner    # Compute and plot the mandelbrot set with the specified 2 dimensional range
574d80f118eSChris Lattner    # info.
575d80f118eSChris Lattner    def mandelhelp(xmin xmax xstep   ymin ymax ystep)
576d80f118eSChris Lattner      for y = ymin, y < ymax, ystep in (
577d80f118eSChris Lattner        (for x = xmin, x < xmax, xstep in
578d80f118eSChris Lattner           printdensity(mandelconverge(x,y)))
579d80f118eSChris Lattner        : putchard(10)
580d80f118eSChris Lattner      )
581d80f118eSChris Lattner
582d80f118eSChris Lattner    # mandel - This is a convenient helper function for plotting the mandelbrot set
583d80f118eSChris Lattner    # from the specified position with the specified Magnification.
584d80f118eSChris Lattner    def mandel(realstart imagstart realmag imagmag)
585d80f118eSChris Lattner      mandelhelp(realstart, realstart+realmag*78, realmag,
586d80f118eSChris Lattner                 imagstart, imagstart+imagmag*40, imagmag);
587d80f118eSChris Lattner
588d80f118eSChris LattnerGiven this, we can try plotting out the mandelbrot set! Lets try it out:
589d80f118eSChris Lattner
590d80f118eSChris Lattner::
591d80f118eSChris Lattner
592d80f118eSChris Lattner    ready> mandel(-2.3, -1.3, 0.05, 0.07);
593d80f118eSChris Lattner    *******************************+++++++++++*************************************
594d80f118eSChris Lattner    *************************+++++++++++++++++++++++*******************************
595d80f118eSChris Lattner    **********************+++++++++++++++++++++++++++++****************************
596d80f118eSChris Lattner    *******************+++++++++++++++++++++.. ...++++++++*************************
597d80f118eSChris Lattner    *****************++++++++++++++++++++++.... ...+++++++++***********************
598d80f118eSChris Lattner    ***************+++++++++++++++++++++++.....   ...+++++++++*********************
599d80f118eSChris Lattner    **************+++++++++++++++++++++++....     ....+++++++++********************
600d80f118eSChris Lattner    *************++++++++++++++++++++++......      .....++++++++*******************
601d80f118eSChris Lattner    ************+++++++++++++++++++++.......       .......+++++++******************
602d80f118eSChris Lattner    ***********+++++++++++++++++++....                ... .+++++++*****************
603d80f118eSChris Lattner    **********+++++++++++++++++.......                     .+++++++****************
604d80f118eSChris Lattner    *********++++++++++++++...........                    ...+++++++***************
605d80f118eSChris Lattner    ********++++++++++++............                      ...++++++++**************
606d80f118eSChris Lattner    ********++++++++++... ..........                        .++++++++**************
607d80f118eSChris Lattner    *******+++++++++.....                                   .+++++++++*************
608d80f118eSChris Lattner    *******++++++++......                                  ..+++++++++*************
609d80f118eSChris Lattner    *******++++++.......                                   ..+++++++++*************
610d80f118eSChris Lattner    *******+++++......                                     ..+++++++++*************
611d80f118eSChris Lattner    *******.... ....                                      ...+++++++++*************
612d80f118eSChris Lattner    *******.... .                                         ...+++++++++*************
613d80f118eSChris Lattner    *******+++++......                                    ...+++++++++*************
614d80f118eSChris Lattner    *******++++++.......                                   ..+++++++++*************
615d80f118eSChris Lattner    *******++++++++......                                   .+++++++++*************
616d80f118eSChris Lattner    *******+++++++++.....                                  ..+++++++++*************
617d80f118eSChris Lattner    ********++++++++++... ..........                        .++++++++**************
618d80f118eSChris Lattner    ********++++++++++++............                      ...++++++++**************
619d80f118eSChris Lattner    *********++++++++++++++..........                     ...+++++++***************
620d80f118eSChris Lattner    **********++++++++++++++++........                     .+++++++****************
621d80f118eSChris Lattner    **********++++++++++++++++++++....                ... ..+++++++****************
622d80f118eSChris Lattner    ***********++++++++++++++++++++++.......       .......++++++++*****************
623d80f118eSChris Lattner    ************+++++++++++++++++++++++......      ......++++++++******************
624d80f118eSChris Lattner    **************+++++++++++++++++++++++....      ....++++++++********************
625d80f118eSChris Lattner    ***************+++++++++++++++++++++++.....   ...+++++++++*********************
626d80f118eSChris Lattner    *****************++++++++++++++++++++++....  ...++++++++***********************
627d80f118eSChris Lattner    *******************+++++++++++++++++++++......++++++++*************************
628d80f118eSChris Lattner    *********************++++++++++++++++++++++.++++++++***************************
629d80f118eSChris Lattner    *************************+++++++++++++++++++++++*******************************
630d80f118eSChris Lattner    ******************************+++++++++++++************************************
631d80f118eSChris Lattner    *******************************************************************************
632d80f118eSChris Lattner    *******************************************************************************
633d80f118eSChris Lattner    *******************************************************************************
634d80f118eSChris Lattner    Evaluated to 0.000000
635d80f118eSChris Lattner    ready> mandel(-2, -1, 0.02, 0.04);
636d80f118eSChris Lattner    **************************+++++++++++++++++++++++++++++++++++++++++++++++++++++
637d80f118eSChris Lattner    ***********************++++++++++++++++++++++++++++++++++++++++++++++++++++++++
638d80f118eSChris Lattner    *********************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.
639d80f118eSChris Lattner    *******************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++...
640d80f118eSChris Lattner    *****************+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.....
641d80f118eSChris Lattner    ***************++++++++++++++++++++++++++++++++++++++++++++++++++++++++........
642d80f118eSChris Lattner    **************++++++++++++++++++++++++++++++++++++++++++++++++++++++...........
643d80f118eSChris Lattner    ************+++++++++++++++++++++++++++++++++++++++++++++++++++++..............
644d80f118eSChris Lattner    ***********++++++++++++++++++++++++++++++++++++++++++++++++++........        .
645d80f118eSChris Lattner    **********++++++++++++++++++++++++++++++++++++++++++++++.............
646d80f118eSChris Lattner    ********+++++++++++++++++++++++++++++++++++++++++++..................
647d80f118eSChris Lattner    *******+++++++++++++++++++++++++++++++++++++++.......................
648d80f118eSChris Lattner    ******+++++++++++++++++++++++++++++++++++...........................
649d80f118eSChris Lattner    *****++++++++++++++++++++++++++++++++............................
650d80f118eSChris Lattner    *****++++++++++++++++++++++++++++...............................
651d80f118eSChris Lattner    ****++++++++++++++++++++++++++......   .........................
652d80f118eSChris Lattner    ***++++++++++++++++++++++++.........     ......    ...........
653d80f118eSChris Lattner    ***++++++++++++++++++++++............
654d80f118eSChris Lattner    **+++++++++++++++++++++..............
655d80f118eSChris Lattner    **+++++++++++++++++++................
656d80f118eSChris Lattner    *++++++++++++++++++.................
657d80f118eSChris Lattner    *++++++++++++++++............ ...
658d80f118eSChris Lattner    *++++++++++++++..............
659d80f118eSChris Lattner    *+++....++++................
660d80f118eSChris Lattner    *..........  ...........
661d80f118eSChris Lattner    *
662d80f118eSChris Lattner    *..........  ...........
663d80f118eSChris Lattner    *+++....++++................
664d80f118eSChris Lattner    *++++++++++++++..............
665d80f118eSChris Lattner    *++++++++++++++++............ ...
666d80f118eSChris Lattner    *++++++++++++++++++.................
667d80f118eSChris Lattner    **+++++++++++++++++++................
668d80f118eSChris Lattner    **+++++++++++++++++++++..............
669d80f118eSChris Lattner    ***++++++++++++++++++++++............
670d80f118eSChris Lattner    ***++++++++++++++++++++++++.........     ......    ...........
671d80f118eSChris Lattner    ****++++++++++++++++++++++++++......   .........................
672d80f118eSChris Lattner    *****++++++++++++++++++++++++++++...............................
673d80f118eSChris Lattner    *****++++++++++++++++++++++++++++++++............................
674d80f118eSChris Lattner    ******+++++++++++++++++++++++++++++++++++...........................
675d80f118eSChris Lattner    *******+++++++++++++++++++++++++++++++++++++++.......................
676d80f118eSChris Lattner    ********+++++++++++++++++++++++++++++++++++++++++++..................
677d80f118eSChris Lattner    Evaluated to 0.000000
678d80f118eSChris Lattner    ready> mandel(-0.9, -1.4, 0.02, 0.03);
679d80f118eSChris Lattner    *******************************************************************************
680d80f118eSChris Lattner    *******************************************************************************
681d80f118eSChris Lattner    *******************************************************************************
682d80f118eSChris Lattner    **********+++++++++++++++++++++************************************************
683d80f118eSChris Lattner    *+++++++++++++++++++++++++++++++++++++++***************************************
684d80f118eSChris Lattner    +++++++++++++++++++++++++++++++++++++++++++++**********************************
685d80f118eSChris Lattner    ++++++++++++++++++++++++++++++++++++++++++++++++++*****************************
686d80f118eSChris Lattner    ++++++++++++++++++++++++++++++++++++++++++++++++++++++*************************
687d80f118eSChris Lattner    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++**********************
688d80f118eSChris Lattner    +++++++++++++++++++++++++++++++++.........++++++++++++++++++*******************
689d80f118eSChris Lattner    +++++++++++++++++++++++++++++++....   ......+++++++++++++++++++****************
690d80f118eSChris Lattner    +++++++++++++++++++++++++++++.......  ........+++++++++++++++++++**************
691d80f118eSChris Lattner    ++++++++++++++++++++++++++++........   ........++++++++++++++++++++************
692d80f118eSChris Lattner    +++++++++++++++++++++++++++.........     ..  ...+++++++++++++++++++++**********
693d80f118eSChris Lattner    ++++++++++++++++++++++++++...........        ....++++++++++++++++++++++********
694d80f118eSChris Lattner    ++++++++++++++++++++++++.............       .......++++++++++++++++++++++******
695d80f118eSChris Lattner    +++++++++++++++++++++++.............        ........+++++++++++++++++++++++****
696d80f118eSChris Lattner    ++++++++++++++++++++++...........           ..........++++++++++++++++++++++***
697d80f118eSChris Lattner    ++++++++++++++++++++...........                .........++++++++++++++++++++++*
698d80f118eSChris Lattner    ++++++++++++++++++............                  ...........++++++++++++++++++++
699d80f118eSChris Lattner    ++++++++++++++++...............                 .............++++++++++++++++++
700d80f118eSChris Lattner    ++++++++++++++.................                 ...............++++++++++++++++
701d80f118eSChris Lattner    ++++++++++++..................                  .................++++++++++++++
702d80f118eSChris Lattner    +++++++++..................                      .................+++++++++++++
703d80f118eSChris Lattner    ++++++........        .                               .........  ..++++++++++++
704d80f118eSChris Lattner    ++............                                         ......    ....++++++++++
705d80f118eSChris Lattner    ..............                                                    ...++++++++++
706d80f118eSChris Lattner    ..............                                                    ....+++++++++
707d80f118eSChris Lattner    ..............                                                    .....++++++++
708d80f118eSChris Lattner    .............                                                    ......++++++++
709d80f118eSChris Lattner    ...........                                                     .......++++++++
710d80f118eSChris Lattner    .........                                                       ........+++++++
711d80f118eSChris Lattner    .........                                                       ........+++++++
712d80f118eSChris Lattner    .........                                                           ....+++++++
713d80f118eSChris Lattner    ........                                                             ...+++++++
714d80f118eSChris Lattner    .......                                                              ...+++++++
715d80f118eSChris Lattner                                                                        ....+++++++
716d80f118eSChris Lattner                                                                       .....+++++++
717d80f118eSChris Lattner                                                                        ....+++++++
718d80f118eSChris Lattner                                                                        ....+++++++
719d80f118eSChris Lattner                                                                        ....+++++++
720d80f118eSChris Lattner    Evaluated to 0.000000
721d80f118eSChris Lattner    ready> ^D
722d80f118eSChris Lattner
723d80f118eSChris LattnerAt this point, you may be starting to realize that Kaleidoscope is a
724d80f118eSChris Lattnerreal and powerful language. It may not be self-similar :), but it can be
725d80f118eSChris Lattnerused to plot things that are!
726d80f118eSChris Lattner
727d80f118eSChris LattnerWith this, we conclude the "adding user-defined operators" chapter of
728d80f118eSChris Lattnerthe tutorial. We have successfully augmented our language, adding the
729d80f118eSChris Lattnerability to extend the language in the library, and we have shown how
730d80f118eSChris Lattnerthis can be used to build a simple but interesting end-user application
731d80f118eSChris Lattnerin Kaleidoscope. At this point, Kaleidoscope can build a variety of
732d80f118eSChris Lattnerapplications that are functional and can call functions with
733d80f118eSChris Lattnerside-effects, but it can't actually define and mutate a variable itself.
734d80f118eSChris Lattner
735d80f118eSChris LattnerStrikingly, variable mutation is an important feature of some languages,
736d80f118eSChris Lattnerand it is not at all obvious how to `add support for mutable
737d80f118eSChris Lattnervariables <LangImpl07.html>`_ without having to add an "SSA construction"
738d80f118eSChris Lattnerphase to your front-end. In the next chapter, we will describe how you
739d80f118eSChris Lattnercan add variable mutation without building SSA in your front-end.
740d80f118eSChris Lattner
741d80f118eSChris LattnerFull Code Listing
742d80f118eSChris Lattner=================
743d80f118eSChris Lattner
744d80f118eSChris LattnerHere is the complete code listing for our running example, enhanced with
745d80f118eSChris Lattnerthe support for user-defined operators. To build this example, use:
746d80f118eSChris Lattner
747d80f118eSChris Lattner.. code-block:: bash
748d80f118eSChris Lattner
749d80f118eSChris Lattner    # Compile
750*3546b372Sxgupta    clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native` -O3 -o toy
751d80f118eSChris Lattner    # Run
752d80f118eSChris Lattner    ./toy
753d80f118eSChris Lattner
754d80f118eSChris LattnerOn some platforms, you will need to specify -rdynamic or
755d80f118eSChris Lattner-Wl,--export-dynamic when linking. This ensures that symbols defined in
756d80f118eSChris Lattnerthe main executable are exported to the dynamic linker and so are
757d80f118eSChris Lattneravailable for symbol resolution at run time. This is not needed if you
758d80f118eSChris Lattnercompile your support code into a shared library, although doing that
759d80f118eSChris Lattnerwill cause problems on Windows.
760d80f118eSChris Lattner
761d80f118eSChris LattnerHere is the code:
762d80f118eSChris Lattner
763147e0ddaSHans Wennborg.. literalinclude:: ../../../examples/Kaleidoscope/Chapter6/toy.cpp
764d80f118eSChris Lattner   :language: c++
765d80f118eSChris Lattner
766d80f118eSChris Lattner`Next: Extending the language: mutable variables / SSA
767d80f118eSChris Lattnerconstruction <LangImpl07.html>`_
768d80f118eSChris Lattner
769