Also reduces changes between tutorial chapters.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245472
91177308-0d34-0410-b5e6-
96231b3b80d8
17 files changed:
tok_eof = -1,
// commands
tok_eof = -1,
// commands
- tok_def = -2, tok_extern = -3,
+ tok_def = -2,
+ tok_extern = -3,
- 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
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
while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
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;
if (LastChar == '#') {
// Comment until end of line.
if (LastChar == '#') {
// Comment until end of line.
- do LastChar = getchar();
+ do
+ LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
};
public:
NumberExprAST(double Val) : Val(Val) {}
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
};
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
};
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST*> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST*> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(std::move(Args)) {}
public:
PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(std::move(Args)) {}
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
/// Error* - These are little helper functions for error handling.
/// 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<ExprAST> Error(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+ }
+ std::unique_ptr<PrototypeAST> 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
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
/// parenexpr ::= '(' expression ')'
static std::unique_ptr<ExprAST> ParseParenExpr() {
/// parenexpr ::= '(' expression ')'
static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
+ getNextToken(); // eat (.
auto V = ParseExpression();
auto V = ParseExpression();
- if (!V) return nullptr;
+ if (!V)
+ return nullptr;
if (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
- getNextToken(); // eat ).
+ getNextToken(); // eat ).
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
std::vector<std::unique_ptr<ExprAST>> 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");
if (CurTok != ',')
return Error("Expected ')' or ',' in argument list");
/// ::= parenexpr
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
/// ::= parenexpr
static std::unique_ptr<ExprAST> 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();
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
- if (!LHS) return nullptr;
+ if (!LHS)
+ return nullptr;
return ParseBinOpRHS(0, std::move(LHS));
}
return ParseBinOpRHS(0, std::move(LHS));
}
// Parse the primary expression after the binary operator.
auto RHS = ParsePrimary();
// 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
As such, this code eats (and remembers) the binary operator and then
parses the primary expression that follows. This builds up the whole
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
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<BinaryExprAST>(BinOp, std::move(LHS),
}
// Merge LHS/RHS.
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
while (1) {
fprintf(stderr, "ready> ");
switch (CurTok) {
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;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen();
public:
NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen();
- 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());
static Module *TheModule;
static IRBuilder<> Builder(getGlobalContext());
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0) return 0;
+ if (!L || !R)
+ return nullptr;
- 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");
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");
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
return ErrorV("Incorrect # arguments passed");
return ErrorV("Unknown function referenced");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
return ErrorV("Incorrect # arguments passed");
- std::vector<Value*> ArgsV;
+ std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
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");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
// Make the function type: double(double,double) etc.
std::vector<Type*> Doubles(Args.size(),
Type::getDoubleTy(getGlobalContext()));
// Make the function type: double(double,double) etc.
std::vector<Type*> 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
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
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
// Add arguments to variable symbol table.
NamedValues[Args[Idx]] = AI;
}
// Add arguments to variable symbol table.
NamedValues[Args[Idx]] = AI;
}
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
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
Code generation for function definitions starts out simply enough: we
just codegen the prototype (Proto) and verify that it is ok. We then
// Error reading body, remove function.
TheFunction->eraseFromParent();
// Error reading body, remove function.
TheFunction->eraseFromParent();
}
The only piece left here is handling of the error case. For simplicity,
}
The only piece left here is handling of the error case. For simplicity,
.. code-block:: c++
/// putchard - putchar that takes a double and returns 0.
.. 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;
}
putchar((char)X);
return 0;
}
.. code-block:: c++
// control
.. 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:
Once we have that, we recognize the new keywords in the lexer. This is
pretty simple stuff:
- 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
return tok_identifier;
AST Extensions for If/Then/Else
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique<ExprAST> Cond, Then, Else;
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique<ExprAST> Cond, Then, Else;
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
// condition.
auto Cond = ParseExpression();
// 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 (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");
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
auto Else = ParseExpression();
getNextToken();
auto Else = ParseExpression();
- if (!Else) return nullptr;
+ if (!Else)
+ return nullptr;
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
static std::unique_ptr<ExprAST> 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();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
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.
// 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
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
// Create blocks for the then and else cases. Insert the 'then' block at the
// end of the function.
// 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");
BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
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.
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
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.
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
// Emit merge block.
TheFunction->getBasicBlockList().push_back(MergeBB);
Builder.SetInsertPoint(MergeBB);
// 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);
PN->addIncoming(ThenV, ThenBB);
PN->addIncoming(ElseV, ElseBB);
tok_for = -9, tok_in = -10
... in gettok ...
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
return tok_identifier;
AST Extensions for the 'for' Loop
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
auto Start = ParseExpression();
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 (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<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
// The step value is optional.
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (!Step) return nullptr;
+ if (!Step)
+ return nullptr;
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
- if (!Body) return nullptr;
+ if (!Body)
+ return nullptr;
return llvm::make_unique<ForExprAST>(IdName, std::move(Start),
std::move(End), std::move(Step),
return llvm::make_unique<ForExprAST>(IdName, std::move(Start),
std::move(End), std::move(Step),
// block.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
BasicBlock *PreheaderBB = Builder.GetInsertBlock();
// 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);
// Insert an explicit fall through from the current block to the LoopBB.
Builder.CreateBr(LoopBB);
Builder.SetInsertPoint(LoopBB);
// Start the PHI node with an entry for Start.
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
Variable->addIncoming(StartVal, PreheaderBB);
Now that the "preheader" for the loop is set up, we switch to emitting
// 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.
// 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
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
.. code-block:: c++
// Emit the step value.
.. code-block:: c++
// Emit the step value.
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
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));
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
// Compute the end condition.
Value *EndCond = End->Codegen();
// 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.
// 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
Finally, we evaluate the exit value of the loop, to determine whether
the loop should exit. This mirrors the condition evaluation for the
// Create the "after loop" block and insert it.
BasicBlock *LoopEndBB = Builder.GetInsertBlock();
// 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);
// Insert the conditional branch into the end of LoopEndBB.
Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
enum Token {
...
// operators
enum Token {
...
// operators
- tok_binary = -11, tok_unary = -12
+ tok_binary = -11,
+ tok_unary = -12
};
...
static int gettok() {
...
};
...
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
return tok_identifier;
This just adds lexer support for the unary and binary keywords, like we
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &name, std::vector<std::string> Args,
bool IsOperator = false, unsigned Prec = 0)
public:
PrototypeAST(const std::string &name, std::vector<std::string> Args,
bool IsOperator = false, unsigned Prec = 0)
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames),
- Kind != 0, BinaryPrecedence);
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames), Kind != 0,
+ BinaryPrecedence);
}
This is all fairly straightforward parsing code, and we have already
}
This is all fairly straightforward parsing code, and we have already
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0) return 0;
+ if (!L || !R)
+ return nullptr;
- 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");
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");
}
// If it wasn't a builtin binary operator, it must be a user defined one. Emit
// a call to it.
}
// 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 };
assert(F && "binary operator not found!");
Value *Ops[2] = { L, R };
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
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())
// If this is an operator, install it.
if (Proto->isBinaryOp())
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
...
// Parse the unary expression after the binary operator.
auto RHS = ParseUnary();
...
// Parse the unary expression after the binary operator.
auto RHS = ParseUnary();
- if (!RHS) return nullptr;
+ if (!RHS)
+ return nullptr;
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
- if (!LHS) return nullptr;
+ if (!LHS)
+ return nullptr;
return ParseBinOpRHS(0, std::move(LHS));
}
return ParseBinOpRHS(0, std::move(LHS));
}
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
- if (OperandV == 0) return 0;
+ if (!OperandV)
+ return nullptr;
Function *F = TheModule->getFunction(std::string("unary")+Opcode);
Function *F = TheModule->getFunction(std::string("unary")+Opcode);
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
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());
// Load the value.
return Builder.CreateLoad(V, Name.c_str());
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
// 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);
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Compute the end condition.
Value *EndCond = End->Codegen();
// 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.
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
// Codegen the RHS.
Value *Val = RHS->Codegen();
// 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()];
// 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;
Builder.CreateStore(Val, Variable);
return Val;
...
static int gettok() {
...
...
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;
...
return tok_identifier;
...
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
public:
VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
std::unique_ptr<ExprAST> body)
public:
VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
std::unique_ptr<ExprAST> body)
/// ::= varexpr
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
/// ::= varexpr
static std::unique_ptr<ExprAST> 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();
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
getNextToken(); // eat 'in'.
auto Body = ParseExpression();
- if (!Body) return nullptr;
+ if (!Body)
+ return nullptr;
return llvm::make_unique<VarExprAST>(std::move(VarNames),
std::move(Body));
return llvm::make_unique<VarExprAST>(std::move(VarNames),
std::move(Body));
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
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));
}
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
// 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:
Finally, before returning, we restore the previous variable bindings:
SourceLocation Loc;
public:
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; }
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';
}
return out << ':' << getLine() << ':' << getCol() << '\n';
}
DILocalVariable D = DBuilder->createParameterVariable(
Scope, Args[Idx], Idx + 1, Unit, Line, KSDbgInfo.getDoubleTy(), true);
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
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
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
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
beginning of the scope on the declare.
One interesting thing to note at this point is that various debuggers have
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-private-field")
+
add_kaleidoscope_chapter(Kaleidoscope-Ch2
toy.cpp
)
add_kaleidoscope_chapter(Kaleidoscope-Ch2
toy.cpp
)
TOOLNAME = Kaleidoscope-Ch2
EXAMPLE_TOOL = 1
TOOLNAME = Kaleidoscope-Ch2
EXAMPLE_TOOL = 1
+LLVM_CXXFLAGS := -Wno-unused-private-field
+
include $(LEVEL)/Makefile.common
include $(LEVEL)/Makefile.common
tok_eof = -1,
// commands
tok_eof = -1,
// commands
- tok_def = -2, tok_extern = -3,
+ tok_def = -2,
+ tok_extern = -3,
- 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() {
/// gettok - Return the next token from standard input.
static int gettok() {
while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
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;
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
std::string NumStr;
do {
NumStr += LastChar;
std::string NumStr;
do {
NumStr += LastChar;
if (LastChar == '#') {
// Comment until end of line.
if (LastChar == '#') {
// Comment until end of line.
- do LastChar = getchar();
+ do
+ LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
return gettok();
}
if (LastChar != EOF)
return gettok();
}
// Check for end of file. Don't eat the EOF.
if (LastChar == EOF)
return tok_eof;
// Check for end of file. Don't eat the EOF.
if (LastChar == EOF)
return tok_eof;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
- NumberExprAST(double Val) {}
+ NumberExprAST(double Val) : Val(Val) {}
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
};
/// 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 {
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
+ char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
+
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
- std::unique_ptr<ExprAST> RHS) {}
+ std::unique_ptr<ExprAST> 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<std::unique_ptr<ExprAST>> Args;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
- : Callee(Callee), Args(std::move(Args)) {}
+ : Callee(Callee), Args(std::move(Args)) {}
};
/// PrototypeAST - This class represents the "prototype" for a function,
};
/// PrototypeAST - This class represents the "prototype" for a function,
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
- : Name(Name), Args(std::move(Args)) {}
-
+ : Name(Name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
+
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
- std::unique_ptr<ExprAST> Body) {}
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
};
} // end anonymous namespace
};
} // end anonymous namespace
/// token the parser is looking at. getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
/// 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.
/// BinopPrecedence - This holds the precedence for each binary operator that is
/// defined.
static int GetTokPrecedence() {
if (!isascii(CurTok))
return -1;
static int GetTokPrecedence() {
if (!isascii(CurTok))
return -1;
// Make sure it's a declared binop.
int TokPrec = BinopPrecedence[CurTok];
// Make sure it's a declared binop.
int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
+ if (TokPrec <= 0)
+ return -1;
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
+
+ getNextToken(); // eat identifier.
+
if (CurTok != '(') // Simple variable ref.
return llvm::make_unique<VariableExprAST>(IdName);
if (CurTok != '(') // Simple variable ref.
return llvm::make_unique<VariableExprAST>(IdName);
- getNextToken(); // eat (
+ getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
- if (CurTok == ')') break;
+ if (CurTok == ')')
+ break;
if (CurTok != ',')
return Error("Expected ')' or ',' in argument list");
if (CurTok != ',')
return Error("Expected ')' or ',' in argument list");
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return Error("expected ')'");
- getNextToken(); // eat ).
- return V;
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
/// ::= parenexpr
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
/// ::= parenexpr
static std::unique_ptr<ExprAST> 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();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// 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;
// 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;
// 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();
// 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) {
// 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;
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
- if (!LHS) return nullptr;
-
+ if (!LHS)
+ return nullptr;
+
return ParseBinOpRHS(0, std::move(LHS));
}
return ParseBinOpRHS(0, std::move(LHS));
}
std::string FnName = IdentifierStr;
getNextToken();
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
return ErrorP("Expected '(' in prototype");
if (CurTok != '(')
return ErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
return ErrorP("Expected ')' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
return ErrorP("Expected ')' in prototype");
- getNextToken(); // eat ')'.
-
- return llvm::make_unique<PrototypeAST>(std::move(FnName),
- std::move(ArgNames));
+ getNextToken(); // eat ')'.
+
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static std::unique_ptr<FunctionAST> ParseDefinition() {
}
/// definition ::= 'def' prototype expression
static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
+ getNextToken(); // eat def.
auto Proto = ParsePrototype();
auto Proto = ParsePrototype();
- if (!Proto) return nullptr;
+ if (!Proto)
+ return nullptr;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("",
- std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
/// external ::= 'extern' prototype
static std::unique_ptr<PrototypeAST> ParseExtern() {
/// external ::= 'extern' prototype
static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
+ getNextToken(); // eat extern.
return ParsePrototype();
}
return ParsePrototype();
}
while (1) {
fprintf(stderr, "ready> ");
switch (CurTok) {
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;
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
- BinopPrecedence['*'] = 40; // highest.
+ BinopPrecedence['*'] = 40; // highest.
// Prime the first token.
fprintf(stderr, "ready> ");
// Prime the first token.
fprintf(stderr, "ready> ");
tok_eof = -1,
// commands
tok_eof = -1,
// commands
- tok_def = -2, tok_extern = -3,
+ tok_def = -2,
+ tok_extern = -3,
- 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() {
/// gettok - Return the next token from standard input.
static int gettok() {
while (isalnum((LastChar = getchar())))
IdentifierStr += LastChar;
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;
- if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
+ if (isdigit(LastChar) || LastChar == '.') { // Number: [0-9.]+
std::string NumStr;
do {
NumStr += LastChar;
std::string NumStr;
do {
NumStr += LastChar;
if (LastChar == '#') {
// Comment until end of line.
if (LastChar == '#') {
// Comment until end of line.
- do LastChar = getchar();
+ do
+ LastChar = getchar();
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
while (LastChar != EOF && LastChar != '\n' && LastChar != '\r');
if (LastChar != EOF)
return gettok();
}
if (LastChar != EOF)
return gettok();
}
// Check for end of file. Don't eat the EOF.
if (LastChar == EOF)
return tok_eof;
// Check for end of file. Don't eat the EOF.
if (LastChar == EOF)
return tok_eof;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
- : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
- : Callee(Callee), Args(std::move(Args)) {}
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
- : Name(Name), Args(std::move(Args)) {}
-
+ : Name(Name), Args(std::move(Args)) {}
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
-
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
/// token the parser is looking at. getNextToken reads another token from the
/// lexer and updates CurTok with its results.
static int CurTok;
/// 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.
/// BinopPrecedence - This holds the precedence for each binary operator that is
/// defined.
static int GetTokPrecedence() {
if (!isascii(CurTok))
return -1;
static int GetTokPrecedence() {
if (!isascii(CurTok))
return -1;
// Make sure it's a declared binop.
int TokPrec = BinopPrecedence[CurTok];
// Make sure it's a declared binop.
int TokPrec = BinopPrecedence[CurTok];
- if (TokPrec <= 0) return -1;
+ if (TokPrec <= 0)
+ return -1;
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
-
- getNextToken(); // eat identifier.
-
+
+ getNextToken(); // eat identifier.
+
if (CurTok != '(') // Simple variable ref.
return llvm::make_unique<VariableExprAST>(IdName);
if (CurTok != '(') // Simple variable ref.
return llvm::make_unique<VariableExprAST>(IdName);
- getNextToken(); // eat (
+ getNextToken(); // eat (
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
- if (CurTok == ')') break;
+ if (CurTok == ')')
+ break;
if (CurTok != ',')
return Error("Expected ')' or ',' in argument list");
if (CurTok != ',')
return Error("Expected ')' or ',' in argument list");
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
-
- return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
-}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return Error("expected ')'");
- getNextToken(); // eat ).
- return V;
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
/// ::= parenexpr
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
/// ::= parenexpr
static std::unique_ptr<ExprAST> 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();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// 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;
// 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;
// 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();
// 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) {
// 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;
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
///
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
- if (!LHS) return nullptr;
-
+ if (!LHS)
+ return nullptr;
+
return ParseBinOpRHS(0, std::move(LHS));
}
return ParseBinOpRHS(0, std::move(LHS));
}
std::string FnName = IdentifierStr;
getNextToken();
std::string FnName = IdentifierStr;
getNextToken();
if (CurTok != '(')
return ErrorP("Expected '(' in prototype");
if (CurTok != '(')
return ErrorP("Expected '(' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
return ErrorP("Expected ')' in prototype");
std::vector<std::string> ArgNames;
while (getNextToken() == tok_identifier)
ArgNames.push_back(IdentifierStr);
if (CurTok != ')')
return ErrorP("Expected ')' in prototype");
- getNextToken(); // eat ')'.
-
- return llvm::make_unique<PrototypeAST>(std::move(FnName),
- std::move(ArgNames));
+ getNextToken(); // eat ')'.
+
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static std::unique_ptr<FunctionAST> ParseDefinition() {
}
/// definition ::= 'def' prototype expression
static std::unique_ptr<FunctionAST> ParseDefinition() {
- getNextToken(); // eat def.
+ getNextToken(); // eat def.
auto Proto = ParsePrototype();
auto Proto = ParsePrototype();
- if (!Proto) return nullptr;
+ if (!Proto)
+ return nullptr;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("",
- std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
/// external ::= 'extern' prototype
static std::unique_ptr<PrototypeAST> ParseExtern() {
/// external ::= 'extern' prototype
static std::unique_ptr<PrototypeAST> ParseExtern() {
- getNextToken(); // eat extern.
+ getNextToken(); // eat extern.
return ParsePrototype();
}
return ParsePrototype();
}
// Code Generation
//===----------------------------------------------------------------------===//
// Code Generation
//===----------------------------------------------------------------------===//
+Value *ErrorV(const char *Str) {
+ Error(Str);
+ return nullptr;
+}
+
static Module *TheModule;
static IRBuilder<> Builder(getGlobalContext());
static Module *TheModule;
static IRBuilder<> Builder(getGlobalContext());
-static std::map<std::string, Value*> NamedValues;
-
-Value *ErrorV(const char *Str) { Error(Str); return nullptr; }
+static std::map<std::string, Value *> NamedValues;
Value *NumberExprAST::Codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
Value *NumberExprAST::Codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (!L || !R) return nullptr;
-
+ if (!L || !R)
+ return nullptr;
+
- 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");
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");
Function *CalleeF = TheModule->getFunction(Callee);
if (!CalleeF)
return ErrorV("Unknown function referenced");
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");
// If argument mismatch error.
if (CalleeF->arg_size() != Args.size())
return ErrorV("Incorrect # arguments passed");
- std::vector<Value*> ArgsV;
+ std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
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.
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
Function *PrototypeAST::Codegen() {
// Make the function type: double(double,double) etc.
- std::vector<Type*> 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<Type *> 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 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 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;
}
}
// 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]);
// 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;
}
// Add arguments to variable symbol table.
NamedValues[Args[Idx]] = AI;
}
return F;
}
Function *FunctionAST::Codegen() {
NamedValues.clear();
return F;
}
Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (!TheFunction)
return nullptr;
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);
// 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);
if (Value *RetVal = Body->Codegen()) {
// Finish off the function.
Builder.CreateRet(RetVal);
// Error reading body, remove function.
TheFunction->eraseFromParent();
return nullptr;
// Error reading body, remove function.
TheFunction->eraseFromParent();
return nullptr;
while (1) {
fprintf(stderr, "ready> ");
switch (CurTok) {
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.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Main driver code.
//===----------------------------------------------------------------------===//
BinopPrecedence['<'] = 10;
BinopPrecedence['+'] = 20;
BinopPrecedence['-'] = 20;
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.
// Prime the first token.
fprintf(stderr, "ready> ");
getNextToken();
// Make the module, which holds all the code.
- std::unique_ptr<Module> Owner = llvm::make_unique<Module>("my cool jit", Context);
+ std::unique_ptr<Module> Owner =
+ llvm::make_unique<Module>("my cool jit", Context);
TheModule = Owner.get();
// Run the main "interpreter loop" now.
TheModule = Owner.get();
// Run the main "interpreter loop" now.
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
- PrototypeAST(const std::string &name, std::vector<std::string> Args)
- : Name(name), Args(std::move(Args)) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args)
+ : Name(Name), Args(std::move(Args)) {}
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return Error("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
/// primary
/// ::= identifierexpr
/// ::= numberexpr
/// primary
/// ::= identifierexpr
/// ::= numberexpr
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("",
- std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
switch (CurTok) {
case tok_eof:
return;
switch (CurTok) {
case tok_eof:
return;
+ case ';': // ignore top-level semicolons.
- break; // ignore top-level semicolons.
case tok_def:
HandleDefinition();
break;
case tok_def:
HandleDefinition();
break;
+/// 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.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Main driver code.
//===----------------------------------------------------------------------===//
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
- PrototypeAST(const std::string &name, std::vector<std::string> Args)
- : Name(name), Args(std::move(Args)) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args)
+ : Name(Name), Args(std::move(Args)) {}
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
- : Proto(std::move(Proto)), Body(std::move(Body)) {}
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> 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<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
- std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("",
- std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
+// 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() {
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)
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (!StartVal)
return nullptr;
// Emit the step value.
return nullptr;
// Emit the step value.
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
switch (CurTok) {
case tok_eof:
return;
switch (CurTok) {
case tok_eof:
return;
+ case ';': // ignore top-level semicolons.
- break; // ignore top-level semicolons.
case tok_def:
HandleDefinition();
break;
case tok_def:
HandleDefinition();
break;
+/// 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.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Main driver code.
//===----------------------------------------------------------------------===//
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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;
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
std::unique_ptr<ExprAST> Body)
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
std::unique_ptr<ExprAST> 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;
};
Value *Codegen() override;
};
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args,
bool IsOperator = false, unsigned Prec = 0)
public:
PrototypeAST(const std::string &Name, std::vector<std::string> 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; }
bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
- FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> 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<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// binoprhs
/// ::= ('+' unary)*
/// binoprhs
/// ::= ('+' unary)*
- static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
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() {
}
Value *UnaryExprAST::Codegen() {
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
- Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
return Builder.CreateCall(F, Ops, "binop");
}
+// 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() {
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)
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (!StartVal)
return nullptr;
// Emit the step value.
return nullptr;
// Emit the step value.
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
EndCond = Builder.CreateFCmpONE(
switch (CurTok) {
case tok_eof:
return;
switch (CurTok) {
case tok_eof:
return;
+ case ';': // ignore top-level semicolons.
- break; // ignore top-level semicolons.
case tok_def:
HandleDefinition();
break;
case tok_def:
HandleDefinition();
break;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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; }
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
const std::string &getName() const { return Name; }
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
- VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
- std::unique_ptr<ExprAST> Body)
- : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
Value *Codegen() override;
};
/// PrototypeAST - This class represents the "prototype" for a function,
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<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args,
bool IsOperator = false, unsigned Prec = 0)
public:
PrototypeAST(const std::string &Name, std::vector<std::string> 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; }
bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
- FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> 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<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// binoprhs
/// ::= ('+' unary)*
/// binoprhs
/// ::= ('+' unary)*
- static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
// 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.
// 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<VariableExprAST*>(LHS.get());
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
- Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
return Builder.CreateCall(F, Ops, "binop");
}
+// 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() {
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.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create an alloca for the variable in the entry block.
return nullptr;
// Emit the step value.
return nullptr;
// Emit the step value.
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
switch (CurTok) {
case tok_eof:
return;
switch (CurTok) {
case tok_eof:
return;
+ case ';': // ignore top-level semicolons.
- break; // ignore top-level semicolons.
case tok_def:
HandleDefinition();
break;
case tok_def:
HandleDefinition();
break;
#include "llvm/Transforms/Scalar.h"
#include <cctype>
#include <cstdio>
#include "llvm/Transforms/Scalar.h"
#include <cctype>
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include <map>
#include <string>
#include <vector>
int Col;
};
static SourceLocation CurLoc;
int Col;
};
static SourceLocation CurLoc;
-static SourceLocation LexLoc = { 1, 0 };
+static SourceLocation LexLoc = {1, 0};
static int advance() {
int LastChar = getchar();
static int advance() {
int LastChar = getchar();
//===----------------------------------------------------------------------===//
namespace {
//===----------------------------------------------------------------------===//
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;
return O << std::string(size, ' ');
}
/// ExprAST - Base class for all expression nodes.
class ExprAST {
SourceLocation Loc;
+ ExprAST(SourceLocation Loc = CurLoc) : Loc(Loc) {}
+ virtual ~ExprAST() {}
+ virtual Value *Codegen() = 0;
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
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';
}
return out << ':' << getLine() << ':' << getCol() << '\n';
}
- virtual ~ExprAST() {}
- virtual Value *Codegen() = 0;
};
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
};
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double Val) : Val(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;
return ExprAST::dump(out << Val, ind);
}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// 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; }
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;
return ExprAST::dump(out << Name, ind);
}
Value *Codegen() override;
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> 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;
ExprAST::dump(out << "unary" << Opcode, ind);
Operand->dump(out, ind + 1);
return out;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
public:
BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> 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);
ExprAST::dump(out << "binary" << Op, ind);
LHS->dump(indent(out, ind) << "LHS:", ind + 1);
RHS->dump(indent(out, ind) << "RHS:", ind + 1);
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(SourceLocation Loc, const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {}
public:
CallExprAST(SourceLocation Loc, const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> 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);
ExprAST::dump(out << "call " << Callee, ind);
for (const auto &Arg : Args)
Arg->dump(indent(out, ind + 1), ind + 1);
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else)
public:
IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> 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);
ExprAST::dump(out << "if", ind);
Cond->dump(indent(out, ind) << "Cond:", ind + 1);
Then->dump(indent(out, ind) << "Then:", ind + 1);
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
std::unique_ptr<ExprAST> Body)
: VarName(VarName), Start(std::move(Start)), End(std::move(End)),
Step(std::move(Step)), Body(std::move(Body)) {}
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
std::unique_ptr<ExprAST> 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);
ExprAST::dump(out << "for", ind);
Start->dump(indent(out, ind) << "Cond:", ind + 1);
End->dump(indent(out, ind) << "End:", ind + 1);
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
- VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
- std::unique_ptr<ExprAST> Body)
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
: VarNames(std::move(VarNames)), Body(std::move(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);
ExprAST::dump(out << "var", ind);
for (const auto &NamedVar : VarNames)
NamedVar.second->dump(indent(out, ind) << NamedVar.first << ':', ind + 1);
};
/// PrototypeAST - This class represents the "prototype" for a function,
};
/// 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<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
int Line;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
int Line;
public:
PrototypeAST(SourceLocation Loc, const std::string &Name,
std::vector<std::string> Args, bool IsOperator = false,
unsigned Prec = 0)
public:
PrototypeAST(SourceLocation Loc, const std::string &Name,
std::vector<std::string> 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; }
bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
public:
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> 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:";
indent(out, ind) << "FunctionAST\n";
++ind;
indent(out, ind) << "Body:";
static std::unique_ptr<ExprAST> ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
- static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
SourceLocation LitLoc = CurLoc;
std::string IdName = IdentifierStr;
SourceLocation LitLoc = CurLoc;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
- auto Arg = ParseExpression();
- if (!Arg)
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
- Args.push_back(std::move(Arg));
if (CurTok == ')')
break;
if (CurTok == ')')
break;
return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
}
return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> 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<ExprAST> ParseIfExpr() {
SourceLocation IfLoc = CurLoc;
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
SourceLocation IfLoc = CurLoc;
/// binoprhs
/// ::= ('+' unary)*
/// binoprhs
/// ::= ('+' unary)*
-static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
SourceLocation FnLoc = CurLoc;
if (auto E = ParseExpression()) {
// Make an anonymous proto.
SourceLocation FnLoc = CurLoc;
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto =
- llvm::make_unique<PrototypeAST>(FnLoc, "main", std::vector<std::string>());
+ auto Proto = llvm::make_unique<PrototypeAST>(FnLoc, "main",
+ std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
// 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.
// 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<VariableExprAST*>(LHS.get());
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
- Value *Ops[] = { L, R };
return Builder.CreateCall(F, Ops, "binop");
}
return Builder.CreateCall(F, Ops, "binop");
}
+// 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() {
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.
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create an alloca for the variable in the entry block.
return nullptr;
// Emit the step value.
return nullptr;
// Emit the step value.
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
switch (CurTok) {
case tok_eof:
return;
switch (CurTok) {
case tok_eof:
return;
+ case ';': // ignore top-level semicolons.
- break; // ignore top-level semicolons.
case tok_def:
HandleDefinition();
break;
case tok_def:
HandleDefinition();
break;
OurFPM.add(createGVNPass());
// Simplify the control flow graph (deleting unreachable blocks, etc).
OurFPM.add(createCFGSimplificationPass());
OurFPM.add(createGVNPass());
// Simplify the control flow graph (deleting unreachable blocks, etc).
OurFPM.add(createCFGSimplificationPass());
OurFPM.doInitialization();
// Set the global so the code gen can use this.
OurFPM.doInitialization();
// Set the global so the code gen can use this.