1:orphan: 2 3============================================================ 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 std::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 std::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 765.. literalinclude:: ../../../examples/Kaleidoscope/Chapter6/toy.cpp 766 :language: c++ 767 768`Next: Extending the language: mutable variables / SSA 769construction <LangImpl07.html>`_ 770 771