[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 about teaching compiler techniques and LLVM specifically, *not* about
teaching modern and sane software engineering principles. In practice, teaching modern and sane software engineering principles. In practice,
this means that we'll take a number of shortcuts to simplify the 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 all over the place, doesn't use nice design patterns like
`visitors <http://en.wikipedia.org/wiki/Visitor_pattern>`_, etc... but `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 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 { class NumberExprAST : public ExprAST {
double Val; double Val;
public: public:
NumberExprAST(double val) : Val(val) {} NumberExprAST(double Val) : Val(Val) {}
}; };
The code above shows the definition of the base ExprAST class and one The code above shows the definition of the base ExprAST class and one
@ -66,16 +66,17 @@ language:
class VariableExprAST : public ExprAST { class VariableExprAST : public ExprAST {
std::string Name; std::string Name;
public: public:
VariableExprAST(const std::string &name) : Name(name) {} VariableExprAST(const std::string &Name) : Name(Name) {}
}; };
/// BinaryExprAST - Expression class for a binary operator. /// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST { class BinaryExprAST : public ExprAST {
char Op; char Op;
ExprAST *LHS, *RHS; std::unique_ptr<ExprAST> LHS, RHS;
public: public:
BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
: Op(op), LHS(lhs), RHS(rhs) {} std::unique_ptr<ExprAST> RHS)
: Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
}; };
/// CallExprAST - Expression class for function calls. /// CallExprAST - Expression class for function calls.
@ -83,8 +84,9 @@ language:
std::string Callee; std::string Callee;
std::vector<ExprAST*> Args; std::vector<ExprAST*> Args;
public: public:
CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) CallExprAST(const std::string &Callee,
: Callee(callee), Args(args) {} std::vector<std::unique_ptr<ExprAST>> Args)
: Callee(Callee), Args(std::move(Args)) {}
}; };
This is all (intentionally) rather straight-forward: variables capture This is all (intentionally) rather straight-forward: variables capture
@ -110,17 +112,18 @@ way to talk about functions themselves:
std::string Name; std::string Name;
std::vector<std::string> Args; std::vector<std::string> Args;
public: public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args) PrototypeAST(const std::string &name, std::vector<std::string> Args)
: Name(name), Args(args) {} : Name(name), Args(std::move(Args)) {}
}; };
/// FunctionAST - This class represents a function definition itself. /// FunctionAST - This class represents a function definition itself.
class FunctionAST { class FunctionAST {
PrototypeAST *Proto; std::unique_ptr<PrototypeAST> Proto;
ExprAST *Body; std::unique_ptr<ExprAST> Body;
public: public:
FunctionAST(PrototypeAST *proto, ExprAST *body) FunctionAST(std::unique_ptr<PrototypeAST> Proto,
: Proto(proto), Body(body) {} std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
}; };
In Kaleidoscope, functions are typed with just a count of their In Kaleidoscope, functions are typed with just a count of their
@ -142,9 +145,10 @@ be generated with calls like this:
.. code-block:: c++ .. code-block:: c++
ExprAST *X = new VariableExprAST("x"); auto LHS = llvm::make_unique<VariableExprAST>("x");
ExprAST *Y = new VariableExprAST("y"); auto RHS = llvm::make_unique<VariableExprAST>("y");
ExprAST *Result = new BinaryExprAST('+', X, 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: 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++ .. code-block:: c++
/// numberexpr ::= number /// numberexpr ::= number
static ExprAST *ParseNumberExpr() { static std::unique_ptr<ExprAST> ParseNumberExpr() {
ExprAST *Result = new NumberExprAST(NumVal); auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number getNextToken(); // consume the number
return Result; return std::move(Result);
} }
This routine is very simple: it expects to be called when the current 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++ .. code-block:: c++
/// parenexpr ::= '(' expression ')' /// parenexpr ::= '(' expression ')'
static ExprAST *ParseParenExpr() { static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (. getNextToken(); // eat (.
ExprAST *V = ParseExpression(); auto V = ParseExpression();
if (!V) return 0; if (!V) return nullptr;
if (CurTok != ')') if (CurTok != ')')
return Error("expected ')'"); return Error("expected ')'");
@ -250,22 +254,22 @@ function calls:
/// identifierexpr /// identifierexpr
/// ::= identifier /// ::= identifier
/// ::= identifier '(' expression* ')' /// ::= identifier '(' expression* ')'
static ExprAST *ParseIdentifierExpr() { static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr; std::string IdName = IdentifierStr;
getNextToken(); // eat identifier. getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref. if (CurTok != '(') // Simple variable ref.
return new VariableExprAST(IdName); return llvm::make_unique<VariableExprAST>(IdName);
// Call. // Call.
getNextToken(); // eat ( getNextToken(); // eat (
std::vector<ExprAST*> Args; std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') { if (CurTok != ')') {
while (1) { while (1) {
ExprAST *Arg = ParseExpression(); auto Arg = ParseExpression();
if (!Arg) return 0; if (!Arg) return nullptr;
Args.push_back(Arg); Args.push_back(std::move(Arg));
if (CurTok == ')') break; if (CurTok == ')') break;
@ -278,7 +282,7 @@ function calls:
// Eat the ')'. // Eat the ')'.
getNextToken(); 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 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 /// ::= identifierexpr
/// ::= numberexpr /// ::= numberexpr
/// ::= parenexpr /// ::= parenexpr
static ExprAST *ParsePrimary() { static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) { switch (CurTok) {
default: return Error("unknown token when expecting an expression"); default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr(); case tok_identifier: return ParseIdentifierExpr();
@ -390,11 +394,11 @@ a sequence of [binop,primaryexpr] pairs:
/// expression /// expression
/// ::= primary binoprhs /// ::= primary binoprhs
/// ///
static ExprAST *ParseExpression() { static std::unique_ptr<ExprAST> ParseExpression() {
ExprAST *LHS = ParsePrimary(); auto LHS = ParsePrimary();
if (!LHS) return 0; 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 ``ParseBinOpRHS`` is the function that parses the sequence of pairs for
@ -416,7 +420,8 @@ starts with:
/// binoprhs /// binoprhs
/// ::= ('+' primary)* /// ::= ('+' 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. // If this is a binop, find its precedence.
while (1) { while (1) {
int TokPrec = GetTokPrecedence(); int TokPrec = GetTokPrecedence();
@ -440,8 +445,8 @@ expression:
getNextToken(); // eat binop getNextToken(); // eat binop
// Parse the primary expression after the binary operator. // Parse the primary expression after the binary operator.
ExprAST *RHS = ParsePrimary(); auto RHS = ParsePrimary();
if (!RHS) return 0; if (!RHS) return nullptr;
As such, this code eats (and remembers) the binary operator and then As such, this code eats (and remembers) the binary operator and then
parses the primary expression that follows. This builds up the whole parses the primary expression that follows. This builds up the whole
@ -474,7 +479,8 @@ then continue parsing:
} }
// Merge LHS/RHS. // 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. } // 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. // the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence(); int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) { if (TokPrec < NextPrec) {
RHS = ParseBinOpRHS(TokPrec+1, RHS); RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (RHS == 0) return 0; if (RHS == 0) return 0;
} }
// Merge LHS/RHS. // 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. } // loop around to the top of the while loop.
} }
@ -541,7 +548,7 @@ expressions):
/// prototype /// prototype
/// ::= id '(' id* ')' /// ::= id '(' id* ')'
static PrototypeAST *ParsePrototype() { static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier) if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype"); return ErrorP("Expected function name in prototype");
@ -561,7 +568,7 @@ expressions):
// success. // success.
getNextToken(); // eat ')'. 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 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++ .. code-block:: c++
/// definition ::= 'def' prototype expression /// definition ::= 'def' prototype expression
static FunctionAST *ParseDefinition() { static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def. getNextToken(); // eat def.
PrototypeAST *Proto = ParsePrototype(); auto Proto = ParsePrototype();
if (Proto == 0) return 0; if (!Proto) return nullptr;
if (ExprAST *E = ParseExpression()) if (auto E = ParseExpression())
return new FunctionAST(Proto, E); return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
return 0; return nullptr;
} }
In addition, we support 'extern' to declare functions like 'sin' and 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++ .. code-block:: c++
/// external ::= 'extern' prototype /// external ::= 'extern' prototype
static PrototypeAST *ParseExtern() { static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern. getNextToken(); // eat extern.
return ParsePrototype(); return ParsePrototype();
} }
@ -599,13 +606,13 @@ nullary (zero argument) functions for them:
.. code-block:: c++ .. code-block:: c++
/// toplevelexpr ::= expression /// toplevelexpr ::= expression
static FunctionAST *ParseTopLevelExpr() { static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (ExprAST *E = ParseExpression()) { if (auto E = ParseExpression()) {
// Make an anonymous proto. // Make an anonymous proto.
PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return new FunctionAST(Proto, E); 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 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 { class NumberExprAST : public ExprAST {
double Val; double Val;
public: public:
NumberExprAST(double val) : Val(val) {} NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen(); virtual Value *Codegen();
}; };
... ...

View File

@ -260,12 +260,12 @@ parses a top-level expression to look like this:
static void HandleTopLevelExpression() { static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function. // Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) { if (auto FnAST = ParseTopLevelExpr()) {
if (Function *LF = F->Codegen()) { if (auto *FnIR = FnAST->Codegen()) {
LF->dump(); // Dump the function for exposition purposes. FnIR->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer. // 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 // Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function. // 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. /// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST { class IfExprAST : public ExprAST {
ExprAST *Cond, *Then, *Else; std::unique<ExprAST> Cond, Then, Else;
public: public:
IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else) IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
: Cond(cond), Then(then), Else(_else) {} std::unique_ptr<ExprAST> Else)
: Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
virtual Value *Codegen(); virtual Value *Codegen();
}; };
@ -109,36 +110,37 @@ First we define a new parsing function:
.. code-block:: c++ .. code-block:: c++
/// ifexpr ::= 'if' expression 'then' expression 'else' expression /// ifexpr ::= 'if' expression 'then' expression 'else' expression
static ExprAST *ParseIfExpr() { static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if. getNextToken(); // eat the if.
// condition. // condition.
ExprAST *Cond = ParseExpression(); auto Cond = ParseExpression();
if (!Cond) return 0; if (!Cond) return nullptr;
if (CurTok != tok_then) if (CurTok != tok_then)
return Error("expected then"); return Error("expected then");
getNextToken(); // eat the then getNextToken(); // eat the then
ExprAST *Then = ParseExpression(); auto Then = ParseExpression();
if (Then == 0) return 0; if (Then) return nullptr;
if (CurTok != tok_else) if (CurTok != tok_else)
return Error("expected else"); return Error("expected else");
getNextToken(); getNextToken();
ExprAST *Else = ParseExpression(); auto Else = ParseExpression();
if (!Else) return 0; 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: Next we hook it up as a primary expression:
.. code-block:: c++ .. code-block:: c++
static ExprAST *ParsePrimary() { static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) { switch (CurTok) {
default: return Error("unknown token when expecting an expression"); default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr(); case tok_identifier: return ParseIdentifierExpr();
@ -269,7 +271,7 @@ for ``IfExprAST``:
Value *IfExprAST::Codegen() { Value *IfExprAST::Codegen() {
Value *CondV = Cond->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. // Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV, CondV = Builder.CreateFCmpONE(CondV,
@ -464,11 +466,13 @@ variable name and the constituent expressions in the node.
/// ForExprAST - Expression class for for/in. /// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST { class ForExprAST : public ExprAST {
std::string VarName; std::string VarName;
ExprAST *Start, *End, *Step, *Body; std::unique_ptr<ExprAST> Start, End, Step, Body;
public: public:
ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end, ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
ExprAST *step, ExprAST *body) std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
: VarName(varname), Start(start), End(end), Step(step), Body(body) {} 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(); virtual Value *Codegen();
}; };
@ -483,7 +487,7 @@ value to null in the AST node:
.. code-block:: c++ .. code-block:: c++
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression /// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
static ExprAST *ParseForExpr() { static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for. getNextToken(); // eat the for.
if (CurTok != tok_identifier) if (CurTok != tok_identifier)
@ -497,31 +501,33 @@ value to null in the AST node:
getNextToken(); // eat '='. getNextToken(); // eat '='.
ExprAST *Start = ParseExpression(); auto Start = ParseExpression();
if (Start == 0) return 0; if (!Start) return nullptr;
if (CurTok != ',') if (CurTok != ',')
return Error("expected ',' after for start value"); return Error("expected ',' after for start value");
getNextToken(); getNextToken();
ExprAST *End = ParseExpression(); auto End = ParseExpression();
if (End == 0) return 0; if (!End) return nullptr;
// The step value is optional. // The step value is optional.
ExprAST *Step = 0; std::unique_ptr<ExprAST> Step;
if (CurTok == ',') { if (CurTok == ',') {
getNextToken(); getNextToken();
Step = ParseExpression(); Step = ParseExpression();
if (Step == 0) return 0; if (!Step) return nullptr;
} }
if (CurTok != tok_in) if (CurTok != tok_in)
return Error("expected 'in' after for"); return Error("expected 'in' after for");
getNextToken(); // eat 'in'. getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression(); auto Body = ParseExpression();
if (Body == 0) return 0; 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 LLVM IR for the 'for' Loop

View File

@ -129,15 +129,16 @@ this:
class PrototypeAST { class PrototypeAST {
std::string Name; std::string Name;
std::vector<std::string> Args; std::vector<std::string> Args;
bool isOperator; bool IsOperator;
unsigned Precedence; // Precedence if a binary op. unsigned Precedence; // Precedence if a binary op.
public: public:
PrototypeAST(const std::string &name, const std::vector<std::string> &args, PrototypeAST(const std::string &name, std::vector<std::string> Args,
bool isoperator = false, unsigned prec = 0) bool IsOperator = false, unsigned Prec = 0)
: Name(name), Args(args), isOperator(isoperator), Precedence(prec) {} : Name(name), Args(std::move(Args)), IsOperator(IsOperator),
Precedence(Prec) {}
bool isUnaryOp() const { return isOperator && Args.size() == 1; } bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
bool isBinaryOp() const { return isOperator && Args.size() == 2; } bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const { char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp()); assert(isUnaryOp() || isBinaryOp());
@ -161,7 +162,7 @@ user-defined operator, we need to parse it:
/// prototype /// prototype
/// ::= id '(' id* ')' /// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id) /// ::= binary LETTER number? (id, id)
static PrototypeAST *ParsePrototype() { static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName; std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. 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) if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator"); 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 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. /// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST { class UnaryExprAST : public ExprAST {
char Opcode; char Opcode;
ExprAST *Operand; std::unique_ptr<ExprAST> Operand;
public: public:
UnaryExprAST(char opcode, ExprAST *operand) UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(opcode), Operand(operand) {} : Opcode(Opcode), Operand(std::move(Operand)) {}
virtual Value *Codegen(); virtual Value *Codegen();
}; };
@ -322,7 +324,7 @@ simple: we'll add a new function to do it:
/// unary /// unary
/// ::= primary /// ::= primary
/// ::= '!' unary /// ::= '!' 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 the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',') if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary(); return ParsePrimary();
@ -330,9 +332,9 @@ simple: we'll add a new function to do it:
// If this is a unary operator, read it. // If this is a unary operator, read it.
int Opc = CurTok; int Opc = CurTok;
getNextToken(); getNextToken();
if (ExprAST *Operand = ParseUnary()) if (auto Operand = ParseUnary())
return new UnaryExprAST(Opc, Operand); return llvm::unique_ptr<UnaryExprAST>(Opc, std::move(Operand));
return 0; return nullptr;
} }
The grammar we add is pretty straightforward here. If we see a unary The grammar we add is pretty straightforward here. If we see a unary
@ -350,21 +352,22 @@ call ParseUnary instead:
/// binoprhs /// binoprhs
/// ::= ('+' unary)* /// ::= ('+' 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. // Parse the unary expression after the binary operator.
ExprAST *RHS = ParseUnary(); auto RHS = ParseUnary();
if (!RHS) return 0; if (!RHS) return nullptr;
... ...
} }
/// expression /// expression
/// ::= unary binoprhs /// ::= unary binoprhs
/// ///
static ExprAST *ParseExpression() { static std::unique_ptr<ExprAST> ParseExpression() {
ExprAST *LHS = ParseUnary(); auto LHS = ParseUnary();
if (!LHS) return 0; 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 With these two simple changes, we are now able to parse unary operators
@ -378,7 +381,7 @@ operator code above with:
/// ::= id '(' id* ')' /// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id) /// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id) /// ::= unary LETTER (id)
static PrototypeAST *ParsePrototype() { static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName; std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary. 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. // Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') { if (Op == '=') {
// Assignment requires the LHS to be an identifier. // Assignment requires the LHS to be an identifier.
VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS); VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS.get());
if (!LHSE) if (!LHSE)
return ErrorV("destination of '=' must be a variable"); return ErrorV("destination of '=' must be a variable");
@ -663,12 +663,12 @@ var/in, it looks like this:
/// VarExprAST - Expression class for var/in /// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST { class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, ExprAST*> > VarNames; std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
ExprAST *Body; std::unique_ptr<ExprAST> Body;
public: public:
VarExprAST(const std::vector<std::pair<std::string, ExprAST*> > &varnames, VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
ExprAST *body) std::unique_ptr<ExprAST> body)
: VarNames(varnames), Body(body) {} : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
virtual Value *Codegen(); virtual Value *Codegen();
}; };
@ -690,7 +690,7 @@ do is add it as a primary expression:
/// ::= ifexpr /// ::= ifexpr
/// ::= forexpr /// ::= forexpr
/// ::= varexpr /// ::= varexpr
static ExprAST *ParsePrimary() { static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) { switch (CurTok) {
default: return Error("unknown token when expecting an expression"); default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr(); case tok_identifier: return ParseIdentifierExpr();
@ -708,10 +708,10 @@ Next we define ParseVarExpr:
/// varexpr ::= 'var' identifier ('=' expression)? /// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression // (',' identifier ('=' expression)?)* 'in' expression
static ExprAST *ParseVarExpr() { static std::unique_ptr<ExprAST> ParseVarExpr() {
getNextToken(); // eat the var. 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. // At least one variable name is required.
if (CurTok != tok_identifier) if (CurTok != tok_identifier)
@ -727,15 +727,15 @@ into the local ``VarNames`` vector.
getNextToken(); // eat identifier. getNextToken(); // eat identifier.
// Read the optional initializer. // Read the optional initializer.
ExprAST *Init = 0; std::unique_ptr<ExprAST> Init;
if (CurTok == '=') { if (CurTok == '=') {
getNextToken(); // eat the '='. getNextToken(); // eat the '='.
Init = ParseExpression(); 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. // End of var list, exit loop.
if (CurTok != ',') break; if (CurTok != ',') break;
@ -755,10 +755,11 @@ AST node:
return Error("expected 'in' keyword after 'var'"); return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'. getNextToken(); // eat 'in'.
ExprAST *Body = ParseExpression(); auto Body = ParseExpression();
if (Body == 0) return 0; 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 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. // Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) { for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first; 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 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 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 .. code-block:: udiff
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); - auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ PrototypeAST *Proto = new PrototypeAST("main", 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. 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() { @@ -1108,17 +1108,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() { static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function. // Evaluate a top-level expression into an anonymous function.
if (FunctionAST *F = ParseTopLevelExpr()) { if (auto FnAST = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) { - if (auto *FnIR = FnAST->Codegen()) {
- // We're just doing this to make sure it executes. - // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject(); - TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer. - // 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 - // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function. - // 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++ .. 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. giving us locations for each of our expressions and variables.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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