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