From 3ae1bf6e18e4a8b1fd9c97e9de180da3dc406f74 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 19 Aug 2015 18:15:58 +0000 Subject: [PATCH] [Kaleidoscope] Clang-format the Kaleidoscope tutorials. Also reduces changes between tutorial chapters. llvm-svn: 245472 --- docs/tutorial/LangImpl1.rst | 19 +- docs/tutorial/LangImpl2.rst | 74 +++-- docs/tutorial/LangImpl3.rst | 46 ++- docs/tutorial/LangImpl4.rst | 3 +- docs/tutorial/LangImpl5.rst | 125 +++++--- docs/tutorial/LangImpl6.rst | 53 ++-- docs/tutorial/LangImpl7.rst | 58 ++-- docs/tutorial/LangImpl8.rst | 14 +- examples/Kaleidoscope/Chapter2/CMakeLists.txt | 2 + examples/Kaleidoscope/Chapter2/Makefile | 2 + examples/Kaleidoscope/Chapter2/toy.cpp | 221 +++++++------ examples/Kaleidoscope/Chapter3/toy.cpp | 296 ++++++++++-------- examples/Kaleidoscope/Chapter4/toy.cpp | 70 +++-- examples/Kaleidoscope/Chapter5/toy.cpp | 107 ++++--- examples/Kaleidoscope/Chapter6/toy.cpp | 114 ++++--- examples/Kaleidoscope/Chapter7/toy.cpp | 127 ++++---- examples/Kaleidoscope/Chapter8/toy.cpp | 195 ++++++------ 17 files changed, 886 insertions(+), 640 deletions(-) diff --git a/docs/tutorial/LangImpl1.rst b/docs/tutorial/LangImpl1.rst index 6840bd6b090..0240986164f 100644 --- a/docs/tutorial/LangImpl1.rst +++ b/docs/tutorial/LangImpl1.rst @@ -169,14 +169,16 @@ numeric value of a number). First, we define the possibilities: tok_eof = -1, // commands - tok_def = -2, tok_extern = -3, + tok_def = -2, + tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5, + tok_identifier = -4, + tok_number = -5, }; - static std::string IdentifierStr; // Filled in if tok_identifier - static double NumVal; // Filled in if tok_number + static std::string IdentifierStr; // Filled in if tok_identifier + static double NumVal; // Filled in if tok_number Each token returned by our lexer will either be one of the Token enum values or it will be an 'unknown' character like '+', which is returned @@ -217,8 +219,10 @@ loop: while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; return tok_identifier; } @@ -250,7 +254,8 @@ extend it :). Next we handle comments: if (LastChar == '#') { // Comment until end of line. - do LastChar = getchar(); + do + LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); if (LastChar != EOF) diff --git a/docs/tutorial/LangImpl2.rst b/docs/tutorial/LangImpl2.rst index 4b28e02a523..09c55e60f3a 100644 --- a/docs/tutorial/LangImpl2.rst +++ b/docs/tutorial/LangImpl2.rst @@ -44,6 +44,7 @@ We'll start with expressions first: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} }; @@ -65,6 +66,7 @@ language: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} }; @@ -73,6 +75,7 @@ language: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char op, std::unique_ptr LHS, std::unique_ptr RHS) @@ -83,6 +86,7 @@ language: class CallExprAST : public ExprAST { std::string Callee; std::vector Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) @@ -111,6 +115,7 @@ way to talk about functions themselves: class PrototypeAST { std::string Name; std::vector Args; + public: PrototypeAST(const std::string &name, std::vector Args) : Name(name), Args(std::move(Args)) {} @@ -120,6 +125,7 @@ way to talk about functions themselves: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) @@ -171,9 +177,14 @@ be parsed. /// Error* - These are little helper functions for error handling. - ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} - PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } - FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } + std::unique_ptr Error(const char *Str) { + fprintf(stderr, "Error: %s\n", Str); + return nullptr; + } + std::unique_ptr ErrorP(const char *Str) { + Error(Str); + return nullptr; + } The ``Error`` routines are simple helper routines that our parser will use to handle errors. The error recovery in our parser will not be the @@ -216,13 +227,14 @@ the parenthesis operator is defined like this: /// parenexpr ::= '(' expression ')' static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. + getNextToken(); // eat (. auto V = ParseExpression(); - if (!V) return nullptr; + if (!V) + return nullptr; if (CurTok != ')') return Error("expected ')'"); - getNextToken(); // eat ). + getNextToken(); // eat ). return V; } @@ -267,11 +279,13 @@ function calls: std::vector> Args; if (CurTok != ')') { while (1) { - auto Arg = ParseExpression(); - if (!Arg) return nullptr; - Args.push_back(std::move(Arg)); + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; - if (CurTok == ')') break; + if (CurTok == ')') + break; if (CurTok != ',') return Error("Expected ')' or ',' in argument list"); @@ -309,10 +323,14 @@ primary expression, we need to determine what sort of expression it is: /// ::= parenexpr 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(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); } } @@ -396,7 +414,8 @@ a sequence of [binop,primaryexpr] pairs: /// static std::unique_ptr ParseExpression() { auto LHS = ParsePrimary(); - if (!LHS) return nullptr; + if (!LHS) + return nullptr; return ParseBinOpRHS(0, std::move(LHS)); } @@ -446,7 +465,8 @@ expression: // Parse the primary expression after the binary operator. auto RHS = ParsePrimary(); - if (!RHS) return nullptr; + if (!RHS) + return nullptr; As such, this code eats (and remembers) the binary operator and then parses the primary expression that follows. This builds up the whole @@ -505,7 +525,8 @@ above two blocks duplicated for context): int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS)); - if (RHS == 0) return 0; + if (!RHS) + return nullptr; } // Merge LHS/RHS. LHS = llvm::make_unique(BinOp, std::move(LHS), @@ -633,11 +654,20 @@ include the top-level loop. See `below <#code>`_ for full code in the while (1) { fprintf(stderr, "ready> "); switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; + case tok_eof: + return; + case ';': // ignore top-level semicolons. + getNextToken(); + break; + case tok_def: + HandleDefinition(); + break; + case tok_extern: + HandleExtern(); + break; + default: + HandleTopLevelExpression(); + break; } } } diff --git a/docs/tutorial/LangImpl3.rst b/docs/tutorial/LangImpl3.rst index 0920aa3f6a2..a2d23e7bcf9 100644 --- a/docs/tutorial/LangImpl3.rst +++ b/docs/tutorial/LangImpl3.rst @@ -41,6 +41,7 @@ class: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} virtual Value *Codegen(); @@ -72,7 +73,10 @@ parser, which will be used to report errors found during code generation .. code-block:: c++ - Value *ErrorV(const char *Str) { Error(Str); return 0; } + Value *ErrorV(const char *Str) { + Error(Str); + return nullptr; + } static Module *TheModule; static IRBuilder<> Builder(getGlobalContext()); @@ -145,18 +149,23 @@ variables `_. Value *BinaryExprAST::Codegen() { Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); - if (L == 0 || R == 0) return 0; + if (!L || !R) + return nullptr; switch (Op) { - case '+': return Builder.CreateFAdd(L, R, "addtmp"); - case '-': return Builder.CreateFSub(L, R, "subtmp"); - case '*': return Builder.CreateFMul(L, R, "multmp"); + case '+': + return Builder.CreateFAdd(L, R, "addtmp"); + case '-': + return Builder.CreateFSub(L, R, "subtmp"); + case '*': + return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); - default: return ErrorV("invalid binary operator"); + default: + return ErrorV("invalid binary operator"); } } @@ -201,17 +210,18 @@ would return 0.0 and -1.0, depending on the input value. Value *CallExprAST::Codegen() { // Look up the name in the global module table. Function *CalleeF = TheModule->getFunction(Callee); - if (CalleeF == 0) + if (!CalleeF) return ErrorV("Unknown function referenced"); // If argument mismatch error. if (CalleeF->arg_size() != Args.size()) return ErrorV("Incorrect # arguments passed"); - std::vector ArgsV; + std::vector ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { ArgsV.push_back(Args[i]->Codegen()); - if (ArgsV.back() == 0) return 0; + if (!ArgsV.back()) + return nullptr; } return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); @@ -253,10 +263,11 @@ with: // Make the function type: double(double,double) etc. std::vector Doubles(Args.size(), Type::getDoubleTy(getGlobalContext())); - FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), - Doubles, false); + FunctionType *FT = + FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); - Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule); + Function *F = + Function::Create(FT, Function::ExternalLinkage, Name, TheModule); This code packs a lot of power into a few lines. Note first that this function returns a "Function\*" instead of a "Value\*". Because a @@ -321,13 +332,13 @@ then deletes it. // If F already has a body, reject this. if (!F->empty()) { ErrorF("redefinition of function"); - return 0; + return nullptr; } // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorF("redefinition of function with different # args"); - return 0; + return nullptr; } } @@ -351,6 +362,7 @@ we emit an error. // Add arguments to variable symbol table. NamedValues[Args[Idx]] = AI; } + return F; } @@ -368,8 +380,8 @@ straight-forward with the mechanics we have already used above. NamedValues.clear(); Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; + if (!TheFunction) + return nullptr; Code generation for function definitions starts out simply enough: we just codegen the prototype (Proto) and verify that it is ok. We then @@ -423,7 +435,7 @@ function is finished and validated, we return it. // Error reading body, remove function. TheFunction->eraseFromParent(); - return 0; + return nullptr; } The only piece left here is handling of the error case. For simplicity, diff --git a/docs/tutorial/LangImpl4.rst b/docs/tutorial/LangImpl4.rst index 8abb7456949..497a4c56a38 100644 --- a/docs/tutorial/LangImpl4.rst +++ b/docs/tutorial/LangImpl4.rst @@ -400,8 +400,7 @@ example, if we add: .. code-block:: c++ /// putchard - putchar that takes a double and returns 0. - extern "C" - double putchard(double X) { + extern "C" double putchard(double X) { putchar((char)X); return 0; } diff --git a/docs/tutorial/LangImpl5.rst b/docs/tutorial/LangImpl5.rst index add0e188734..c0420fa70f7 100644 --- a/docs/tutorial/LangImpl5.rst +++ b/docs/tutorial/LangImpl5.rst @@ -66,7 +66,9 @@ for the relevant tokens: .. code-block:: c++ // control - tok_if = -6, tok_then = -7, tok_else = -8, + tok_if = -6, + tok_then = -7, + tok_else = -8, Once we have that, we recognize the new keywords in the lexer. This is pretty simple stuff: @@ -74,11 +76,16 @@ pretty simple stuff: .. code-block:: c++ ... - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; - if (IdentifierStr == "if") return tok_if; - if (IdentifierStr == "then") return tok_then; - if (IdentifierStr == "else") return tok_else; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; + if (IdentifierStr == "if") + return tok_if; + if (IdentifierStr == "then") + return tok_then; + if (IdentifierStr == "else") + return tok_else; return tok_identifier; AST Extensions for If/Then/Else @@ -91,6 +98,7 @@ To represent the new expression we add a new AST node for it: /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique Cond, Then, Else; + public: IfExprAST(std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) @@ -115,14 +123,16 @@ First we define a new parsing function: // condition. auto Cond = ParseExpression(); - if (!Cond) return nullptr; + if (!Cond) + return nullptr; if (CurTok != tok_then) return Error("expected then"); getNextToken(); // eat the then auto Then = ParseExpression(); - if (Then) return nullptr; + if (!Then) + return nullptr; if (CurTok != tok_else) return Error("expected else"); @@ -130,7 +140,8 @@ First we define a new parsing function: getNextToken(); auto Else = ParseExpression(); - if (!Else) return nullptr; + if (!Else) + return nullptr; return llvm::make_unique(std::move(Cond), std::move(Then), std::move(Else)); @@ -142,11 +153,16 @@ Next we hook it up as a primary expression: 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(); + 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(); } } @@ -271,12 +287,12 @@ for ``IfExprAST``: Value *IfExprAST::Codegen() { Value *CondV = Cond->Codegen(); - if (!CondV) return nullptr; + if (!CondV) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. - CondV = Builder.CreateFCmpONE(CondV, - ConstantFP::get(getGlobalContext(), APFloat(0.0)), - "ifcond"); + CondV = Builder.CreateFCmpONE( + CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond"); This code is straightforward and similar to what we saw before. We emit the expression for the condition, then compare that value to zero to get @@ -288,7 +304,8 @@ a truth value as a 1-bit (bool) value. // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. - BasicBlock *ThenBB = BasicBlock::Create(getGlobalContext(), "then", TheFunction); + BasicBlock *ThenBB = + BasicBlock::Create(getGlobalContext(), "then", TheFunction); BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else"); BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont"); @@ -321,7 +338,8 @@ that LLVM supports forward references. Builder.SetInsertPoint(ThenBB); Value *ThenV = Then->Codegen(); - if (ThenV == 0) return 0; + if (!ThenV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. @@ -362,7 +380,8 @@ value for code that will set up the Phi node. Builder.SetInsertPoint(ElseBB); Value *ElseV = Else->Codegen(); - if (ElseV == 0) return 0; + if (!ElseV) + return nullptr; Builder.CreateBr(MergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. @@ -380,8 +399,8 @@ code: // Emit merge block. TheFunction->getBasicBlockList().push_back(MergeBB); Builder.SetInsertPoint(MergeBB); - PHINode *PN = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, - "iftmp"); + PHINode *PN = + Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp"); PN->addIncoming(ThenV, ThenBB); PN->addIncoming(ElseV, ElseBB); @@ -446,13 +465,20 @@ The lexer extensions are the same sort of thing as for if/then/else: tok_for = -9, tok_in = -10 ... in gettok ... - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; - if (IdentifierStr == "if") return tok_if; - if (IdentifierStr == "then") return tok_then; - if (IdentifierStr == "else") return tok_else; - if (IdentifierStr == "for") return tok_for; - if (IdentifierStr == "in") return tok_in; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; + if (IdentifierStr == "if") + return tok_if; + if (IdentifierStr == "then") + return tok_then; + if (IdentifierStr == "else") + return tok_else; + if (IdentifierStr == "for") + return tok_for; + if (IdentifierStr == "in") + return tok_in; return tok_identifier; AST Extensions for the 'for' Loop @@ -467,6 +493,7 @@ variable name and the constituent expressions in the node. class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; + public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, @@ -502,20 +529,23 @@ value to null in the AST node: auto Start = ParseExpression(); - if (!Start) return nullptr; + if (!Start) + return nullptr; if (CurTok != ',') return Error("expected ',' after for start value"); getNextToken(); auto End = ParseExpression(); - if (!End) return nullptr; + if (!End) + return nullptr; // The step value is optional. std::unique_ptr Step; if (CurTok == ',') { getNextToken(); Step = ParseExpression(); - if (!Step) return nullptr; + if (!Step) + return nullptr; } if (CurTok != tok_in) @@ -523,7 +553,8 @@ value to null in the AST node: getNextToken(); // eat 'in'. auto Body = ParseExpression(); - if (!Body) return nullptr; + if (!Body) + return nullptr; return llvm::make_unique(IdName, std::move(Start), std::move(End), std::move(Step), @@ -593,7 +624,8 @@ expression). // block. Function *TheFunction = Builder.GetInsertBlock()->getParent(); BasicBlock *PreheaderBB = Builder.GetInsertBlock(); - BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", TheFunction); + BasicBlock *LoopBB = + BasicBlock::Create(getGlobalContext(), "loop", TheFunction); // Insert an explicit fall through from the current block to the LoopBB. Builder.CreateBr(LoopBB); @@ -610,7 +642,8 @@ the two blocks. Builder.SetInsertPoint(LoopBB); // Start the PHI node with an entry for Start. - PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, VarName.c_str()); + PHINode *Variable = Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), + 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB); Now that the "preheader" for the loop is set up, we switch to emitting @@ -630,8 +663,8 @@ backedge, but we can't set it up yet (because it doesn't exist!). // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. - if (Body->Codegen() == 0) - return 0; + if (!Body->Codegen()) + return nullptr; Now the code starts to get more interesting. Our 'for' loop introduces a new variable to the symbol table. This means that our symbol table can @@ -653,10 +686,11 @@ table. .. code-block:: c++ // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { StepVal = Step->Codegen(); - if (StepVal == 0) return 0; + if (!StepVal) + return nullptr; } else { // If not specified, use 1.0. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0)); @@ -673,12 +707,12 @@ iteration of the loop. // Compute the end condition. Value *EndCond = End->Codegen(); - if (EndCond == 0) return EndCond; + if (!EndCond) + return nullptr; // Convert condition to a bool by comparing equal to 0.0. - EndCond = Builder.CreateFCmpONE(EndCond, - ConstantFP::get(getGlobalContext(), APFloat(0.0)), - "loopcond"); + EndCond = Builder.CreateFCmpONE( + EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond"); Finally, we evaluate the exit value of the loop, to determine whether the loop should exit. This mirrors the condition evaluation for the @@ -688,7 +722,8 @@ if/then/else statement. // Create the "after loop" block and insert it. BasicBlock *LoopEndBB = Builder.GetInsertBlock(); - BasicBlock *AfterBB = BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); + BasicBlock *AfterBB = + BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction); // Insert the conditional branch into the end of LoopEndBB. Builder.CreateCondBr(EndCond, LoopBB, AfterBB); diff --git a/docs/tutorial/LangImpl6.rst b/docs/tutorial/LangImpl6.rst index b3138182a29..4918cb08edf 100644 --- a/docs/tutorial/LangImpl6.rst +++ b/docs/tutorial/LangImpl6.rst @@ -96,15 +96,20 @@ keywords: enum Token { ... // operators - tok_binary = -11, tok_unary = -12 + tok_binary = -11, + tok_unary = -12 }; ... static int gettok() { ... - if (IdentifierStr == "for") return tok_for; - if (IdentifierStr == "in") return tok_in; - if (IdentifierStr == "binary") return tok_binary; - if (IdentifierStr == "unary") return tok_unary; + if (IdentifierStr == "for") + return tok_for; + if (IdentifierStr == "in") + return tok_in; + if (IdentifierStr == "binary") + return tok_binary; + if (IdentifierStr == "unary") + return tok_unary; return tok_identifier; This just adds lexer support for the unary and binary keywords, like we @@ -131,6 +136,7 @@ this: std::vector Args; bool IsOperator; unsigned Precedence; // Precedence if a binary op. + public: PrototypeAST(const std::string &name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) @@ -211,8 +217,8 @@ user-defined operator, we need to parse it: if (Kind && ArgNames.size() != Kind) return ErrorP("Invalid number of operands for operator"); - return llvm::make_unique(FnName, std::move(ArgNames), - Kind != 0, BinaryPrecedence); + return llvm::make_unique(FnName, std::move(ArgNames), Kind != 0, + BinaryPrecedence); } This is all fairly straightforward parsing code, and we have already @@ -232,23 +238,28 @@ default case for our existing binary operator node: Value *BinaryExprAST::Codegen() { Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); - if (L == 0 || R == 0) return 0; + if (!L || !R) + return nullptr; switch (Op) { - case '+': return Builder.CreateFAdd(L, R, "addtmp"); - case '-': return Builder.CreateFSub(L, R, "subtmp"); - case '*': return Builder.CreateFMul(L, R, "multmp"); + case '+': + return Builder.CreateFAdd(L, R, "addtmp"); + case '-': + return Builder.CreateFSub(L, R, "subtmp"); + case '*': + return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); - default: break; + default: + break; } // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. - Function *F = TheModule->getFunction(std::string("binary")+Op); + Function *F = TheModule->getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); Value *Ops[2] = { L, R }; @@ -269,8 +280,8 @@ The final piece of code we are missing, is a bit of top-level magic: NamedValues.clear(); Function *TheFunction = Proto->Codegen(); - if (TheFunction == 0) - return 0; + if (!TheFunction) + return nullptr; // If this is an operator, install it. if (Proto->isBinaryOp()) @@ -308,6 +319,7 @@ that, we need an AST node: class UnaryExprAST : public ExprAST { char Opcode; std::unique_ptr Operand; + public: UnaryExprAST(char Opcode, std::unique_ptr Operand) : Opcode(Opcode), Operand(std::move(Operand)) {} @@ -357,7 +369,8 @@ call ParseUnary instead: ... // Parse the unary expression after the binary operator. auto RHS = ParseUnary(); - if (!RHS) return nullptr; + if (!RHS) + return nullptr; ... } /// expression @@ -365,7 +378,8 @@ call ParseUnary instead: /// static std::unique_ptr ParseExpression() { auto LHS = ParseUnary(); - if (!LHS) return nullptr; + if (!LHS) + return nullptr; return ParseBinOpRHS(0, std::move(LHS)); } @@ -416,10 +430,11 @@ unary operators. It looks like this: Value *UnaryExprAST::Codegen() { Value *OperandV = Operand->Codegen(); - if (OperandV == 0) return 0; + if (!OperandV) + return nullptr; Function *F = TheModule->getFunction(std::string("unary")+Opcode); - if (F == 0) + if (!F) return ErrorV("Unknown unary operator"); return Builder.CreateCall(F, OperandV, "unop"); diff --git a/docs/tutorial/LangImpl7.rst b/docs/tutorial/LangImpl7.rst index 33f48535f16..8c35f2ac019 100644 --- a/docs/tutorial/LangImpl7.rst +++ b/docs/tutorial/LangImpl7.rst @@ -358,7 +358,8 @@ from the stack slot: 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()); @@ -378,7 +379,8 @@ the unabridged code): // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->Codegen(); - if (StartVal == 0) return 0; + if (!StartVal) + return nullptr; // Store the value into the alloca. Builder.CreateStore(StartVal, Alloca); @@ -386,7 +388,8 @@ the unabridged code): // Compute the end condition. Value *EndCond = End->Codegen(); - if (EndCond == 0) return EndCond; + if (!EndCond) + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -588,11 +591,13 @@ allowed. // Codegen the RHS. Value *Val = RHS->Codegen(); - if (Val == 0) return 0; + 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; @@ -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; ... @@ -665,6 +674,7 @@ var/in, it looks like this: class VarExprAST : public ExprAST { std::vector>> VarNames; std::unique_ptr Body; + public: VarExprAST(std::vector>> VarNames, std::unique_ptr body) @@ -692,13 +702,20 @@ do is add it as a primary expression: /// ::= varexpr 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(); } } @@ -756,7 +773,8 @@ AST node: getNextToken(); // eat 'in'. auto Body = ParseExpression(); - if (!Body) return nullptr; + if (!Body) + return nullptr; return llvm::make_unique(std::move(VarNames), std::move(Body)); @@ -791,7 +809,8 @@ previous value that we replace in OldBindings. Value *InitVal; if (Init) { InitVal = Init->Codegen(); - if (InitVal == 0) return 0; + if (!InitVal) + return nullptr; } else { // If not specified, use 0.0. InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0)); } @@ -816,7 +835,8 @@ we evaluate the body of the var/in expression: // Codegen the body, now that all vars are in scope. Value *BodyVal = Body->Codegen(); - if (BodyVal == 0) return 0; + if (!BodyVal) + return nullptr; Finally, before returning, we restore the previous variable bindings: diff --git a/docs/tutorial/LangImpl8.rst b/docs/tutorial/LangImpl8.rst index 2f994c23d25..77e3e429674 100644 --- a/docs/tutorial/LangImpl8.rst +++ b/docs/tutorial/LangImpl8.rst @@ -307,10 +307,12 @@ and then we have added to all of our AST classes a source location: SourceLocation Loc; public: + ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} + virtual ~ExprAST() {} + virtual Value* Codegen() = 0; int getLine() const { return Loc.Line; } int getCol() const { return Loc.Col; } - ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} - virtual std::ostream &dump(std::ostream &out, int ind) { + virtual raw_ostream &dump(raw_ostream &out, int ind) { return out << ':' << getLine() << ':' << getCol() << '\n'; } @@ -399,9 +401,9 @@ argument allocas in ``PrototypeAST::CreateArgumentAllocas``. DILocalVariable D = DBuilder->createParameterVariable( Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true); - Instruction *Call = DBuilder->insertDeclare( - Alloca, D, DBuilder->createExpression(), Builder.GetInsertBlock()); - Call->setDebugLoc(DebugLoc::get(Line, 0, Scope)); + DBuilder->insertDeclare(Alloca, D, DBuilder->createExpression(), + DebugLoc::get(Line, 0, Scope), + Builder.GetInsertBlock()); Here we're doing a few things. First, we're grabbing our current scope for the variable so we can say what range of code our variable is valid @@ -409,7 +411,7 @@ through. Second, we're creating the variable, giving it the scope, the name, source location, type, and since it's an argument, the argument index. Third, we create an ``lvm.dbg.declare`` call to indicate at the IR level that we've got a variable in an alloca (and it gives a starting -location for the variable). Lastly, we set a source location for the +location for the variable), and setting a source location for the beginning of the scope on the declare. One interesting thing to note at this point is that various debuggers have diff --git a/examples/Kaleidoscope/Chapter2/CMakeLists.txt b/examples/Kaleidoscope/Chapter2/CMakeLists.txt index fed3f4b78c7..a02faa22130 100644 --- a/examples/Kaleidoscope/Chapter2/CMakeLists.txt +++ b/examples/Kaleidoscope/Chapter2/CMakeLists.txt @@ -1,3 +1,5 @@ +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-private-field") + add_kaleidoscope_chapter(Kaleidoscope-Ch2 toy.cpp ) diff --git a/examples/Kaleidoscope/Chapter2/Makefile b/examples/Kaleidoscope/Chapter2/Makefile index 1a9b94ce541..fa27e6e0668 100644 --- a/examples/Kaleidoscope/Chapter2/Makefile +++ b/examples/Kaleidoscope/Chapter2/Makefile @@ -10,4 +10,6 @@ LEVEL = ../../.. TOOLNAME = Kaleidoscope-Ch2 EXAMPLE_TOOL = 1 +LLVM_CXXFLAGS := -Wno-unused-private-field + include $(LEVEL)/Makefile.common diff --git a/examples/Kaleidoscope/Chapter2/toy.cpp b/examples/Kaleidoscope/Chapter2/toy.cpp index 789caabce0f..9ecf75d3467 100644 --- a/examples/Kaleidoscope/Chapter2/toy.cpp +++ b/examples/Kaleidoscope/Chapter2/toy.cpp @@ -15,14 +15,16 @@ enum Token { tok_eof = -1, // commands - tok_def = -2, tok_extern = -3, + tok_def = -2, + tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5 + tok_identifier = -4, + tok_number = -5 }; -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number +static std::string IdentifierStr; // Filled in if tok_identifier +static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { @@ -37,12 +39,14 @@ static int gettok() { while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; return tok_identifier; } - if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ + if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ std::string NumStr; do { NumStr += LastChar; @@ -55,13 +59,14 @@ static int gettok() { if (LastChar == '#') { // Comment until end of line. - do LastChar = getchar(); + do + LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -84,32 +89,40 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { + double Val; + public: - NumberExprAST(double Val) {} + NumberExprAST(double Val) : Val(Val) {} }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} }; /// BinaryExprAST - Expression class for a binary operator. class BinaryExprAST : public ExprAST { + char Op; + std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, - std::unique_ptr RHS) {} + std::unique_ptr RHS) + : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} }; /// CallExprAST - Expression class for function calls. class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) - : Callee(Callee), Args(std::move(Args)) {} + : Callee(Callee), Args(std::move(Args)) {} }; /// PrototypeAST - This class represents the "prototype" for a function, @@ -118,17 +131,21 @@ public: class PrototypeAST { std::string Name; std::vector Args; + public: PrototypeAST(const std::string &Name, std::vector Args) - : Name(Name), Args(std::move(Args)) {} - + : Name(Name), Args(std::move(Args)) {} }; /// FunctionAST - This class represents a function definition itself. class FunctionAST { + std::unique_ptr Proto; + std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, - std::unique_ptr Body) {} + std::unique_ptr Body) + : Proto(std::move(Proto)), Body(std::move(Body)) {} }; } // end anonymous namespace @@ -140,9 +157,7 @@ public: /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; -static int getNextToken() { - return CurTok = gettok(); -} +static int getNextToken() { return CurTok = gettok(); } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. @@ -152,10 +167,11 @@ static std::map BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; - if (TokPrec <= 0) return -1; + if (TokPrec <= 0) + return -1; return TokPrec; } @@ -171,41 +187,6 @@ std::unique_ptr ErrorP(const char *Str) { static std::unique_ptr ParseExpression(); -/// identifierexpr -/// ::= identifier -/// ::= identifier '(' expression* ')' -static std::unique_ptr ParseIdentifierExpr() { - std::string IdName = IdentifierStr; - - getNextToken(); // eat identifier. - - if (CurTok != '(') // Simple variable ref. - return llvm::make_unique(IdName); - - // Call. - getNextToken(); // eat ( - std::vector> Args; - if (CurTok != ')') { - while (1) { - if (auto Arg = ParseExpression()) - Args.push_back(std::move(Arg)); - else - return nullptr; - - if (CurTok == ')') break; - - if (CurTok != ',') - return Error("Expected ')' or ',' in argument list"); - getNextToken(); - } - } - - // Eat the ')'. - getNextToken(); - - return llvm::make_unique(IdName, std::move(Args)); -} - /// numberexpr ::= number static std::unique_ptr ParseNumberExpr() { auto Result = llvm::make_unique(NumVal); @@ -215,27 +196,67 @@ static std::unique_ptr ParseNumberExpr() { /// parenexpr ::= '(' expression ')' static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. + getNextToken(); // eat (. auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return Error("expected ')'"); - getNextToken(); // eat ). + getNextToken(); // eat ). return V; } +/// identifierexpr +/// ::= identifier +/// ::= identifier '(' expression* ')' +static std::unique_ptr ParseIdentifierExpr() { + std::string IdName = IdentifierStr; + + getNextToken(); // eat identifier. + + if (CurTok != '(') // Simple variable ref. + return llvm::make_unique(IdName); + + // Call. + getNextToken(); // eat ( + std::vector> Args; + if (CurTok != ')') { + while (1) { + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; + + if (CurTok == ')') + break; + + if (CurTok != ',') + return Error("Expected ')' or ',' in argument list"); + getNextToken(); + } + } + + // Eat the ')'. + getNextToken(); + + return llvm::make_unique(IdName, std::move(Args)); +} + /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr 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(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); } } @@ -246,31 +267,33 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; - getNextToken(); // eat binop - + getNextToken(); // eat binop + // Parse the primary expression after the binary operator. auto RHS = ParsePrimary(); - if (!RHS) return nullptr; - + if (!RHS) + return nullptr; + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS)); - if (!RHS) return nullptr; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } - + // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), - std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -279,8 +302,9 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, /// static std::unique_ptr ParseExpression() { auto LHS = ParsePrimary(); - if (!LHS) return nullptr; - + if (!LHS) + return nullptr; + return ParseBinOpRHS(0, std::move(LHS)); } @@ -292,28 +316,28 @@ static std::unique_ptr ParsePrototype() { std::string FnName = IdentifierStr; getNextToken(); - + if (CurTok != '(') return ErrorP("Expected '(' in prototype"); - + std::vector ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorP("Expected ')' in prototype"); - + // success. - getNextToken(); // eat ')'. - - return llvm::make_unique(std::move(FnName), - std::move(ArgNames)); + getNextToken(); // eat ')'. + + return llvm::make_unique(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression static std::unique_ptr ParseDefinition() { - getNextToken(); // eat def. + getNextToken(); // eat def. auto Proto = ParsePrototype(); - if (!Proto) return nullptr; + if (!Proto) + return nullptr; if (auto E = ParseExpression()) return llvm::make_unique(std::move(Proto), std::move(E)); @@ -324,8 +348,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", - std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -333,7 +357,7 @@ static std::unique_ptr ParseTopLevelExpr() { /// external ::= 'extern' prototype static std::unique_ptr ParseExtern() { - getNextToken(); // eat extern. + getNextToken(); // eat extern. return ParsePrototype(); } @@ -374,11 +398,20 @@ static void MainLoop() { while (1) { fprintf(stderr, "ready> "); switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; + case tok_eof: + return; + case ';': // ignore top-level semicolons. + getNextToken(); + break; + case tok_def: + HandleDefinition(); + break; + case tok_extern: + HandleExtern(); + break; + default: + HandleTopLevelExpression(); + break; } } } @@ -393,7 +426,7 @@ int main() { BinopPrecedence['<'] = 10; BinopPrecedence['+'] = 20; BinopPrecedence['-'] = 20; - BinopPrecedence['*'] = 40; // highest. + BinopPrecedence['*'] = 40; // highest. // Prime the first token. fprintf(stderr, "ready> "); diff --git a/examples/Kaleidoscope/Chapter3/toy.cpp b/examples/Kaleidoscope/Chapter3/toy.cpp index d425b101b51..29914aa0331 100644 --- a/examples/Kaleidoscope/Chapter3/toy.cpp +++ b/examples/Kaleidoscope/Chapter3/toy.cpp @@ -21,14 +21,16 @@ enum Token { tok_eof = -1, // commands - tok_def = -2, tok_extern = -3, + tok_def = -2, + tok_extern = -3, // primary - tok_identifier = -4, tok_number = -5 + tok_identifier = -4, + tok_number = -5 }; -static std::string IdentifierStr; // Filled in if tok_identifier -static double NumVal; // Filled in if tok_number +static std::string IdentifierStr; // Filled in if tok_identifier +static double NumVal; // Filled in if tok_number /// gettok - Return the next token from standard input. static int gettok() { @@ -43,12 +45,14 @@ static int gettok() { while (isalnum((LastChar = getchar()))) IdentifierStr += LastChar; - if (IdentifierStr == "def") return tok_def; - if (IdentifierStr == "extern") return tok_extern; + if (IdentifierStr == "def") + return tok_def; + if (IdentifierStr == "extern") + return tok_extern; return tok_identifier; } - if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ + if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+ std::string NumStr; do { NumStr += LastChar; @@ -61,13 +65,14 @@ static int gettok() { if (LastChar == '#') { // Comment until end of line. - do LastChar = getchar(); + do + LastChar = getchar(); while (LastChar != EOF && LastChar != '\n' && LastChar != '\r'); - + if (LastChar != EOF) return gettok(); } - + // Check for end of file. Don't eat the EOF. if (LastChar == EOF) return tok_eof; @@ -92,6 +97,7 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} Value *Codegen() override; @@ -100,6 +106,7 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} Value *Codegen() override; @@ -109,10 +116,11 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) - : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} + : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} Value *Codegen() override; }; @@ -120,10 +128,11 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) - : Callee(Callee), Args(std::move(Args)) {} + : Callee(Callee), Args(std::move(Args)) {} Value *Codegen() override; }; @@ -133,10 +142,10 @@ public: class PrototypeAST { std::string Name; std::vector Args; + public: PrototypeAST(const std::string &Name, std::vector Args) - : Name(Name), Args(std::move(Args)) {} - + : Name(Name), Args(std::move(Args)) {} Function *Codegen(); }; @@ -144,11 +153,11 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) - : Proto(std::move(Proto)), Body(std::move(Body)) {} - + : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *Codegen(); }; } // end anonymous namespace @@ -161,9 +170,7 @@ public: /// token the parser is looking at. getNextToken reads another token from the /// lexer and updates CurTok with its results. static int CurTok; -static int getNextToken() { - return CurTok = gettok(); -} +static int getNextToken() { return CurTok = gettok(); } /// BinopPrecedence - This holds the precedence for each binary operator that is /// defined. @@ -173,10 +180,11 @@ static std::map BinopPrecedence; static int GetTokPrecedence() { if (!isascii(CurTok)) return -1; - + // Make sure it's a declared binop. int TokPrec = BinopPrecedence[CurTok]; - if (TokPrec <= 0) return -1; + if (TokPrec <= 0) + return -1; return TokPrec; } @@ -196,41 +204,6 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); -/// identifierexpr -/// ::= identifier -/// ::= identifier '(' expression* ')' -static std::unique_ptr ParseIdentifierExpr() { - std::string IdName = IdentifierStr; - - getNextToken(); // eat identifier. - - if (CurTok != '(') // Simple variable ref. - return llvm::make_unique(IdName); - - // Call. - getNextToken(); // eat ( - std::vector> Args; - if (CurTok != ')') { - while (1) { - if (auto Arg = ParseExpression()) - Args.push_back(std::move(Arg)); - else - return nullptr; - - if (CurTok == ')') break; - - if (CurTok != ',') - return Error("Expected ')' or ',' in argument list"); - getNextToken(); - } - } - - // Eat the ')'. - getNextToken(); - - return llvm::make_unique(IdName, std::move(Args)); -} - /// numberexpr ::= number static std::unique_ptr ParseNumberExpr() { auto Result = llvm::make_unique(NumVal); @@ -240,27 +213,67 @@ static std::unique_ptr ParseNumberExpr() { /// parenexpr ::= '(' expression ')' static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. + getNextToken(); // eat (. auto V = ParseExpression(); if (!V) return nullptr; - + if (CurTok != ')') return Error("expected ')'"); - getNextToken(); // eat ). + getNextToken(); // eat ). return V; } +/// identifierexpr +/// ::= identifier +/// ::= identifier '(' expression* ')' +static std::unique_ptr ParseIdentifierExpr() { + std::string IdName = IdentifierStr; + + getNextToken(); // eat identifier. + + if (CurTok != '(') // Simple variable ref. + return llvm::make_unique(IdName); + + // Call. + getNextToken(); // eat ( + std::vector> Args; + if (CurTok != ')') { + while (1) { + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; + + if (CurTok == ')') + break; + + if (CurTok != ',') + return Error("Expected ')' or ',' in argument list"); + getNextToken(); + } + } + + // Eat the ')'. + getNextToken(); + + return llvm::make_unique(IdName, std::move(Args)); +} + /// primary /// ::= identifierexpr /// ::= numberexpr /// ::= parenexpr 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(); + default: + return Error("unknown token when expecting an expression"); + case tok_identifier: + return ParseIdentifierExpr(); + case tok_number: + return ParseNumberExpr(); + case '(': + return ParseParenExpr(); } } @@ -271,31 +284,33 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); - + // If this is a binop that binds at least as tightly as the current binop, // consume it, otherwise we are done. if (TokPrec < ExprPrec) return LHS; - + // Okay, we know this is a binop. int BinOp = CurTok; - getNextToken(); // eat binop - + getNextToken(); // eat binop + // Parse the primary expression after the binary operator. auto RHS = ParsePrimary(); - if (!RHS) return nullptr; - + if (!RHS) + return nullptr; + // If BinOp binds less tightly with RHS than the operator after RHS, let // the pending operator take RHS as its LHS. int NextPrec = GetTokPrecedence(); if (TokPrec < NextPrec) { - RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS)); - if (!RHS) return nullptr; + RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS)); + if (!RHS) + return nullptr; } - + // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), - std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -304,8 +319,9 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, /// static std::unique_ptr ParseExpression() { auto LHS = ParsePrimary(); - if (!LHS) return nullptr; - + if (!LHS) + return nullptr; + return ParseBinOpRHS(0, std::move(LHS)); } @@ -317,28 +333,28 @@ static std::unique_ptr ParsePrototype() { std::string FnName = IdentifierStr; getNextToken(); - + if (CurTok != '(') return ErrorP("Expected '(' in prototype"); - + std::vector ArgNames; while (getNextToken() == tok_identifier) ArgNames.push_back(IdentifierStr); if (CurTok != ')') return ErrorP("Expected ')' in prototype"); - + // success. - getNextToken(); // eat ')'. - - return llvm::make_unique(std::move(FnName), - std::move(ArgNames)); + getNextToken(); // eat ')'. + + return llvm::make_unique(FnName, std::move(ArgNames)); } /// definition ::= 'def' prototype expression static std::unique_ptr ParseDefinition() { - getNextToken(); // eat def. + getNextToken(); // eat def. auto Proto = ParsePrototype(); - if (!Proto) return nullptr; + if (!Proto) + return nullptr; if (auto E = ParseExpression()) return llvm::make_unique(std::move(Proto), std::move(E)); @@ -349,8 +365,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", - std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -358,7 +374,7 @@ static std::unique_ptr ParseTopLevelExpr() { /// external ::= 'extern' prototype static std::unique_ptr ParseExtern() { - getNextToken(); // eat extern. + getNextToken(); // eat extern. return ParsePrototype(); } @@ -366,11 +382,14 @@ static std::unique_ptr ParseExtern() { // Code Generation //===----------------------------------------------------------------------===// +Value *ErrorV(const char *Str) { + Error(Str); + return nullptr; +} + static Module *TheModule; static IRBuilder<> Builder(getGlobalContext()); -static std::map NamedValues; - -Value *ErrorV(const char *Str) { Error(Str); return nullptr; } +static std::map NamedValues; Value *NumberExprAST::Codegen() { return ConstantFP::get(getGlobalContext(), APFloat(Val)); @@ -385,18 +404,23 @@ Value *VariableExprAST::Codegen() { Value *BinaryExprAST::Codegen() { Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); - if (!L || !R) return nullptr; - + if (!L || !R) + return nullptr; + switch (Op) { - case '+': return Builder.CreateFAdd(L, R, "addtmp"); - case '-': return Builder.CreateFSub(L, R, "subtmp"); - case '*': return Builder.CreateFMul(L, R, "multmp"); + case '+': + return Builder.CreateFAdd(L, R, "addtmp"); + case '-': + return Builder.CreateFSub(L, R, "subtmp"); + case '*': + return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); - default: return ErrorV("invalid binary operator"); + default: + return ErrorV("invalid binary operator"); } } @@ -405,74 +429,75 @@ Value *CallExprAST::Codegen() { Function *CalleeF = TheModule->getFunction(Callee); if (!CalleeF) return ErrorV("Unknown function referenced"); - + // If argument mismatch error. if (CalleeF->arg_size() != Args.size()) return ErrorV("Incorrect # arguments passed"); - std::vector ArgsV; + std::vector ArgsV; for (unsigned i = 0, e = Args.size(); i != e; ++i) { ArgsV.push_back(Args[i]->Codegen()); - if (!ArgsV.back()) return nullptr; + if (!ArgsV.back()) + return nullptr; } - + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); - FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), - Doubles, false); - - Function *F = Function::Create(FT, Function::ExternalLinkage, Name, - TheModule); - + std::vector Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); + FunctionType *FT = + FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); + + Function *F = + Function::Create(FT, Function::ExternalLinkage, Name, TheModule); + // If F conflicted, there was already something named 'Name'. If it has a // body, don't allow redefinition or reextern. if (F->getName() != Name) { // Delete the one we just made and get the existing one. F->eraseFromParent(); F = TheModule->getFunction(Name); - + // If F already has a body, reject this. if (!F->empty()) { ErrorF("redefinition of function"); return nullptr; } - + // If F took a different number of args, reject. if (F->arg_size() != Args.size()) { ErrorF("redefinition of function with different # args"); return nullptr; } } - + // Set names for all arguments. unsigned Idx = 0; for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); ++AI, ++Idx) { AI->setName(Args[Idx]); - + // Add arguments to variable symbol table. NamedValues[Args[Idx]] = AI; } - + return F; } Function *FunctionAST::Codegen() { NamedValues.clear(); - + Function *TheFunction = Proto->Codegen(); if (!TheFunction) return nullptr; - + // Create a new basic block to start insertion into. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction); Builder.SetInsertPoint(BB); - + if (Value *RetVal = Body->Codegen()) { // Finish off the function. Builder.CreateRet(RetVal); @@ -482,7 +507,7 @@ Function *FunctionAST::Codegen() { return TheFunction; } - + // Error reading body, remove function. TheFunction->eraseFromParent(); return nullptr; @@ -534,26 +559,24 @@ static void MainLoop() { while (1) { fprintf(stderr, "ready> "); switch (CurTok) { - case tok_eof: return; - case ';': getNextToken(); break; // ignore top-level semicolons. - case tok_def: HandleDefinition(); break; - case tok_extern: HandleExtern(); break; - default: HandleTopLevelExpression(); break; + case tok_eof: + return; + case ';': // ignore top-level semicolons. + getNextToken(); + break; + case tok_def: + HandleDefinition(); + break; + case tok_extern: + HandleExtern(); + break; + default: + HandleTopLevelExpression(); + break; } } } -//===----------------------------------------------------------------------===// -// "Library" functions that can be "extern'd" from user code. -//===----------------------------------------------------------------------===// - -/// putchard - putchar that takes a double and returns 0. -extern "C" -double putchard(double X) { - putchar((char)X); - return 0; -} - //===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// @@ -566,14 +589,15 @@ int main() { BinopPrecedence['<'] = 10; BinopPrecedence['+'] = 20; BinopPrecedence['-'] = 20; - BinopPrecedence['*'] = 40; // highest. + BinopPrecedence['*'] = 40; // highest. // Prime the first token. fprintf(stderr, "ready> "); getNextToken(); // Make the module, which holds all the code. - std::unique_ptr Owner = llvm::make_unique("my cool jit", Context); + std::unique_ptr Owner = + llvm::make_unique("my cool jit", Context); TheModule = Owner.get(); // Run the main "interpreter loop" now. diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp index f0665f29831..eba0ab1f27d 100644 --- a/examples/Kaleidoscope/Chapter4/toy.cpp +++ b/examples/Kaleidoscope/Chapter4/toy.cpp @@ -106,6 +106,7 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} Value *Codegen() override; @@ -114,6 +115,7 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} Value *Codegen() override; @@ -123,6 +125,7 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) @@ -134,6 +137,7 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) @@ -147,9 +151,10 @@ public: class PrototypeAST { std::string Name; std::vector Args; + public: - PrototypeAST(const std::string &name, std::vector Args) - : Name(name), Args(std::move(Args)) {} + PrototypeAST(const std::string &Name, std::vector Args) + : Name(Name), Args(std::move(Args)) {} Function *Codegen(); }; @@ -157,10 +162,11 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) - : Proto(std::move(Proto)), Body(std::move(Body)) {} + : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *Codegen(); }; } // end anonymous namespace @@ -207,6 +213,26 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); +/// numberexpr ::= number +static std::unique_ptr ParseNumberExpr() { + auto Result = llvm::make_unique(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} + +/// parenexpr ::= '(' expression ')' +static std::unique_ptr ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} + /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' @@ -243,26 +269,6 @@ static std::unique_ptr ParseIdentifierExpr() { return llvm::make_unique(IdName, std::move(Args)); } -/// numberexpr ::= number -static std::unique_ptr ParseNumberExpr() { - auto Result = llvm::make_unique(NumVal); - getNextToken(); // consume the number - return std::move(Result); -} - -/// parenexpr ::= '(' expression ')' -static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. - auto V = ParseExpression(); - if (!V) - return nullptr; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; -} - /// primary /// ::= identifierexpr /// ::= numberexpr @@ -312,8 +318,8 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, } // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), - std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -368,8 +374,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", - std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -806,9 +812,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -832,6 +838,12 @@ extern "C" double putchard(double X) { return 0; } +/// printd - printf that takes a double prints it as "%f\n", returning 0. +extern "C" double printd(double X) { + printf("%f\n", X); + return 0; +} + //===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp index 042d974626d..c191d61d562 100644 --- a/examples/Kaleidoscope/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/Chapter5/toy.cpp @@ -123,6 +123,7 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} Value *Codegen() override; @@ -131,6 +132,7 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} Value *Codegen() override; @@ -140,6 +142,7 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) @@ -151,6 +154,7 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) @@ -161,6 +165,7 @@ public: /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique_ptr Cond, Then, Else; + public: IfExprAST(std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) @@ -172,6 +177,7 @@ public: class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; + public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, @@ -187,9 +193,10 @@ public: class PrototypeAST { std::string Name; std::vector Args; + public: - PrototypeAST(const std::string &name, std::vector Args) - : Name(name), Args(std::move(Args)) {} + PrototypeAST(const std::string &Name, std::vector Args) + : Name(Name), Args(std::move(Args)) {} Function *Codegen(); }; @@ -197,10 +204,11 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) - : Proto(std::move(Proto)), Body(std::move(Body)) {} + : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *Codegen(); }; } // end anonymous namespace @@ -247,6 +255,26 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); +/// numberexpr ::= number +static std::unique_ptr ParseNumberExpr() { + auto Result = llvm::make_unique(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} + +/// parenexpr ::= '(' expression ')' +static std::unique_ptr ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} + /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' @@ -283,26 +311,6 @@ static std::unique_ptr ParseIdentifierExpr() { return llvm::make_unique(IdName, std::move(Args)); } -/// numberexpr ::= number -static std::unique_ptr ParseNumberExpr() { - auto Result = llvm::make_unique(NumVal); - getNextToken(); // consume the number - return std::move(Result); -} - -/// parenexpr ::= '(' expression ')' -static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. - auto V = ParseExpression(); - if (!V) - return nullptr; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; -} - /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr ParseIfExpr() { getNextToken(); // eat the if. @@ -434,8 +442,8 @@ static std::unique_ptr ParseBinOpRHS(int ExprPrec, } // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), - std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -490,8 +498,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", - std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -624,23 +632,22 @@ Value *IfExprAST::Codegen() { return PN; } +// Output for-loop as: +// ... +// start = startexpr +// goto loop +// loop: +// variable = phi [start, loopheader], [nextvariable, loopend] +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// nextvariable = variable + step +// endcond = endexpr +// br endcond, loop, endloop +// outloop: Value *ForExprAST::Codegen() { - // Output this as: - // ... - // start = startexpr - // goto loop - // loop: - // variable = phi [start, loopheader], [nextvariable, loopend] - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // nextvariable = variable + step - // endcond = endexpr - // br endcond, loop, endloop - // outloop: - // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->Codegen(); if (!StartVal) @@ -676,7 +683,7 @@ Value *ForExprAST::Codegen() { return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { StepVal = Step->Codegen(); if (!StepVal) @@ -691,7 +698,7 @@ Value *ForExprAST::Codegen() { // Compute the end condition. Value *EndCond = End->Codegen(); if (!EndCond) - return EndCond; + return nullptr; // Convert condition to a bool by comparing equal to 0.0. EndCond = Builder.CreateFCmpONE( @@ -849,9 +856,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -875,6 +882,12 @@ extern "C" double putchard(double X) { return 0; } +/// printd - printf that takes a double prints it as "%f\n", returning 0. +extern "C" double printd(double X) { + printf("%f\n", X); + return 0; +} + //===----------------------------------------------------------------------===// // Main driver code. //===----------------------------------------------------------------------===// diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp index ba308af5120..87048bb2da4 100644 --- a/examples/Kaleidoscope/Chapter6/toy.cpp +++ b/examples/Kaleidoscope/Chapter6/toy.cpp @@ -131,6 +131,7 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} Value *Codegen() override; @@ -139,6 +140,7 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} Value *Codegen() override; @@ -159,6 +161,7 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) @@ -170,6 +173,7 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) @@ -180,6 +184,7 @@ public: /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique_ptr Cond, Then, Else; + public: IfExprAST(std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) @@ -191,12 +196,13 @@ public: class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; + public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, std::unique_ptr Body) - : VarName(VarName), Start(std::move(Start)), End(std::move(End)), - Step(std::move(Step)), Body(std::move(Body)) {} + : VarName(VarName), Start(std::move(Start)), End(std::move(End)), + Step(std::move(Step)), Body(std::move(Body)) {} Value *Codegen() override; }; @@ -208,11 +214,12 @@ class PrototypeAST { std::vector Args; bool IsOperator; unsigned Precedence; // Precedence if a binary op. + public: PrototypeAST(const std::string &Name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) - : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), - Precedence(Prec) {} + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec) {} bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } @@ -231,8 +238,10 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: - FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) + FunctionAST(std::unique_ptr Proto, + std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *Codegen(); }; @@ -280,6 +289,26 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); +/// numberexpr ::= number +static std::unique_ptr ParseNumberExpr() { + auto Result = llvm::make_unique(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} + +/// parenexpr ::= '(' expression ')' +static std::unique_ptr ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} + /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' @@ -316,26 +345,6 @@ static std::unique_ptr ParseIdentifierExpr() { return llvm::make_unique(IdName, std::move(Args)); } -/// numberexpr ::= number -static std::unique_ptr ParseNumberExpr() { - auto Result = llvm::make_unique(NumVal); - getNextToken(); // consume the number - return std::move(Result); -} - -/// parenexpr ::= '(' expression ')' -static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. - auto V = ParseExpression(); - if (!V) - return nullptr; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; -} - /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr ParseIfExpr() { getNextToken(); // eat the if. @@ -453,7 +462,8 @@ static std::unique_ptr ParseUnary() { /// binoprhs /// ::= ('+' unary)* - static std::unique_ptr ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { +static std::unique_ptr ParseBinOpRHS(int ExprPrec, + std::unique_ptr LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -482,7 +492,8 @@ static std::unique_ptr ParseUnary() { } // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -579,7 +590,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -612,7 +624,10 @@ Value *NumberExprAST::Codegen() { Value *VariableExprAST::Codegen() { // Look this variable up in the function. Value *V = NamedValues[Name]; - return V ? V : ErrorV("Unknown variable name"); + if (!V) + return ErrorV("Unknown variable name"); + + return V; } Value *UnaryExprAST::Codegen() { @@ -654,7 +669,7 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } @@ -732,23 +747,22 @@ Value *IfExprAST::Codegen() { return PN; } +// Output for-loop as: +// ... +// start = startexpr +// goto loop +// loop: +// variable = phi [start, loopheader], [nextvariable, loopend] +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// nextvariable = variable + step +// endcond = endexpr +// br endcond, loop, endloop +// outloop: Value *ForExprAST::Codegen() { - // Output this as: - // ... - // start = startexpr - // goto loop - // loop: - // variable = phi [start, loopheader], [nextvariable, loopend] - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // nextvariable = variable + step - // endcond = endexpr - // br endcond, loop, endloop - // outloop: - // Emit the start code first, without 'variable' in scope. Value *StartVal = Start->Codegen(); if (!StartVal) @@ -784,7 +798,7 @@ Value *ForExprAST::Codegen() { return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { StepVal = Step->Codegen(); if (!StepVal) @@ -799,7 +813,7 @@ Value *ForExprAST::Codegen() { // Compute the end condition. Value *EndCond = End->Codegen(); if (!EndCond) - return EndCond; + return nullptr; // Convert condition to a bool by comparing equal to 0.0. EndCond = Builder.CreateFCmpONE( @@ -964,9 +978,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp index 3c988ac9aa2..a900c5f7b16 100644 --- a/examples/Kaleidoscope/Chapter7/toy.cpp +++ b/examples/Kaleidoscope/Chapter7/toy.cpp @@ -136,6 +136,7 @@ public: /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} Value *Codegen() override; @@ -144,6 +145,7 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(const std::string &Name) : Name(Name) {} const std::string &getName() const { return Name; } @@ -154,6 +156,7 @@ public: class UnaryExprAST : public ExprAST { char Opcode; std::unique_ptr Operand; + public: UnaryExprAST(char Opcode, std::unique_ptr Operand) : Opcode(Opcode), Operand(std::move(Operand)) {} @@ -164,6 +167,7 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(char Op, std::unique_ptr LHS, std::unique_ptr RHS) @@ -175,6 +179,7 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(const std::string &Callee, std::vector> Args) @@ -185,6 +190,7 @@ public: /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique_ptr Cond, Then, Else; + public: IfExprAST(std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) @@ -196,6 +202,7 @@ public: class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; + public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, @@ -209,25 +216,29 @@ public: class VarExprAST : public ExprAST { std::vector>> VarNames; std::unique_ptr Body; + public: - VarExprAST(std::vector>> VarNames, - std::unique_ptr Body) - : VarNames(std::move(VarNames)), Body(std::move(Body)) {} + VarExprAST( + std::vector>> VarNames, + std::unique_ptr Body) + : VarNames(std::move(VarNames)), Body(std::move(Body)) {} Value *Codegen() override; }; /// PrototypeAST - This class represents the "prototype" for a function, -/// which captures its argument names as well as if it is an operator. +/// which captures its name, and its argument names (thus implicitly the number +/// of arguments the function takes), as well as if it is an operator. class PrototypeAST { std::string Name; std::vector Args; bool IsOperator; unsigned Precedence; // Precedence if a binary op. + public: PrototypeAST(const std::string &Name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) - : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), - Precedence(Prec) {} + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec) {} bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } @@ -248,8 +259,10 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: - FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) + FunctionAST(std::unique_ptr Proto, + std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} Function *Codegen(); }; @@ -297,6 +310,26 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); +/// numberexpr ::= number +static std::unique_ptr ParseNumberExpr() { + auto Result = llvm::make_unique(NumVal); + getNextToken(); // consume the number + return std::move(Result); +} + +/// parenexpr ::= '(' expression ')' +static std::unique_ptr ParseParenExpr() { + getNextToken(); // eat (. + auto V = ParseExpression(); + if (!V) + return nullptr; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} + /// identifierexpr /// ::= identifier /// ::= identifier '(' expression* ')' @@ -333,26 +366,6 @@ static std::unique_ptr ParseIdentifierExpr() { return llvm::make_unique(IdName, std::move(Args)); } -/// numberexpr ::= number -static std::unique_ptr ParseNumberExpr() { - auto Result = llvm::make_unique(NumVal); - getNextToken(); // consume the number - return std::move(Result); -} - -/// parenexpr ::= '(' expression ')' -static std::unique_ptr ParseParenExpr() { - getNextToken(); // eat (. - auto V = ParseExpression(); - if (!V) - return nullptr; - - if (CurTok != ')') - return Error("expected ')'"); - getNextToken(); // eat ). - return V; -} - /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr ParseIfExpr() { getNextToken(); // eat the if. @@ -521,7 +534,8 @@ static std::unique_ptr ParseUnary() { /// binoprhs /// ::= ('+' unary)* - static std::unique_ptr ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { +static std::unique_ptr ParseBinOpRHS(int ExprPrec, + std::unique_ptr LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -550,7 +564,8 @@ static std::unique_ptr ParseUnary() { } // Merge LHS/RHS. - LHS = llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); + LHS = + llvm::make_unique(BinOp, std::move(LHS), std::move(RHS)); } } @@ -647,7 +662,8 @@ static std::unique_ptr ParseDefinition() { static std::unique_ptr ParseTopLevelExpr() { if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = llvm::make_unique("", std::vector()); + auto Proto = + llvm::make_unique("", std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -716,7 +732,7 @@ Value *BinaryExprAST::Codegen() { // This assume we're building without RTTI because LLVM builds that way by // default. If you build LLVM with RTTI this can be changed to a // dynamic_cast for automatic error checking. - VariableExprAST *LHSE = static_cast(LHS.get()); + VariableExprAST *LHSE = static_cast(LHS.get()); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. @@ -759,7 +775,7 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } @@ -837,27 +853,26 @@ Value *IfExprAST::Codegen() { return PN; } +// Output for-loop as: +// var = alloca double +// ... +// start = startexpr +// store start -> var +// goto loop +// loop: +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// endcond = endexpr +// +// curvar = load var +// nextvar = curvar + step +// store nextvar -> var +// br endcond, loop, endloop +// outloop: Value *ForExprAST::Codegen() { - // Output this as: - // var = alloca double - // ... - // start = startexpr - // store start -> var - // goto loop - // loop: - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // endcond = endexpr - // - // curvar = load var - // nextvar = curvar + step - // store nextvar -> var - // br endcond, loop, endloop - // outloop: - Function *TheFunction = Builder.GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. @@ -894,7 +909,7 @@ Value *ForExprAST::Codegen() { return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { StepVal = Step->Codegen(); if (!StepVal) @@ -907,7 +922,7 @@ Value *ForExprAST::Codegen() { // Compute the end condition. Value *EndCond = End->Codegen(); if (!EndCond) - return EndCond; + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -1137,9 +1152,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; diff --git a/examples/Kaleidoscope/Chapter8/toy.cpp b/examples/Kaleidoscope/Chapter8/toy.cpp index ed2d9b427ff..b39a5a215af 100644 --- a/examples/Kaleidoscope/Chapter8/toy.cpp +++ b/examples/Kaleidoscope/Chapter8/toy.cpp @@ -17,7 +17,6 @@ #include "llvm/Transforms/Scalar.h" #include #include -#include #include #include #include @@ -109,7 +108,7 @@ struct SourceLocation { int Col; }; static SourceLocation CurLoc; -static SourceLocation LexLoc = { 1, 0 }; +static SourceLocation LexLoc = {1, 0}; static int advance() { int LastChar = getchar(); @@ -196,30 +195,32 @@ static int gettok() { //===----------------------------------------------------------------------===// namespace { -std::ostream &indent(std::ostream &O, int size) { +raw_ostream &indent(raw_ostream &O, int size) { return O << std::string(size, ' '); } /// ExprAST - Base class for all expression nodes. class ExprAST { SourceLocation Loc; + public: - int getLine() const { return Loc.Line; } - int getCol() const { return Loc.Col; } ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {} - virtual std::ostream &dump(std::ostream &out, int ind) { - return out << ':' << getLine() << ':' << getCol() << '\n'; - } virtual ~ExprAST() {} virtual Value *Codegen() = 0; + int getLine() const { return Loc.Line; } + int getCol() const { return Loc.Col; } + virtual raw_ostream &dump(raw_ostream &out, int ind) { + return out << ':' << getLine() << ':' << getCol() << '\n'; + } }; /// NumberExprAST - Expression class for numeric literals like "1.0". class NumberExprAST : public ExprAST { double Val; + public: NumberExprAST(double Val) : Val(Val) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { return ExprAST::dump(out << Val, ind); } Value *Codegen() override; @@ -228,11 +229,12 @@ public: /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; + public: VariableExprAST(SourceLocation Loc, const std::string &Name) : ExprAST(Loc), Name(Name) {} const std::string &getName() const { return Name; } - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { return ExprAST::dump(out << Name, ind); } Value *Codegen() override; @@ -242,10 +244,11 @@ public: class UnaryExprAST : public ExprAST { char Opcode; std::unique_ptr Operand; + public: UnaryExprAST(char Opcode, std::unique_ptr Operand) : Opcode(Opcode), Operand(std::move(Operand)) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "unary" << Opcode, ind); Operand->dump(out, ind + 1); return out; @@ -257,11 +260,12 @@ public: class BinaryExprAST : public ExprAST { char Op; std::unique_ptr LHS, RHS; + public: BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr LHS, std::unique_ptr RHS) : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "binary" << Op, ind); LHS->dump(indent(out, ind) << "LHS:", ind + 1); RHS->dump(indent(out, ind) << "RHS:", ind + 1); @@ -274,11 +278,12 @@ public: class CallExprAST : public ExprAST { std::string Callee; std::vector> Args; + public: CallExprAST(SourceLocation Loc, const std::string &Callee, std::vector> Args) : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "call " << Callee, ind); for (const auto &Arg : Args) Arg->dump(indent(out, ind + 1), ind + 1); @@ -290,11 +295,13 @@ public: /// IfExprAST - Expression class for if/then/else. class IfExprAST : public ExprAST { std::unique_ptr Cond, Then, Else; + public: IfExprAST(SourceLocation Loc, std::unique_ptr Cond, std::unique_ptr Then, std::unique_ptr Else) - : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {} - std::ostream &dump(std::ostream &out, int ind) override { + : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)), + Else(std::move(Else)) {} + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "if", ind); Cond->dump(indent(out, ind) << "Cond:", ind + 1); Then->dump(indent(out, ind) << "Then:", ind + 1); @@ -308,13 +315,14 @@ public: class ForExprAST : public ExprAST { std::string VarName; std::unique_ptr Start, End, Step, Body; + public: ForExprAST(const std::string &VarName, std::unique_ptr Start, std::unique_ptr End, std::unique_ptr Step, std::unique_ptr Body) : VarName(VarName), Start(std::move(Start)), End(std::move(End)), Step(std::move(Step)), Body(std::move(Body)) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "for", ind); Start->dump(indent(out, ind) << "Cond:", ind + 1); End->dump(indent(out, ind) << "End:", ind + 1); @@ -329,11 +337,13 @@ public: class VarExprAST : public ExprAST { std::vector>> VarNames; std::unique_ptr Body; + public: - VarExprAST(std::vector>> VarNames, - std::unique_ptr Body) + VarExprAST( + std::vector>> VarNames, + std::unique_ptr Body) : VarNames(std::move(VarNames)), Body(std::move(Body)) {} - std::ostream &dump(std::ostream &out, int ind) override { + raw_ostream &dump(raw_ostream &out, int ind) override { ExprAST::dump(out << "var", ind); for (const auto &NamedVar : VarNames) NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1); @@ -344,19 +354,21 @@ public: }; /// PrototypeAST - This class represents the "prototype" for a function, -/// which captures its argument names as well as if it is an operator. +/// which captures its name, and its argument names (thus implicitly the number +/// of arguments the function takes), as well as if it is an operator. class PrototypeAST { std::string Name; std::vector Args; bool IsOperator; unsigned Precedence; // Precedence if a binary op. int Line; + public: PrototypeAST(SourceLocation Loc, const std::string &Name, std::vector Args, bool IsOperator = false, unsigned Prec = 0) - : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), - Precedence(Prec), Line(Loc.Line) {} + : Name(Name), Args(std::move(Args)), IsOperator(IsOperator), + Precedence(Prec), Line(Loc.Line) {} bool isUnaryOp() const { return IsOperator && Args.size() == 1; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; } @@ -378,12 +390,13 @@ public: class FunctionAST { std::unique_ptr Proto; std::unique_ptr Body; + public: FunctionAST(std::unique_ptr Proto, std::unique_ptr Body) : Proto(std::move(Proto)), Body(std::move(Body)) {} - std::ostream &dump(std::ostream &out, int ind) { + raw_ostream &dump(raw_ostream &out, int ind) { indent(out, ind) << "FunctionAST\n"; ++ind; indent(out, ind) << "Body:"; @@ -436,44 +449,6 @@ std::unique_ptr ErrorF(const char *Str) { static std::unique_ptr ParseExpression(); -/// identifierexpr -/// ::= identifier -/// ::= identifier '(' expression* ')' - static std::unique_ptr ParseIdentifierExpr() { - std::string IdName = IdentifierStr; - - SourceLocation LitLoc = CurLoc; - - getNextToken(); // eat identifier. - - if (CurTok != '(') // Simple variable ref. - return llvm::make_unique(LitLoc, IdName); - - // Call. - getNextToken(); // eat ( - std::vector> Args; - if (CurTok != ')') { - while (1) { - auto Arg = ParseExpression(); - if (!Arg) - return nullptr; - Args.push_back(std::move(Arg)); - - if (CurTok == ')') - break; - - if (CurTok != ',') - return Error("Expected ')' or ',' in argument list"); - getNextToken(); - } - } - - // Eat the ')'. - getNextToken(); - - return llvm::make_unique(LitLoc, IdName, std::move(Args)); -} - /// numberexpr ::= number static std::unique_ptr ParseNumberExpr() { auto Result = llvm::make_unique(NumVal); @@ -494,6 +469,44 @@ static std::unique_ptr ParseParenExpr() { return V; } +/// identifierexpr +/// ::= identifier +/// ::= identifier '(' expression* ')' +static std::unique_ptr ParseIdentifierExpr() { + std::string IdName = IdentifierStr; + + SourceLocation LitLoc = CurLoc; + + getNextToken(); // eat identifier. + + if (CurTok != '(') // Simple variable ref. + return llvm::make_unique(LitLoc, IdName); + + // Call. + getNextToken(); // eat ( + std::vector> Args; + if (CurTok != ')') { + while (1) { + if (auto Arg = ParseExpression()) + Args.push_back(std::move(Arg)); + else + return nullptr; + + if (CurTok == ')') + break; + + if (CurTok != ',') + return Error("Expected ')' or ',' in argument list"); + getNextToken(); + } + } + + // Eat the ')'. + getNextToken(); + + return llvm::make_unique(LitLoc, IdName, std::move(Args)); +} + /// ifexpr ::= 'if' expression 'then' expression 'else' expression static std::unique_ptr ParseIfExpr() { SourceLocation IfLoc = CurLoc; @@ -664,7 +677,8 @@ static std::unique_ptr ParseUnary() { /// binoprhs /// ::= ('+' unary)* -static std::unique_ptr ParseBinOpRHS(int ExprPrec, std::unique_ptr LHS) { +static std::unique_ptr ParseBinOpRHS(int ExprPrec, + std::unique_ptr LHS) { // If this is a binop, find its precedence. while (1) { int TokPrec = GetTokPrecedence(); @@ -795,8 +809,8 @@ static std::unique_ptr ParseTopLevelExpr() { SourceLocation FnLoc = CurLoc; if (auto E = ParseExpression()) { // Make an anonymous proto. - auto Proto = - llvm::make_unique(FnLoc, "main", std::vector()); + auto Proto = llvm::make_unique(FnLoc, "main", + std::vector()); return llvm::make_unique(std::move(Proto), std::move(E)); } return nullptr; @@ -909,7 +923,7 @@ Value *BinaryExprAST::Codegen() { // This assume we're building without RTTI because LLVM builds that way by // default. If you build LLVM with RTTI this can be changed to a // dynamic_cast for automatic error checking. - VariableExprAST *LHSE = static_cast(LHS.get()); + VariableExprAST *LHSE = static_cast(LHS.get()); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. @@ -952,7 +966,7 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; + Value *Ops[] = {L, R}; return Builder.CreateCall(F, Ops, "binop"); } @@ -1034,27 +1048,26 @@ Value *IfExprAST::Codegen() { return PN; } +// Output for-loop as: +// var = alloca double +// ... +// start = startexpr +// store start -> var +// goto loop +// loop: +// ... +// bodyexpr +// ... +// loopend: +// step = stepexpr +// endcond = endexpr +// +// curvar = load var +// nextvar = curvar + step +// store nextvar -> var +// br endcond, loop, endloop +// outloop: Value *ForExprAST::Codegen() { - // Output this as: - // var = alloca double - // ... - // start = startexpr - // store start -> var - // goto loop - // loop: - // ... - // bodyexpr - // ... - // loopend: - // step = stepexpr - // endcond = endexpr - // - // curvar = load var - // nextvar = curvar + step - // store nextvar -> var - // br endcond, loop, endloop - // outloop: - Function *TheFunction = Builder.GetInsertBlock()->getParent(); // Create an alloca for the variable in the entry block. @@ -1093,7 +1106,7 @@ Value *ForExprAST::Codegen() { return nullptr; // Emit the step value. - Value *StepVal; + Value *StepVal = nullptr; if (Step) { StepVal = Step->Codegen(); if (!StepVal) @@ -1106,7 +1119,7 @@ Value *ForExprAST::Codegen() { // Compute the end condition. Value *EndCond = End->Codegen(); if (!EndCond) - return EndCond; + return nullptr; // Reload, increment, and restore the alloca. This handles the case where // the body of the loop mutates the variable. @@ -1369,9 +1382,9 @@ static void MainLoop() { switch (CurTok) { case tok_eof: return; - case ';': + case ';': // ignore top-level semicolons. getNextToken(); - break; // ignore top-level semicolons. + break; case tok_def: HandleDefinition(); break; @@ -1473,7 +1486,7 @@ int main() { OurFPM.add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). OurFPM.add(createCFGSimplificationPass()); - #endif +#endif OurFPM.doInitialization(); // Set the global so the code gen can use this.