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