[Kaleidoscope] Start C++11'ifying the kaleidoscope tutorials.

llvm-svn: 245322
This commit is contained in:
Lang Hames 2015-08-18 18:11:06 +00:00
parent b5226576ea
commit 09bf4c102f
15 changed files with 1037 additions and 982 deletions

View File

@ -25,7 +25,7 @@ It is useful to point out ahead of time that this tutorial is really
about teaching compiler techniques and LLVM specifically, *not* about
teaching modern and sane software engineering principles. In practice,
this means that we'll take a number of shortcuts to simplify the
exposition. For example, the code leaks memory, uses global variables
exposition. For example, the code uses global variables
all over the place, doesn't use nice design patterns like
`visitors <http://en.wikipedia.org/wiki/Visitor_pattern>`_, etc... but
it is very simple. If you dig in and use the code as a basis for future

View File

@ -45,7 +45,7 @@ We'll start with expressions first:
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
};
The code above shows the definition of the base ExprAST class and one
@ -66,16 +66,17 @@ language:
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
};
/// CallExprAST - Expression class for function calls.
@ -83,8 +84,9 @@ language:
std::string Callee;
std::vector<ExprAST*> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
};
This is all (intentionally) rather straight-forward: variables capture
@ -110,17 +112,18 @@ way to talk about functions themselves:
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args)
: Name(name), Args(args) {}
PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body)
: Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
};
In Kaleidoscope, functions are typed with just a count of their
@ -142,9 +145,10 @@ be generated with calls like this:
.. code-block:: c++
ExprAST *X = new VariableExprAST("x");
ExprAST *Y = new VariableExprAST("y");
ExprAST *Result = new BinaryExprAST('+', X, Y);
auto LHS = llvm::make_unique<VariableExprAST>("x");
auto RHS = llvm::make_unique<VariableExprAST>("y");
auto Result = std::make_unique<BinaryExprAST>('+', std::move(LHS),
std::move(RHS));
In order to do this, we'll start by defining some basic helper routines:
@ -190,10 +194,10 @@ which parses that production. For numeric literals, we have:
.. code-block:: c++
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
This routine is very simple: it expects to be called when the current
@ -211,10 +215,10 @@ the parenthesis operator is defined like this:
.. code-block:: c++
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
if (!V) return 0;
auto V = ParseExpression();
if (!V) return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -250,22 +254,22 @@ function calls:
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST*> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg) return 0;
Args.push_back(Arg);
auto Arg = ParseExpression();
if (!Arg) return nullptr;
Args.push_back(std::move(Arg));
if (CurTok == ')') break;
@ -278,7 +282,7 @@ function calls:
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
This routine follows the same style as the other routines. (It expects
@ -303,7 +307,7 @@ primary expression, we need to determine what sort of expression it is:
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@ -390,11 +394,11 @@ a sequence of [binop,primaryexpr] pairs:
/// expression
/// ::= primary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParsePrimary();
if (!LHS) return 0;
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS) return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
``ParseBinOpRHS`` is the function that parses the sequence of pairs for
@ -416,7 +420,8 @@ starts with:
/// binoprhs
/// ::= ('+' primary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -440,8 +445,8 @@ expression:
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary();
if (!RHS) return 0;
auto RHS = ParsePrimary();
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
@ -474,7 +479,8 @@ then continue parsing:
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
} // loop around to the top of the while loop.
}
@ -498,11 +504,12 @@ above two blocks duplicated for context):
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, RHS);
RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (RHS == 0) return 0;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
} // loop around to the top of the while loop.
}
@ -541,7 +548,7 @@ expressions):
/// prototype
/// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@ -561,7 +568,7 @@ expressions):
// success.
getNextToken(); // eat ')'.
return new PrototypeAST(FnName, ArgNames);
return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
Given this, a function definition is very simple, just a prototype plus
@ -570,14 +577,14 @@ an expression to implement the body:
.. code-block:: c++
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0) return 0;
auto Proto = ParsePrototype();
if (!Proto) return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
In addition, we support 'extern' to declare functions like 'sin' and
@ -587,7 +594,7 @@ In addition, we support 'extern' to declare functions like 'sin' and
.. code-block:: c++
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -599,13 +606,13 @@ nullary (zero argument) functions for them:
.. code-block:: c++
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
Now that we have all the pieces, let's build a little driver that will

View File

@ -42,7 +42,7 @@ class:
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen();
};
...

View File

@ -260,12 +260,12 @@ parses a top-level expression to look like this:
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
LF->dump(); // Dump the function for exposition purposes.
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
FnIR->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.

View File

@ -90,10 +90,11 @@ To represent the new expression we add a new AST node for it:
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else;
std::unique<ExprAST> Cond, Then, Else;
public:
IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
: Cond(cond), Then(then), Else(_else) {}
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
: Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
virtual Value *Codegen();
};
@ -109,36 +110,37 @@ First we define a new parsing function:
.. code-block:: c++
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
ExprAST *Cond = ParseExpression();
if (!Cond) return 0;
auto Cond = ParseExpression();
if (!Cond) return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
ExprAST *Then = ParseExpression();
if (Then == 0) return 0;
auto Then = ParseExpression();
if (Then) return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
ExprAST *Else = ParseExpression();
if (!Else) return 0;
auto Else = ParseExpression();
if (!Else) return nullptr;
return new IfExprAST(Cond, Then, Else);
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
Next we hook it up as a primary expression:
.. code-block:: c++
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@ -269,7 +271,7 @@ for ``IfExprAST``:
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
if (CondV == 0) return 0;
if (!CondV) return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV,
@ -464,11 +466,13 @@ variable name and the constituent expressions in the node.
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
ExprAST *Start, *End, *Step, *Body;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
ExprAST *step, ExprAST *body)
: VarName(varname), Start(start), End(end), Step(step), Body(body) {}
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)) {}
virtual Value *Codegen();
};
@ -483,7 +487,7 @@ value to null in the AST node:
.. code-block:: c++
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@ -497,31 +501,33 @@ value to null in the AST node:
getNextToken(); // eat '='.
ExprAST *Start = ParseExpression();
if (Start == 0) return 0;
auto Start = ParseExpression();
if (!Start) return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
ExprAST *End = ParseExpression();
if (End == 0) return 0;
auto End = ParseExpression();
if (!End) return nullptr;
// The step value is optional.
ExprAST *Step = 0;
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (Step == 0) return 0;
if (!Step) return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0) return 0;
auto Body = ParseExpression();
if (!Body) return nullptr;
return new ForExprAST(IdName, Start, End, Step, Body);
return llvm::make_unique<ForExprAST>(IdName, std::move(Start),
std::move(End), std::move(Step),
std::move(Body));
}
LLVM IR for the 'for' Loop

