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