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