View File

@ -129,15 +129,16 @@ this:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool isOperator;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args,
bool isoperator = false, unsigned prec = 0)
: Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
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) {}
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; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
@ -161,7 +162,7 @@ user-defined operator, we need to parse it:
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
@ -210,7 +211,8 @@ user-defined operator, we need to parse it:
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
return new PrototypeAST(FnName, 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
@ -305,10 +307,10 @@ that, we need an AST node:
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
ExprAST *Operand;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char opcode, ExprAST *operand)
: Opcode(opcode), Operand(operand) {}
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
virtual Value *Codegen();
};
@ -322,7 +324,7 @@ simple: we'll add a new function to do it:
/// unary
/// ::= primary
/// ::= '!' unary
static ExprAST *ParseUnary() {
static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
@ -330,9 +332,9 @@ simple: we'll add a new function to do it:
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
if (ExprAST *Operand = ParseUnary())
return new UnaryExprAST(Opc, Operand);
return 0;
if (auto Operand = ParseUnary())
return llvm::unique_ptr<UnaryExprAST>(Opc, std::move(Operand));
return nullptr;
}
The grammar we add is pretty straightforward here. If we see a unary
@ -350,21 +352,22 @@ call ParseUnary instead:
/// binoprhs
/// ::= ('+' unary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
std::unique_ptr<ExprAST> LHS) {
...
// Parse the unary expression after the binary operator.
ExprAST *RHS = ParseUnary();
if (!RHS) return 0;
auto RHS = ParseUnary();
if (!RHS) return nullptr;
...
}
/// expression
/// ::= unary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParseUnary();
if (!LHS) return 0;
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
if (!LHS) return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
With these two simple changes, we are now able to parse unary operators
@ -378,7 +381,7 @@ operator code above with:
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.

View File

@ -573,7 +573,7 @@ implement codegen for the assignment operator. This looks like:
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS);
VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
@ -663,12 +663,12 @@ var/in, it looks like this:
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, ExprAST*> > VarNames;
ExprAST *Body;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
public:
VarExprAST(const std::vector<std::pair<std::string, ExprAST*> > &varnames,
ExprAST *body)
: VarNames(varnames), Body(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)) {}
virtual Value *Codegen();
};
@ -690,7 +690,7 @@ do is add it as a primary expression:
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@ -708,10 +708,10 @@ Next we define ParseVarExpr:
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() {
static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the var.
std::vector<std::pair<std::string, ExprAST*> > VarNames;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
// At least one variable name is required.
if (CurTok != tok_identifier)
@ -727,15 +727,15 @@ into the local ``VarNames`` vector.
getNextToken(); // eat identifier.
// Read the optional initializer.
ExprAST *Init = 0;
std::unique_ptr<ExprAST> Init;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (Init == 0) return 0;
if (!Init) return nullptr;
}
VarNames.push_back(std::make_pair(Name, Init));
VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',') break;
@ -755,10 +755,11 @@ AST node:
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0) return 0;
auto Body = ParseExpression();
if (!Body) return nullptr;
return new VarExprAST(VarNames, Body);
return llvm::make_unique<VarExprAST>(std::move(VarNames),
std::move(Body));
}
Now that we can parse and represent the code, we need to support
@ -774,7 +775,7 @@ emission of LLVM IR for it. This code starts out with:
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
ExprAST *Init = VarNames[i].second;
ExprAST *Init = VarNames[i].second.get();
Basically it loops over all the variables, installing them one at a
time. For each variable we put into the symbol table, we remember the

View File

@ -75,8 +75,8 @@ statement be our "main":
.. code-block:: udiff
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
+ PrototypeAST *Proto = new PrototypeAST("main", std::vector<std::string>());
- auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto = llvm::make_unique<PrototypeAST>("main", std::vector<std::string>());
just with the simple change of giving it a name.
@ -108,12 +108,12 @@ code is that the llvm IR goes to standard error:
@@ -1108,17 +1108,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
- if (auto *FnIR = FnAST->Codegen()) {
- // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
- void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
@ -318,7 +318,8 @@ that we pass down through when we create a new expression:
.. code-block:: c++
LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
std::move(RHS));
giving us locations for each of our expressions and variables.

View File

@ -1,6 +1,6 @@
#include "llvm/ADT/STLExtras.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <string>
#include <vector>
@ -85,29 +85,31 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
public:
NumberExprAST(double val) {}
NumberExprAST(double Val) {}
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS) {}
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST*> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
};
/// PrototypeAST - This class represents the "prototype" for a function,
@ -117,15 +119,16 @@ class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args)
: Name(name), Args(args) {}
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
: Name(Name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body) {}
};
} // end anonymous namespace
@ -157,30 +160,37 @@ static int GetTokPrecedence() {
}
/// 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; }
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;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST*> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg) return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')') break;
@ -193,21 +203,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
if (!V) return 0;
auto V = ParseExpression();
if (!V)
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -219,7 +230,7 @@ static ExprAST *ParseParenExpr() {
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@ -230,7 +241,8 @@ static ExprAST *ParsePrimary() {
/// binoprhs
/// ::= ('+' primary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -245,35 +257,36 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary();
if (!RHS) return 0;
auto RHS = ParsePrimary();
if (!RHS) return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, RHS);
if (RHS == 0) return 0;
RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (!RHS) return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParsePrimary();
if (!LHS) return 0;
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS) return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@ -292,32 +305,34 @@ static PrototypeAST *ParsePrototype() {
// success.
getNextToken(); // eat ')'.
return new PrototypeAST(FnName, ArgNames);
return llvm::make_unique<PrototypeAST>(std::move(FnName),
std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0) return 0;
auto Proto = ParsePrototype();
if (!Proto) return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}

