X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=docs%2Ftutorial%2FLangImpl7.rst;h=3ab27deebe2d3e4bdc0d1f58d3b517cec1f615e2;hb=a884848a9a8d79469679ad9a2222b8ac2d3ea2b5;hp=c44590836b89dcbf01953f0ec8a75c68898b6da3;hpb=092251cccb575807be704de0f5ec9dbe2c43799a;p=oota-llvm.git diff --git a/docs/tutorial/LangImpl7.rst b/docs/tutorial/LangImpl7.rst index c44590836b8..3ab27deebe2 100644 --- a/docs/tutorial/LangImpl7.rst +++ b/docs/tutorial/LangImpl7.rst @@ -355,10 +355,11 @@ from the stack slot: .. code-block:: c++ - Value *VariableExprAST::Codegen() { + Value *VariableExprAST::codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - if (V == 0) return ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); // Load the value. return Builder.CreateLoad(V, Name.c_str()); @@ -366,7 +367,7 @@ from the stack slot: As you can see, this is pretty straightforward. Now we need to update the things that define the variables to set up the alloca. We'll start -with ``ForExprAST::Codegen`` (see the `full code listing <#code>`_ for +with ``ForExprAST::codegen()`` (see the `full code listing <#code>`_ for the unabridged code): .. code-block:: c++ @@ -377,16 +378,18 @@ the unabridged code): AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, VarName); // Emit the start code first, without 'variable' in scope. - Value *StartVal = Start->Codegen(); - if (StartVal == 0) return 0; + Value *StartVal = Start->codegen(); + if (!StartVal) + return nullptr; // Store the value into the alloca. Builder.CreateStore(StartVal, Alloca); ... // Compute the end condition. - Value *EndCond = End->Codegen(); - if (EndCond == 0) return EndCond; + Value *EndCond = End->codegen(); + if (!EndCond) + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -423,7 +426,7 @@ them. The code for this is also pretty simple: For each argument, we make an alloca, store the input value to the function into the alloca, and register the alloca as the memory location -for the argument. This method gets invoked by ``FunctionAST::Codegen`` +for the argument. This method gets invoked by ``FunctionAST::codegen()`` right after it sets up the entry block for the function. The final missing piece is adding the mem2reg pass, which allows us to @@ -569,11 +572,11 @@ implement codegen for the assignment operator. This looks like: .. code-block:: c++ - Value *BinaryExprAST::Codegen() { + Value *BinaryExprAST::codegen() { // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. - VariableExprAST *LHSE = dynamic_cast(LHS); + VariableExprAST *LHSE = dynamic_cast(LHS.get()); if (!LHSE) return ErrorV("destination of '=' must be a variable"); @@ -587,12 +590,14 @@ allowed. .. code-block:: c++ // Codegen the RHS. - Value *Val = RHS->Codegen(); - if (Val == 0) return 0; + Value *Val = RHS->codegen(); + if (!Val) + return nullptr; // Look up the name. Value *Variable = NamedValues[LHSE->getName()]; - if (Variable == 0) return ErrorV("Unknown variable name"); + if (!Variable) + return ErrorV("Unknown variable name"); Builder.CreateStore(Val, Variable); return Val; @@ -632,7 +637,7 @@ own local variables, lets add this next! User-defined Local Variables ============================ -Adding var/in is just like any other other extensions we made to +Adding var/in is just like any other extension we made to Kaleidoscope: we extend the lexer, the parser, the AST and the code generator. The first step for adding our new 'var/in' construct is to extend the lexer. As before, this is pretty trivial, the code looks like @@ -649,10 +654,14 @@ this: ... static int gettok() { ... - if (IdentifierStr == "in") return tok_in; - if (IdentifierStr == "binary") return tok_binary; - if (IdentifierStr == "unary") return tok_unary; - if (IdentifierStr == "var") return tok_var; + if (IdentifierStr == "in") + return tok_in; + if (IdentifierStr == "binary") + return tok_binary; + if (IdentifierStr == "unary") + return tok_unary; + if (IdentifierStr == "var") + return tok_var; return tok_identifier; ... @@ -663,14 +672,15 @@ var/in, it looks like this: /// VarExprAST - Expression class for var/in class VarExprAST : public ExprAST { - std::vector > VarNames; - ExprAST *Body; + std::vector>> VarNames; + std::unique_ptr Body; + public: - VarExprAST(const std::vector > &varnames, - ExprAST *body) - : VarNames(varnames), Body(body) {} + VarExprAST(std::vector>> VarNames, + std::unique_ptr body) + : VarNames(std::move(VarNames)), Body(std::move(Body)) {} - virtual Value *Codegen(); + virtual Value *codegen(); }; var/in allows a list of names to be defined all at once, and each name @@ -690,15 +700,22 @@ do is add it as a primary expression: /// ::= ifexpr /// ::= forexpr /// ::= varexpr - static ExprAST *ParsePrimary() { + static std::unique_ptr ParsePrimary() { switch (CurTok) { - default: return Error("unknown token when expecting an expression"); - case tok_identifier: return ParseIdentifierExpr(); - case tok_number: return ParseNumberExpr(); - case '(': return ParseParenExpr(); - case tok_if: return ParseIfExpr(); - case tok_for: return ParseForExpr(); - case tok_var: return ParseVarExpr(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); + case tok_if: + return ParseIfExpr(); + case tok_for: + return ParseForExpr(); + case tok_var: + return ParseVarExpr(); } } @@ -708,10 +725,10 @@ Next we define ParseVarExpr: /// varexpr ::= 'var' identifier ('=' expression)? // (',' identifier ('=' expression)?)* 'in' expression - static ExprAST *ParseVarExpr() { + static std::unique_ptr ParseVarExpr() { getNextToken(); // eat the var. - std::vector > VarNames; + std::vector>> VarNames; // At least one variable name is required. if (CurTok != tok_identifier) @@ -727,15 +744,15 @@ into the local ``VarNames`` vector. getNextToken(); // eat identifier. // Read the optional initializer. - ExprAST *Init = 0; + std::unique_ptr Init; if (CurTok == '=') { getNextToken(); // eat the '='. Init = ParseExpression(); - if (Init == 0) return 0; + if (!Init) return nullptr; } - VarNames.push_back(std::make_pair(Name, Init)); + VarNames.push_back(std::make_pair(Name, std::move(Init))); // End of var list, exit loop. if (CurTok != ',') break; @@ -755,10 +772,12 @@ AST node: return Error("expected 'in' keyword after 'var'"); getNextToken(); // eat 'in'. - ExprAST *Body = ParseExpression(); - if (Body == 0) return 0; + auto Body = ParseExpression(); + if (!Body) + return nullptr; - return new VarExprAST(VarNames, Body); + return llvm::make_unique(std::move(VarNames), + std::move(Body)); } Now that we can parse and represent the code, we need to support @@ -766,7 +785,7 @@ emission of LLVM IR for it. This code starts out with: .. code-block:: c++ - Value *VarExprAST::Codegen() { + Value *VarExprAST::codegen() { std::vector OldBindings; Function *TheFunction = Builder.GetInsertBlock()->getParent(); @@ -774,7 +793,7 @@ emission of LLVM IR for it. This code starts out with: // Register all variables and emit their initializer. for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { const std::string &VarName = VarNames[i].first; - ExprAST *Init = VarNames[i].second; + ExprAST *Init = VarNames[i].second.get(); Basically it loops over all the variables, installing them one at a time. For each variable we put into the symbol table, we remember the @@ -789,8 +808,9 @@ previous value that we replace in OldBindings. // var a = a in ... # refers to outer 'a'. Value *InitVal; if (Init) { - InitVal = Init->Codegen(); - if (InitVal == 0) return 0; + InitVal = Init->codegen(); + if (!InitVal) + return nullptr; } else { // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); } @@ -814,8 +834,9 @@ we evaluate the body of the var/in expression: .. code-block:: c++ // Codegen the body, now that all vars are in scope. - Value *BodyVal = Body->Codegen(); - if (BodyVal == 0) return 0; + Value *BodyVal = Body->codegen(); + if (!BodyVal) + return nullptr; Finally, before returning, we restore the previous variable bindings: