LangImpl06.rst 31 KB

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