View File

@ -1,3 +1,4 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
@ -92,7 +93,7 @@ public:
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
@ -100,27 +101,29 @@ public:
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST*> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
@ -131,19 +134,20 @@ class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args)
: Name(name), Args(args) {}
PrototypeAST(const std::string &Name, std::vector<std::string> Args)
: Name(Name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body)
: Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
@ -177,31 +181,41 @@ static int GetTokPrecedence() {
}
/// 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;
}
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST*> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg) return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')') break;
@ -214,21 +228,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
if (!V) return 0;
auto V = ParseExpression();
if (!V)
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -240,7 +255,7 @@ static ExprAST *ParseParenExpr() {
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
@ -251,7 +266,8 @@ static ExprAST *ParsePrimary() {
/// binoprhs
/// ::= ('+' primary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -266,35 +282,36 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary();
if (!RHS) return 0;
auto RHS = ParsePrimary();
if (!RHS) return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, RHS);
if (RHS == 0) return 0;
RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (!RHS) return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParsePrimary();
if (!LHS) return 0;
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS) return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@ -313,32 +330,34 @@ static PrototypeAST *ParsePrototype() {
// success.
getNextToken(); // eat ')'.
return new PrototypeAST(FnName, ArgNames);
return llvm::make_unique<PrototypeAST>(std::move(FnName),
std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0) return 0;
auto Proto = ParsePrototype();
if (!Proto) return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -351,7 +370,7 @@ static Module *TheModule;
static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value*> NamedValues;
Value *ErrorV(const char *Str) { Error(Str); return 0; }
Value *ErrorV(const char *Str) { Error(Str); return nullptr; }
Value *NumberExprAST::Codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
@ -366,7 +385,7 @@ Value *VariableExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0) return 0;
if (!L || !R) return nullptr;
switch (Op) {
case '+': return Builder.CreateFAdd(L, R, "addtmp");
@ -384,7 +403,7 @@ Value *BinaryExprAST::Codegen() {
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -394,7 +413,7 @@ Value *CallExprAST::Codegen() {
std::vector<Value*> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0) return 0;
if (!ArgsV.back()) return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -407,7 +426,8 @@ Function *PrototypeAST::Codegen() {
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);
// If F conflicted, there was already something named 'Name'. If it has a
// body, don't allow redefinition or reextern.
@ -419,13 +439,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -446,8 +466,8 @@ Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (TheFunction == 0)
return 0;
if (!TheFunction)
return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
@ -465,7 +485,7 @@ Function *FunctionAST::Codegen() {
// Error reading body, remove function.
TheFunction->eraseFromParent();
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -473,10 +493,10 @@ Function *FunctionAST::Codegen() {
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -485,10 +505,10 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (Function *F = P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
F->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -498,10 +518,10 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read top-level expression:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -553,7 +573,8 @@ int main() {
getNextToken();
// Make the module, which holds all the code.
TheModule = new 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.
MainLoop();

View File

@ -1,3 +1,4 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
@ -105,40 +106,38 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
@ -148,22 +147,20 @@ public:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args)
: Name(name), Args(args) {}
PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
@ -195,41 +192,41 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) {
std::unique_ptr<ExprAST> Error(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return 0;
return nullptr;
}
PrototypeAST *ErrorP(const char *Str) {
std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
FunctionAST *ErrorF(const char *Str) {
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg)
return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')')
break;
@ -243,22 +240,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
auto V = ParseExpression();
if (!V)
return 0;
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -270,7 +267,7 @@ static ExprAST *ParseParenExpr() {
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
@ -285,7 +282,8 @@ static ExprAST *ParsePrimary() {
/// binoprhs
/// ::= ('+' primary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -300,38 +298,39 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary();
auto RHS = ParsePrimary();
if (!RHS)
return 0;
return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS);
if (RHS == 0)
return 0;
RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParsePrimary();
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS)
return 0;
return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@ -350,33 +349,34 @@ static PrototypeAST *ParsePrototype() {
// success.
getNextToken(); // eat ')'.
return new PrototypeAST(FnName, ArgNames);
return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0)
return 0;
auto Proto = ParsePrototype();
if (!Proto)
return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -505,7 +505,7 @@ Function *MCJITHelper::getFunction(const std::string FnName) {
Function *PF = OpenModule->getFunction(FnName);
if (PF && !PF->empty()) {
ErrorF("redefinition of function across modules");
return 0;
return nullptr;
}
// If we don't have a prototype yet, create one.
@ -626,7 +626,7 @@ static std::map<std::string, Value *> NamedValues;
Value *ErrorV(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
Value *NumberExprAST::Codegen() {
@ -642,8 +642,8 @@ Value *VariableExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0)
return 0;
if (!L || !R)
return nullptr;
switch (Op) {
case '+':
@ -665,7 +665,7 @@ Value *BinaryExprAST::Codegen() {
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = JITHelper->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -675,8 +675,8 @@ Value *CallExprAST::Codegen() {
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0)
return 0;
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -704,13 +704,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -731,8 +731,8 @@ Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (TheFunction == 0)
return 0;
if (!TheFunction)
return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
@ -750,7 +750,7 @@ Function *FunctionAST::Codegen() {
// Error reading body, remove function.
TheFunction->eraseFromParent();
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -758,10 +758,10 @@ Function *FunctionAST::Codegen() {
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -770,10 +770,10 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (Function *F = P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
F->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -783,10 +783,10 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
// JIT the function, returning a function pointer.
void *FPtr = JITHelper->getPointerToFunction(LF);
void *FPtr = JITHelper->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.

View File

@ -123,62 +123,61 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else;
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
: Cond(cond), Then(then), Else(_else) {}
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
: Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
ExprAST *Start, *End, *Step, *Body;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
ExprAST *step, ExprAST *body)
: VarName(varname), Start(start), End(end), Step(step), Body(body) {}
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)) {}
Value *Codegen() override;
};
@ -188,22 +187,20 @@ public:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args)
: Name(name), Args(args) {}
PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto,
std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
@ -235,41 +232,41 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) {
std::unique_ptr<ExprAST> Error(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return 0;
return nullptr;
}
PrototypeAST *ErrorP(const char *Str) {
std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
FunctionAST *ErrorF(const char *Str) {
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg)
return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')')
break;
@ -283,22 +280,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
auto V = ParseExpression();
if (!V)
return 0;
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -307,36 +304,37 @@ static ExprAST *ParseParenExpr() {
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
ExprAST *Cond = ParseExpression();
auto Cond = ParseExpression();
if (!Cond)
return 0;
return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
ExprAST *Then = ParseExpression();
if (Then == 0)
return 0;
auto Then = ParseExpression();
if (!Then)
return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
ExprAST *Else = ParseExpression();
auto Else = ParseExpression();
if (!Else)
return 0;
return nullptr;
return new IfExprAST(Cond, Then, Else);
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@ -349,35 +347,36 @@ static ExprAST *ParseForExpr() {
return Error("expected '=' after for");
getNextToken(); // eat '='.
ExprAST *Start = ParseExpression();
if (Start == 0)
return 0;
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
ExprAST *End = ParseExpression();
if (End == 0)
return 0;
auto End = ParseExpression();
if (!End)
return nullptr;
// The step value is optional.
ExprAST *Step = 0;
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (Step == 0)
return 0;
if (!Step)
return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new ForExprAST(IdName, Start, End, Step, Body);
return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
std::move(Step), std::move(Body));
}
/// primary
@ -386,7 +385,7 @@ static ExprAST *ParseForExpr() {
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
@ -405,7 +404,8 @@ static ExprAST *ParsePrimary() {
/// binoprhs
/// ::= ('+' primary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -420,38 +420,39 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary();
auto RHS = ParsePrimary();
if (!RHS)
return 0;
return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS);
if (RHS == 0)
return 0;
RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParsePrimary();
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParsePrimary();
if (!LHS)
return 0;
return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
@ -470,33 +471,34 @@ static PrototypeAST *ParsePrototype() {
// success.
getNextToken(); // eat ')'.
return new PrototypeAST(FnName, ArgNames);
return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0)
return 0;
auto Proto = ParsePrototype();
if (!Proto)
return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("",
std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -512,7 +514,7 @@ static legacy::FunctionPassManager *TheFPM;
Value *ErrorV(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
Value *NumberExprAST::Codegen() {
@ -528,8 +530,8 @@ Value *VariableExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0)
return 0;
if (!L || !R)
return nullptr;
switch (Op) {
case '+':
@ -551,7 +553,7 @@ Value *BinaryExprAST::Codegen() {
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -561,8 +563,8 @@ Value *CallExprAST::Codegen() {
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0)
return 0;
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -570,8 +572,8 @@ Value *CallExprAST::Codegen() {
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
if (CondV == 0)
return 0;
if (!CondV)
return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
@ -592,8 +594,8 @@ Value *IfExprAST::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.
@ -604,8 +606,8 @@ Value *IfExprAST::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.
@ -641,8 +643,8 @@ Value *ForExprAST::Codegen() {
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (StartVal == 0)
return 0;
if (!StartVal)
return nullptr;
// Make the new basic block for the loop header, inserting after current
// block.
@ -670,15 +672,15 @@ Value *ForExprAST::Codegen() {
// 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;
// Emit the step value.
Value *StepVal;
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));
@ -688,7 +690,7 @@ Value *ForExprAST::Codegen() {
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0)
if (!EndCond)
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
@ -739,13 +741,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -766,8 +768,8 @@ Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (TheFunction == 0)
return 0;
if (!TheFunction)
return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
@ -788,7 +790,7 @@ Function *FunctionAST::Codegen() {
// Error reading body, remove function.
TheFunction->eraseFromParent();
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -798,10 +800,10 @@ Function *FunctionAST::Codegen() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -810,10 +812,10 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (Function *F = P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
F->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -823,11 +825,11 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.

View File

@ -131,73 +131,72 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
ExprAST *Operand;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char opcode, ExprAST *operand)
: Opcode(opcode), Operand(operand) {}
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else;
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
: Cond(cond), Then(then), Else(_else) {}
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
: Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
ExprAST *Start, *End, *Step, *Body;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
ExprAST *step, ExprAST *body)
: VarName(varname), Start(start), End(end), Step(step), Body(body) {}
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)) {}
Value *Codegen() override;
};
@ -207,15 +206,16 @@ public:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool isOperator;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args,
bool isoperator = false, unsigned prec = 0)
: Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
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) {}
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; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
@ -229,12 +229,11 @@ public:
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
@ -266,41 +265,41 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) {
std::unique_ptr<ExprAST> Error(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return 0;
return nullptr;
}
PrototypeAST *ErrorP(const char *Str) {
std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
FunctionAST *ErrorF(const char *Str) {
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg)
return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')')
break;
@ -314,22 +313,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
auto V = ParseExpression();
if (!V)
return 0;
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -338,36 +337,37 @@ static ExprAST *ParseParenExpr() {
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
ExprAST *Cond = ParseExpression();
auto Cond = ParseExpression();
if (!Cond)
return 0;
return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
ExprAST *Then = ParseExpression();
if (Then == 0)
return 0;
auto Then = ParseExpression();
if (!Then)
return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
ExprAST *Else = ParseExpression();
auto Else = ParseExpression();
if (!Else)
return 0;
return nullptr;
return new IfExprAST(Cond, Then, Else);
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@ -380,35 +380,36 @@ static ExprAST *ParseForExpr() {
return Error("expected '=' after for");
getNextToken(); // eat '='.
ExprAST *Start = ParseExpression();
if (Start == 0)
return 0;
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
ExprAST *End = ParseExpression();
if (End == 0)
return 0;
auto End = ParseExpression();
if (!End)
return nullptr;
// The step value is optional.
ExprAST *Step = 0;
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (Step == 0)
return 0;
if (!Step)
return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new ForExprAST(IdName, Start, End, Step, Body);
return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
std::move(Step), std::move(Body));
}
/// primary
@ -417,7 +418,7 @@ static ExprAST *ParseForExpr() {
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
@ -437,7 +438,7 @@ static ExprAST *ParsePrimary() {
/// unary
/// ::= primary
/// ::= '!' unary
static ExprAST *ParseUnary() {
static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
@ -445,14 +446,14 @@ static ExprAST *ParseUnary() {
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
if (ExprAST *Operand = ParseUnary())
return new UnaryExprAST(Opc, Operand);
return 0;
if (auto Operand = ParseUnary())
return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -467,40 +468,40 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
ExprAST *RHS = ParseUnary();
auto RHS = ParseUnary();
if (!RHS)
return 0;
return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS);
if (RHS == 0)
return 0;
RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParseUnary();
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
if (!LHS)
return 0;
return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
@ -558,33 +559,34 @@ static PrototypeAST *ParsePrototype() {
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence);
return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0)
return 0;
auto Proto = ParsePrototype();
if (!Proto)
return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -600,7 +602,7 @@ static legacy::FunctionPassManager *TheFPM;
Value *ErrorV(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
Value *NumberExprAST::Codegen() {
@ -615,11 +617,11 @@ Value *VariableExprAST::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);
if (F == 0)
if (!F)
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
@ -628,8 +630,8 @@ Value *UnaryExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0)
return 0;
if (!L || !R)
return nullptr;
switch (Op) {
case '+':
@ -659,7 +661,7 @@ Value *BinaryExprAST::Codegen() {
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -669,8 +671,8 @@ Value *CallExprAST::Codegen() {
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0)
return 0;
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -678,8 +680,8 @@ Value *CallExprAST::Codegen() {
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
if (CondV == 0)
return 0;
if (!CondV)
return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
@ -700,8 +702,8 @@ Value *IfExprAST::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.
@ -712,8 +714,8 @@ Value *IfExprAST::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.
@ -749,8 +751,8 @@ Value *ForExprAST::Codegen() {
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
if (StartVal == 0)
return 0;
if (!StartVal)
return nullptr;
// Make the new basic block for the loop header, inserting after current
// block.
@ -778,15 +780,15 @@ Value *ForExprAST::Codegen() {
// 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;
// Emit the step value.
Value *StepVal;
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));
@ -796,7 +798,7 @@ Value *ForExprAST::Codegen() {
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0)
if (!EndCond)
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
@ -847,13 +849,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -874,8 +876,8 @@ Function *FunctionAST::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())
@ -903,7 +905,7 @@ Function *FunctionAST::Codegen() {
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -913,10 +915,10 @@ Function *FunctionAST::Codegen() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -925,10 +927,10 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (Function *F = P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
F->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -938,11 +940,11 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.

View File

@ -136,18 +136,16 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(const std::string &name) : Name(name) {}
VariableExprAST(const std::string &Name) : Name(Name) {}
const std::string &getName() const { return Name; }
Value *Codegen() override;
};
@ -155,68 +153,66 @@ public:
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
ExprAST *Operand;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char opcode, ExprAST *operand)
: Opcode(opcode), Operand(operand) {}
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
: Op(op), LHS(lhs), RHS(rhs) {}
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
: Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
: Callee(callee), Args(args) {}
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else;
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
: Cond(cond), Then(then), Else(_else) {}
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
: Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
ExprAST *Start, *End, *Step, *Body;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
ExprAST *step, ExprAST *body)
: VarName(varname), Start(start), End(end), Step(step), Body(body) {}
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)) {}
Value *Codegen() override;
};
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, ExprAST *> > VarNames;
ExprAST *Body;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
public:
VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames,
ExprAST *body)
: VarNames(varnames), Body(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;
};
@ -225,15 +221,16 @@ public:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool isOperator;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args,
bool isoperator = false, unsigned prec = 0)
: Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
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) {}
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; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
@ -249,12 +246,11 @@ public:
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
@ -286,41 +282,41 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) {
std::unique_ptr<ExprAST> Error(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return 0;
return nullptr;
}
PrototypeAST *ErrorP(const char *Str) {
std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
FunctionAST *ErrorF(const char *Str) {
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName);
return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
if (!Arg)
return 0;
Args.push_back(Arg);
if (auto Arg = ParseExpression())
Args.push_back(std::move(Arg));
else
return nullptr;
if (CurTok == ')')
break;
@ -334,22 +330,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(IdName, Args);
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
auto V = ParseExpression();
if (!V)
return 0;
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -358,36 +354,37 @@ static ExprAST *ParseParenExpr() {
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
ExprAST *Cond = ParseExpression();
auto Cond = ParseExpression();
if (!Cond)
return 0;
return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
ExprAST *Then = ParseExpression();
if (Then == 0)
return 0;
auto Then = ParseExpression();
if (!Then)
return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
ExprAST *Else = ParseExpression();
auto Else = ParseExpression();
if (!Else)
return 0;
return nullptr;
return new IfExprAST(Cond, Then, Else);
return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
std::move(Else));
}
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@ -400,43 +397,44 @@ static ExprAST *ParseForExpr() {
return Error("expected '=' after for");
getNextToken(); // eat '='.
ExprAST *Start = ParseExpression();
if (Start == 0)
return 0;
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
ExprAST *End = ParseExpression();
if (End == 0)
return 0;
auto End = ParseExpression();
if (!End)
return nullptr;
// The step value is optional.
ExprAST *Step = 0;
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (Step == 0)
return 0;
if (!Step)
return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new ForExprAST(IdName, Start, End, Step, Body);
return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
std::move(Step), std::move(Body));
}
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() {
static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the var.
std::vector<std::pair<std::string, ExprAST *> > VarNames;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
// At least one variable name is required.
if (CurTok != tok_identifier)
@ -447,16 +445,16 @@ static ExprAST *ParseVarExpr() {
getNextToken(); // eat identifier.
// Read the optional initializer.
ExprAST *Init = 0;
std::unique_ptr<ExprAST> Init = nullptr;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (Init == 0)
return 0;
if (!Init)
return nullptr;
}
VarNames.push_back(std::make_pair(Name, Init));
VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',')
@ -472,11 +470,11 @@ static ExprAST *ParseVarExpr() {
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new VarExprAST(VarNames, Body);
return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
}
/// primary
@ -486,7 +484,7 @@ static ExprAST *ParseVarExpr() {
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
@ -508,7 +506,7 @@ static ExprAST *ParsePrimary() {
/// unary
/// ::= primary
/// ::= '!' unary
static ExprAST *ParseUnary() {
static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
@ -516,14 +514,14 @@ static ExprAST *ParseUnary() {
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
if (ExprAST *Operand = ParseUnary())
return new UnaryExprAST(Opc, Operand);
return 0;
if (auto Operand = ParseUnary())
return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -538,40 +536,40 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
ExprAST *RHS = ParseUnary();
auto RHS = ParseUnary();
if (!RHS)
return 0;
return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS);
if (RHS == 0)
return 0;
RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParseUnary();
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
if (!LHS)
return 0;
return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
@ -629,33 +627,34 @@ static PrototypeAST *ParsePrototype() {
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
return new PrototypeAST(FnName, ArgNames, Kind != 0, BinaryPrecedence);
return llvm::make_unique<PrototypeAST>(FnName, ArgNames, Kind != 0,
BinaryPrecedence);
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0)
return 0;
auto Proto = ParsePrototype();
if (!Proto)
return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -671,7 +670,7 @@ static legacy::FunctionPassManager *TheFPM;
Value *ErrorV(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
@ -691,7 +690,7 @@ Value *NumberExprAST::Codegen() {
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (V == 0)
if (!V)
return ErrorV("Unknown variable name");
// Load the value.
@ -700,11 +699,11 @@ Value *VariableExprAST::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);
if (F == 0)
if (!F)
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
@ -717,17 +716,17 @@ Value *BinaryExprAST::Codegen() {
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
if (Val == 0)
return 0;
if (!Val)
return nullptr;
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
if (Variable == 0)
if (!Variable)
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
@ -736,8 +735,8 @@ Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0)
return 0;
if (!L || !R)
return nullptr;
switch (Op) {
case '+':
@ -767,7 +766,7 @@ Value *BinaryExprAST::Codegen() {
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -777,8 +776,8 @@ Value *CallExprAST::Codegen() {
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0)
return 0;
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -786,8 +785,8 @@ Value *CallExprAST::Codegen() {
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
if (CondV == 0)
return 0;
if (!CondV)
return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
@ -808,8 +807,8 @@ Value *IfExprAST::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.
@ -820,8 +819,8 @@ Value *IfExprAST::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.
@ -866,8 +865,8 @@ Value *ForExprAST::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);
@ -891,15 +890,15 @@ Value *ForExprAST::Codegen() {
// 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;
// Emit the step value.
Value *StepVal;
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));
@ -907,7 +906,7 @@ Value *ForExprAST::Codegen() {
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0)
if (!EndCond)
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
@ -948,7 +947,7 @@ Value *VarExprAST::Codegen() {
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
ExprAST *Init = VarNames[i].second;
ExprAST *Init = VarNames[i].second.get();
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
@ -958,8 +957,8 @@ Value *VarExprAST::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));
}
@ -977,8 +976,8 @@ Value *VarExprAST::Codegen() {
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
if (BodyVal == 0)
return 0;
if (!BodyVal)
return nullptr;
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
@ -1008,13 +1007,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -1047,8 +1046,8 @@ Function *FunctionAST::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())
@ -1079,7 +1078,7 @@ Function *FunctionAST::Codegen() {
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -1089,10 +1088,10 @@ Function *FunctionAST::Codegen() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
LF->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -1101,10 +1100,10 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (Function *F = P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
F->dump();
FnIR->dump();
}
} else {
// Skip token for error recovery.
@ -1114,11 +1113,11 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.

View File

@ -203,7 +203,6 @@ std::ostream &indent(std::ostream &O, int size) {
/// ExprAST - Base class for all expression nodes.
class ExprAST {
SourceLocation Loc;
public:
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
@ -218,9 +217,8 @@ public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
public:
NumberExprAST(double val) : Val(val) {}
NumberExprAST(double Val) : Val(Val) {}
std::ostream &dump(std::ostream &out, int ind) override {
return ExprAST::dump(out << Val, ind);
}
@ -230,10 +228,9 @@ public:
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
VariableExprAST(SourceLocation Loc, const std::string &name)
: ExprAST(Loc), Name(name) {}
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 {
return ExprAST::dump(out << Name, ind);
@ -244,11 +241,10 @@ public:
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
ExprAST *Operand;
std::unique_ptr<ExprAST> Operand;
public:
UnaryExprAST(char opcode, ExprAST *operand)
: Opcode(opcode), Operand(operand) {}
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "unary" << Opcode, ind);
Operand->dump(out, ind + 1);
@ -260,11 +256,11 @@ public:
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
ExprAST *LHS, *RHS;
std::unique_ptr<ExprAST> LHS, RHS;
public:
BinaryExprAST(SourceLocation Loc, char op, ExprAST *lhs, ExprAST *rhs)
: ExprAST(Loc), Op(op), LHS(lhs), RHS(rhs) {}
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 {
ExprAST::dump(out << "binary" << Op, ind);
LHS->dump(indent(out, ind) << "LHS:", ind + 1);
@ -277,15 +273,14 @@ public:
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
public:
CallExprAST(SourceLocation Loc, const std::string &callee,
std::vector<ExprAST *> &args)
: ExprAST(Loc), Callee(callee), Args(args) {}
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 {
ExprAST::dump(out << "call " << Callee, ind);
for (ExprAST *Arg : Args)
for (const auto &Arg : Args)
Arg->dump(indent(out, ind + 1), ind + 1);
return out;
}
@ -294,11 +289,11 @@ public:
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else;
std::unique_ptr<ExprAST> Cond, Then, Else;
public:
IfExprAST(SourceLocation Loc, ExprAST *cond, ExprAST *then, ExprAST *_else)
: ExprAST(Loc), Cond(cond), Then(then), Else(_else) {}
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::dump(out << "if", ind);
Cond->dump(indent(out, ind) << "Cond:", ind + 1);
@ -312,12 +307,13 @@ public:
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
ExprAST *Start, *End, *Step, *Body;
std::unique_ptr<ExprAST> Start, End, Step, Body;
public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
ExprAST *step, ExprAST *body)
: VarName(varname), Start(start), End(end), Step(step), Body(body) {}
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 {
ExprAST::dump(out << "for", ind);
Start->dump(indent(out, ind) << "Cond:", ind + 1);
@ -331,14 +327,12 @@ public:
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, ExprAST *> > VarNames;
ExprAST *Body;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
public:
VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames,
ExprAST *body)
: VarNames(varnames), Body(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)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "var", ind);
for (const auto &NamedVar : VarNames)
@ -354,19 +348,18 @@ public:
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool isOperator;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
int Line;
public:
PrototypeAST(SourceLocation Loc, const std::string &name,
const std::vector<std::string> &args, bool isoperator = false,
unsigned prec = 0)
: Name(name), Args(args), isOperator(isoperator), Precedence(prec),
Line(Loc.Line) {}
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) {}
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; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
@ -383,11 +376,12 @@ public:
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
PrototypeAST *Proto;
ExprAST *Body;
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
public:
FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
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) {
indent(out, ind) << "FunctionAST\n";
@ -427,25 +421,25 @@ static int GetTokPrecedence() {
}
/// Error* - These are little helper functions for error handling.
ExprAST *Error(const char *Str) {
std::unique_ptr<ExprAST> Error(const char *Str) {
fprintf(stderr, "Error: %s\n", Str);
return 0;
return nullptr;
}
PrototypeAST *ErrorP(const char *Str) {
std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
FunctionAST *ErrorF(const char *Str) {
std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
static ExprAST *ParseExpression();
static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() {
static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
SourceLocation LitLoc = CurLoc;
@ -453,17 +447,17 @@ static ExprAST *ParseIdentifierExpr() {
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(LitLoc, IdName);
return llvm::make_unique<VariableExprAST>(LitLoc, IdName);
// Call.
getNextToken(); // eat (
std::vector<ExprAST *> Args;
std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
ExprAST *Arg = ParseExpression();
auto Arg = ParseExpression();
if (!Arg)
return 0;
Args.push_back(Arg);
return nullptr;
Args.push_back(std::move(Arg));
if (CurTok == ')')
break;
@ -477,22 +471,22 @@ static ExprAST *ParseIdentifierExpr() {
// Eat the ')'.
getNextToken();
return new CallExprAST(LitLoc, IdName, Args);
return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
}
/// numberexpr ::= number
static ExprAST *ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal);
static std::unique_ptr<ExprAST> ParseNumberExpr() {
auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
return Result;
return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() {
static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
ExprAST *V = ParseExpression();
auto V = ParseExpression();
if (!V)
return 0;
return nullptr;
if (CurTok != ')')
return Error("expected ')'");
@ -501,38 +495,39 @@ static ExprAST *ParseParenExpr() {
}
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() {
static std::unique_ptr<ExprAST> ParseIfExpr() {
SourceLocation IfLoc = CurLoc;
getNextToken(); // eat the if.
// condition.
ExprAST *Cond = ParseExpression();
auto Cond = ParseExpression();
if (!Cond)
return 0;
return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
ExprAST *Then = ParseExpression();
if (Then == 0)
return 0;
auto Then = ParseExpression();
if (!Then)
return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
ExprAST *Else = ParseExpression();
auto Else = ParseExpression();
if (!Else)
return 0;
return nullptr;
return new IfExprAST(IfLoc, Cond, Then, Else);
return llvm::make_unique<IfExprAST>(IfLoc, std::move(Cond), std::move(Then),
std::move(Else));
}
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() {
static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
@ -545,43 +540,44 @@ static ExprAST *ParseForExpr() {
return Error("expected '=' after for");
getNextToken(); // eat '='.
ExprAST *Start = ParseExpression();
if (Start == 0)
return 0;
auto Start = ParseExpression();
if (!Start)
return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
ExprAST *End = ParseExpression();
if (End == 0)
return 0;
auto End = ParseExpression();
if (!End)
return nullptr;
// The step value is optional.
ExprAST *Step = 0;
std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (Step == 0)
return 0;
if (!Step)
return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new ForExprAST(IdName, Start, End, Step, Body);
return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
std::move(Step), std::move(Body));
}
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() {
static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the var.
std::vector<std::pair<std::string, ExprAST *> > VarNames;
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
// At least one variable name is required.
if (CurTok != tok_identifier)
@ -592,16 +588,16 @@ static ExprAST *ParseVarExpr() {
getNextToken(); // eat identifier.
// Read the optional initializer.
ExprAST *Init = 0;
std::unique_ptr<ExprAST> Init = nullptr;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (Init == 0)
return 0;
if (!Init)
return nullptr;
}
VarNames.push_back(std::make_pair(Name, Init));
VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',')
@ -617,11 +613,11 @@ static ExprAST *ParseVarExpr() {
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression();
if (Body == 0)
return 0;
auto Body = ParseExpression();
if (!Body)
return nullptr;
return new VarExprAST(VarNames, Body);
return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
}
/// primary
@ -631,7 +627,7 @@ static ExprAST *ParseVarExpr() {
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
static ExprAST *ParsePrimary() {
static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
@ -653,7 +649,7 @@ static ExprAST *ParsePrimary() {
/// unary
/// ::= primary
/// ::= '!' unary
static ExprAST *ParseUnary() {
static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
@ -661,14 +657,14 @@ static ExprAST *ParseUnary() {
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
if (ExprAST *Operand = ParseUnary())
return new UnaryExprAST(Opc, Operand);
return 0;
if (auto Operand = ParseUnary())
return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
static ExprAST *ParseBinOpRHS(int ExprPrec, 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();
@ -684,40 +680,41 @@ static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
ExprAST *RHS = ParseUnary();
auto RHS = ParseUnary();
if (!RHS)
return 0;
return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec + 1, RHS);
if (RHS == 0)
return 0;
RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
if (!RHS)
return nullptr;
}
// Merge LHS/RHS.
LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS);
LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
static ExprAST *ParseExpression() {
ExprAST *LHS = ParseUnary();
static std::unique_ptr<ExprAST> ParseExpression() {
auto LHS = ParseUnary();
if (!LHS)
return 0;
return nullptr;
return ParseBinOpRHS(0, LHS);
return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() {
static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
SourceLocation FnLoc = CurLoc;
@ -777,35 +774,36 @@ static PrototypeAST *ParsePrototype() {
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
return new PrototypeAST(FnLoc, FnName, ArgNames, Kind != 0, BinaryPrecedence);
return llvm::make_unique<PrototypeAST>(FnLoc, FnName, ArgNames, Kind != 0,
BinaryPrecedence);
}
/// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() {
static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype();
if (Proto == 0)
return 0;
auto Proto = ParsePrototype();
if (!Proto)
return nullptr;
if (ExprAST *E = ParseExpression())
return new FunctionAST(Proto, E);
return 0;
if (auto E = ParseExpression())
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return nullptr;
}
/// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() {
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
SourceLocation FnLoc = CurLoc;
if (ExprAST *E = ParseExpression()) {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
PrototypeAST *Proto =
new PrototypeAST(FnLoc, "main", std::vector<std::string>());
return new FunctionAST(Proto, E);
auto Proto =
llvm::make_unique<PrototypeAST>(FnLoc, "main", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return 0;
return nullptr;
}
/// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() {
static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
@ -860,7 +858,7 @@ static legacy::FunctionPassManager *TheFPM;
Value *ErrorV(const char *Str) {
Error(Str);
return 0;
return nullptr;
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
@ -881,7 +879,7 @@ Value *NumberExprAST::Codegen() {
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
if (V == 0)
if (!V)
return ErrorV("Unknown variable name");
KSDbgInfo.emitLocation(this);
@ -891,11 +889,11 @@ Value *VariableExprAST::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);
if (F == 0)
if (!F)
return ErrorV("Unknown unary operator");
KSDbgInfo.emitLocation(this);
@ -911,17 +909,17 @@ Value *BinaryExprAST::Codegen() {
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
if (Val == 0)
return 0;
if (!Val)
return nullptr;
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
if (Variable == 0)
if (!Variable)
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
@ -930,8 +928,8 @@ Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
if (L == 0 || R == 0)
return 0;
if (!L || !R)
return nullptr;
switch (Op) {
case '+':
@ -963,7 +961,7 @@ Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
if (CalleeF == 0)
if (!CalleeF)
return ErrorV("Unknown function referenced");
// If argument mismatch error.
@ -973,8 +971,8 @@ Value *CallExprAST::Codegen() {
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
if (ArgsV.back() == 0)
return 0;
if (!ArgsV.back())
return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
@ -984,8 +982,8 @@ Value *IfExprAST::Codegen() {
KSDbgInfo.emitLocation(this);
Value *CondV = Cond->Codegen();
if (CondV == 0)
return 0;
if (!CondV)
return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
@ -1006,8 +1004,8 @@ Value *IfExprAST::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.
@ -1018,8 +1016,8 @@ Value *IfExprAST::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.
@ -1066,8 +1064,8 @@ Value *ForExprAST::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);
@ -1091,15 +1089,15 @@ Value *ForExprAST::Codegen() {
// 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;
// Emit the step value.
Value *StepVal;
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));
@ -1107,7 +1105,7 @@ Value *ForExprAST::Codegen() {
// Compute the end condition.
Value *EndCond = End->Codegen();
if (EndCond == 0)
if (!EndCond)
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
@ -1148,7 +1146,7 @@ Value *VarExprAST::Codegen() {
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
ExprAST *Init = VarNames[i].second;
ExprAST *Init = VarNames[i].second.get();
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
@ -1158,8 +1156,8 @@ Value *VarExprAST::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));
}
@ -1179,8 +1177,8 @@ Value *VarExprAST::Codegen() {
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
if (BodyVal == 0)
return 0;
if (!BodyVal)
return nullptr;
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
@ -1210,13 +1208,13 @@ Function *PrototypeAST::Codegen() {
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
return 0;
return nullptr;
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
return 0;
return nullptr;
}
}
@ -1272,11 +1270,11 @@ Function *FunctionAST::Codegen() {
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
if (TheFunction == 0)
return 0;
if (!TheFunction)
return nullptr;
// Push the current scope.
KSDbgInfo.LexicalBlocks.push_back(KSDbgInfo.FnScopeMap[Proto]);
KSDbgInfo.LexicalBlocks.push_back(KSDbgInfo.FnScopeMap[Proto.get()]);
// Unset the location for the prologue emission (leading instructions with no
// location in a function are considered part of the prologue and the debugger
@ -1294,7 +1292,7 @@ Function *FunctionAST::Codegen() {
// Add all arguments to the symbol table and create their allocas.
Proto->CreateArgumentAllocas(TheFunction);
KSDbgInfo.emitLocation(Body);
KSDbgInfo.emitLocation(Body.get());
if (Value *RetVal = Body->Codegen()) {
// Finish off the function.
@ -1322,7 +1320,7 @@ Function *FunctionAST::Codegen() {
// unconditionally.
KSDbgInfo.LexicalBlocks.pop_back();
return 0;
return nullptr;
}
//===----------------------------------------------------------------------===//
@ -1332,8 +1330,8 @@ Function *FunctionAST::Codegen() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
if (FunctionAST *F = ParseDefinition()) {
if (!F->Codegen()) {
if (auto FnAST = ParseDefinition()) {
if (!FnAST->Codegen()) {
fprintf(stderr, "Error reading function definition:");
}
} else {
@ -1343,8 +1341,8 @@ static void HandleDefinition() {
}
static void HandleExtern() {
if (PrototypeAST *P = ParseExtern()) {
if (!P->Codegen()) {
if (auto ProtoAST = ParseExtern()) {
if (!ProtoAST->Codegen()) {
fprintf(stderr, "Error reading extern");
}
} else {
@ -1355,8 +1353,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) {
if (!F->Codegen()) {
if (auto FnAST = ParseTopLevelExpr()) {
if (!FnAST->Codegen()) {
fprintf(stderr, "Error generating code for top level expr");
}
} else {