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