git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245322
91177308-0d34-0410-b5e6-
96231b3b80d8
15 files changed:
about teaching compiler techniques and LLVM specifically, *not* about
teaching modern and sane software engineering principles. In practice,
this means that we'll take a number of shortcuts to simplify the
about teaching compiler techniques and LLVM specifically, *not* about
teaching modern and sane software engineering principles. In practice,
this means that we'll take a number of shortcuts to simplify the
-exposition. For example, the code leaks memory, uses global variables
+exposition. For example, the code uses global variables
all over the place, doesn't use nice design patterns like
`visitors <http://en.wikipedia.org/wiki/Visitor_pattern>`_, etc... but
it is very simple. If you dig in and use the code as a basis for future
all over the place, doesn't use nice design patterns like
`visitors <http://en.wikipedia.org/wiki/Visitor_pattern>`_, etc... but
it is very simple. If you dig in and use the code as a basis for future
class NumberExprAST : public ExprAST {
double Val;
public:
class NumberExprAST : public ExprAST {
double Val;
public:
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
};
The code above shows the definition of the base ExprAST class and one
};
The code above shows the definition of the base ExprAST class and one
class VariableExprAST : public ExprAST {
std::string Name;
public:
class VariableExprAST : public ExprAST {
std::string Name;
public:
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
};
/// CallExprAST - Expression class for function calls.
};
/// CallExprAST - Expression class for function calls.
std::string Callee;
std::vector<ExprAST*> Args;
public:
std::string Callee;
std::vector<ExprAST*> Args;
public:
- CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
};
This is all (intentionally) rather straight-forward: variables capture
};
This is all (intentionally) rather straight-forward: variables capture
std::string Name;
std::vector<std::string> Args;
public:
std::string Name;
std::vector<std::string> Args;
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
+ PrototypeAST(const std::string &name, std::vector<std::string> Args)
+ : Name(name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body)
- : Proto(proto), Body(body) {}
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
};
In Kaleidoscope, functions are typed with just a count of their
};
In Kaleidoscope, functions are typed with just a count of their
- ExprAST *X = new VariableExprAST("x");
- ExprAST *Y = new VariableExprAST("y");
- ExprAST *Result = new BinaryExprAST('+', X, Y);
+ auto LHS = llvm::make_unique<VariableExprAST>("x");
+ auto RHS = llvm::make_unique<VariableExprAST>("y");
+ auto Result = std::make_unique<BinaryExprAST>('+', std::move(LHS),
+ std::move(RHS));
In order to do this, we'll start by defining some basic helper routines:
In order to do this, we'll start by defining some basic helper routines:
.. code-block:: c++
/// numberexpr ::= number
.. code-block:: c++
/// numberexpr ::= number
- static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+ static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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
.. code-block:: c++
/// parenexpr ::= '(' expression ')'
.. code-block:: c++
/// parenexpr ::= '(' expression ')'
- static ExprAST *ParseParenExpr() {
+ static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
getNextToken(); // eat (.
- ExprAST *V = ParseExpression();
- if (!V) return 0;
+ auto V = ParseExpression();
+ if (!V) return nullptr;
if (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
- static ExprAST *ParseIdentifierExpr() {
+ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg) return 0;
- Args.push_back(Arg);
+ auto Arg = ParseExpression();
+ if (!Arg) return nullptr;
+ Args.push_back(std::move(Arg));
if (CurTok == ')') break;
if (CurTok == ')') break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
This routine follows the same style as the other routines. (It expects
}
This routine follows the same style as the other routines. (It expects
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
/// expression
/// ::= primary binoprhs
///
/// expression
/// ::= primary binoprhs
///
- static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
- if (!LHS) return 0;
+ static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
``ParseBinOpRHS`` is the function that parses the sequence of pairs for
}
``ParseBinOpRHS`` is the function that parses the sequence of pairs for
/// binoprhs
/// ::= ('+' primary)*
/// binoprhs
/// ::= ('+' primary)*
- static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
- if (!RHS) return 0;
+ auto RHS = ParsePrimary();
+ if (!RHS) return nullptr;
As such, this code eats (and remembers) the binary operator and then
parses the primary expression that follows. This builds up the whole
As such, this code eats (and remembers) the binary operator and then
parses the primary expression that follows. This builds up the whole
- 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.
}
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, RHS);
+ RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
if (RHS == 0) return 0;
}
// Merge LHS/RHS.
if (RHS == 0) return 0;
}
// Merge LHS/RHS.
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
} // loop around to the top of the while loop.
}
} // loop around to the top of the while loop.
}
/// prototype
/// ::= id '(' id* ')'
/// prototype
/// ::= id '(' id* ')'
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
// success.
getNextToken(); // eat ')'.
// success.
getNextToken(); // eat ')'.
- return new PrototypeAST(FnName, ArgNames);
+ return llvm::make_unique<PrototypeAST>(FnName, std::move(ArgNames));
}
Given this, a function definition is very simple, just a prototype plus
}
Given this, a function definition is very simple, just a prototype plus
.. code-block:: c++
/// definition ::= 'def' prototype expression
.. code-block:: c++
/// definition ::= 'def' prototype expression
- static FunctionAST *ParseDefinition() {
+ static std::unique_ptr<FunctionAST> ParseDefinition() {
getNextToken(); // eat def.
getNextToken(); // eat def.
- PrototypeAST *Proto = ParsePrototype();
- if (Proto == 0) return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto) return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
In addition, we support 'extern' to declare functions like 'sin' and
}
In addition, we support 'extern' to declare functions like 'sin' and
.. code-block:: c++
/// external ::= 'extern' prototype
.. code-block:: c++
/// external ::= 'extern' prototype
- static PrototypeAST *ParseExtern() {
+ static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
.. code-block:: c++
/// toplevelexpr ::= expression
.. code-block:: c++
/// toplevelexpr ::= expression
- static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+ static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
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
class NumberExprAST : public ExprAST {
double Val;
public:
class NumberExprAST : public ExprAST {
double Val;
public:
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
virtual Value *Codegen();
};
...
virtual Value *Codegen();
};
...
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
- LF->dump(); // Dump the function for exposition purposes.
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
+ FnIR->dump(); // Dump the function for exposition purposes.
// JIT the function, returning a function pointer.
// JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
+ std::unique<ExprAST> Cond, Then, Else;
- IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
- : Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
virtual Value *Codegen();
};
virtual Value *Codegen();
};
.. code-block:: c++
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
.. code-block:: c++
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
- static ExprAST *ParseIfExpr() {
+ static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
// condition.
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
- if (!Cond) return 0;
+ auto Cond = ParseExpression();
+ if (!Cond) return nullptr;
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0) return 0;
+ auto Then = ParseExpression();
+ if (Then) return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
- if (!Else) return 0;
+ auto Else = ParseExpression();
+ if (!Else) return nullptr;
- return new IfExprAST(Cond, Then, Else);
+ return llvm::make_unique<IfExprAST>(std::move(Cond), std::move(Then),
+ std::move(Else));
}
Next we hook it up as a primary expression:
.. code-block:: c++
}
Next we hook it up as a primary expression:
.. code-block:: c++
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
- if (CondV == 0) return 0;
+ if (!CondV) return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV,
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(CondV,
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
virtual Value *Codegen();
};
virtual Value *Codegen();
};
.. code-block:: c++
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
.. code-block:: c++
/// forexpr ::= 'for' identifier '=' expr ',' expr (',' expr)? 'in' expression
- static ExprAST *ParseForExpr() {
+ static std::unique_ptr<ExprAST> ParseForExpr() {
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
getNextToken(); // eat '='.
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0) return 0;
+ auto Start = ParseExpression();
+ if (!Start) return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0) return 0;
+ auto End = ParseExpression();
+ if (!End) return nullptr;
// The step value is optional.
// The step value is optional.
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0) return 0;
+ if (!Step) return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0) return 0;
+ auto Body = ParseExpression();
+ if (!Body) return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start),
+ std::move(End), std::move(Step),
+ std::move(Body));
}
LLVM IR for the 'for' Loop
}
LLVM IR for the 'for' Loop
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
unsigned Precedence; // Precedence if a binary op.
public:
unsigned Precedence; // Precedence if a binary op.
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args,
- bool isoperator = false, unsigned prec = 0)
- : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
+ PrototypeAST(const std::string &name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
- bool isUnaryOp() const { return isOperator && Args.size() == 1; }
- bool isBinaryOp() const { return isOperator && Args.size() == 2; }
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return 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
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
+ std::unique_ptr<ExprAST> Operand;
- UnaryExprAST(char opcode, ExprAST *operand)
- : Opcode(opcode), Operand(operand) {}
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
virtual Value *Codegen();
};
virtual Value *Codegen();
};
/// unary
/// ::= primary
/// ::= '!' unary
/// unary
/// ::= primary
/// ::= '!' unary
- static ExprAST *ParseUnary() {
+ static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
- if (ExprAST *Operand = ParseUnary())
- return new UnaryExprAST(Opc, Operand);
- return 0;
+ if (auto Operand = ParseUnary())
+ return llvm::unique_ptr<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
}
The grammar we add is pretty straightforward here. If we see a unary
}
The grammar we add is pretty straightforward here. If we see a unary
/// binoprhs
/// ::= ('+' unary)*
/// binoprhs
/// ::= ('+' unary)*
- static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
...
// Parse the unary expression after the binary operator.
...
// Parse the unary expression after the binary operator.
- ExprAST *RHS = ParseUnary();
- if (!RHS) return 0;
+ auto RHS = ParseUnary();
+ if (!RHS) return nullptr;
...
}
/// expression
/// ::= unary binoprhs
///
...
}
/// expression
/// ::= unary binoprhs
///
- static ExprAST *ParseExpression() {
- ExprAST *LHS = ParseUnary();
- if (!LHS) return 0;
+ static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
With these two simple changes, we are now able to parse unary operators
}
With these two simple changes, we are now able to parse unary operators
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
- static PrototypeAST *ParsePrototype() {
+ static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
// Special case '=' because we don't want to emit the LHS as an expression.
if (Op == '=') {
// Assignment requires the LHS to be an identifier.
- VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS);
+ VariableExprAST *LHSE = dynamic_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
- std::vector<std::pair<std::string, ExprAST*> > VarNames;
- ExprAST *Body;
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
- VarExprAST(const std::vector<std::pair<std::string, ExprAST*> > &varnames,
- ExprAST *body)
- : VarNames(varnames), Body(body) {}
+ VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
virtual Value *Codegen();
};
virtual Value *Codegen();
};
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
- static ExprAST *ParsePrimary() {
+ static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
/// varexpr ::= 'var' identifier ('=' 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.
if (CurTok != tok_identifier)
// At least one variable name is required.
if (CurTok != tok_identifier)
getNextToken(); // eat identifier.
// Read the optional initializer.
getNextToken(); // eat identifier.
// Read the optional initializer.
+ std::unique_ptr<ExprAST> Init;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
- if (Init == 0) return 0;
+ if (!Init) return nullptr;
- VarNames.push_back(std::make_pair(Name, Init));
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',') break;
// End of var list, exit loop.
if (CurTok != ',') break;
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0) return 0;
+ auto Body = ParseExpression();
+ if (!Body) return nullptr;
- return new VarExprAST(VarNames, Body);
+ return llvm::make_unique<VarExprAST>(std::move(VarNames),
+ std::move(Body));
}
Now that we can parse and represent the code, we need to support
}
Now that we can parse and represent the code, we need to support
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
- ExprAST *Init = VarNames[i].second;
+ ExprAST *Init = VarNames[i].second.get();
Basically it loops over all the variables, installing them one at a
time. For each variable we put into the symbol table, we remember the
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
- - PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- + PrototypeAST *Proto = new PrototypeAST("main", std::vector<std::string>());
+ - auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ + auto Proto = llvm::make_unique<PrototypeAST>("main", std::vector<std::string>());
just with the simple change of giving it a name.
just with the simple change of giving it a name.
@@ -1108,17 +1108,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
@@ -1108,17 +1108,8 @@ static void HandleExtern() {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- - if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ - if (auto *FnIR = FnAST->Codegen()) {
- // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer.
- // We're just doing this to make sure it executes.
- TheExecutionEngine->finalizeObject();
- // JIT the function, returning a function pointer.
- - void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ - void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
-
- // Cast it to the right type (takes no arguments, returns a double) so we
- // can call it as a native function.
- 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.
+#include "llvm/ADT/STLExtras.h"
#include <cctype>
#include <cstdio>
#include <cctype>
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include <map>
#include <string>
#include <vector>
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
public:
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
public:
- NumberExprAST(double val) {}
+ NumberExprAST(double Val) {}
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
public:
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
public:
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
public:
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS) {}
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
};
/// PrototypeAST - This class represents the "prototype" for a function,
};
/// PrototypeAST - This class represents the "prototype" for a function,
std::string Name;
std::vector<std::string> Args;
public:
std::string Name;
std::vector<std::string> Args;
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args)
+ : Name(Name), Args(std::move(Args)) {}
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
public:
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
public:
- FunctionAST(PrototypeAST *proto, ExprAST *body) {}
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body) {}
};
} // end anonymous namespace
};
} // end anonymous namespace
}
/// Error* - These are little helper functions for error handling.
}
/// Error* - These are little helper functions for error handling.
-ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
-PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
+std::unique_ptr<ExprAST> Error(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
+ Error(Str);
+ return nullptr;
+}
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg) return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')') break;
if (CurTok == ')') break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
}
/// parenexpr ::= '(' expression ')'
-static ExprAST *ParseParenExpr() {
+static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
getNextToken(); // eat (.
- ExprAST *V = ParseExpression();
- if (!V) return 0;
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
if (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
/// binoprhs
/// ::= ('+' primary)*
/// binoprhs
/// ::= ('+' primary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
- if (!RHS) return 0;
+ auto RHS = ParsePrimary();
+ if (!RHS) return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, RHS);
- if (RHS == 0) return 0;
+ RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
+ if (!RHS) return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
}
}
/// expression
/// ::= primary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
- if (!LHS) return 0;
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
}
/// prototype
/// ::= id '(' id* ')'
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
// success.
getNextToken(); // eat ')'.
// success.
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();
- if (Proto == 0) return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto) return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
class NumberExprAST : public ExprAST {
double Val;
public:
class NumberExprAST : public ExprAST {
double Val;
public:
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class VariableExprAST : public ExprAST {
std::string Name;
public:
class VariableExprAST : public ExprAST {
std::string Name;
public:
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
std::string Name;
std::vector<std::string> Args;
public:
std::string Name;
std::vector<std::string> Args;
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args)
+ : Name(Name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- 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)) {}
}
/// Error* - These are little helper functions for error handling.
}
/// Error* - These are little helper functions for error handling.
-ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
-PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
-FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
+std::unique_ptr<ExprAST> Error(const char *Str) {
+ fprintf(stderr, "Error: %s\n", Str);
+ return nullptr;
+}
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
+ Error(Str);
+ return nullptr;
+}
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
+ Error(Str);
+ return nullptr;
+}
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST*> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg) return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')') break;
if (CurTok == ')') break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ return std::move(Result);
}
/// parenexpr ::= '(' expression ')'
}
/// parenexpr ::= '(' expression ')'
-static ExprAST *ParseParenExpr() {
+static std::unique_ptr<ExprAST> ParseParenExpr() {
getNextToken(); // eat (.
getNextToken(); // eat (.
- ExprAST *V = ParseExpression();
- if (!V) return 0;
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
if (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
switch (CurTok) {
default: return Error("unknown token when expecting an expression");
case tok_identifier: return ParseIdentifierExpr();
/// binoprhs
/// ::= ('+' primary)*
/// binoprhs
/// ::= ('+' primary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
- if (!RHS) return 0;
+ auto RHS = ParsePrimary();
+ if (!RHS) return nullptr;
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec+1, RHS);
- if (RHS == 0) return 0;
+ RHS = ParseBinOpRHS(TokPrec+1, std::move(RHS));
+ if (!RHS) return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
}
}
/// expression
/// ::= primary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
- if (!LHS) return 0;
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
+ if (!LHS) return nullptr;
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
}
/// prototype
/// ::= id '(' id* ')'
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
// success.
getNextToken(); // eat ')'.
// success.
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();
- if (Proto == 0) return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto) return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value*> NamedValues;
static IRBuilder<> Builder(getGlobalContext());
static std::map<std::string, Value*> NamedValues;
-Value *ErrorV(const char *Str) { Error(Str); return 0; }
+Value *ErrorV(const char *Str) { Error(Str); return nullptr; }
Value *NumberExprAST::Codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
Value *NumberExprAST::Codegen() {
return ConstantFP::get(getGlobalContext(), APFloat(Val));
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0) return 0;
+ if (!L || !R) return nullptr;
switch (Op) {
case '+': return Builder.CreateFAdd(L, R, "addtmp");
switch (Op) {
case '+': return Builder.CreateFAdd(L, R, "addtmp");
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value*> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value*> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0) return 0;
+ if (!ArgsV.back()) return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
Doubles, false);
- Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
+ Function *F = Function::Create(FT, Function::ExternalLinkage, Name,
+ TheModule);
// If F conflicted, there was already something named 'Name'. If it has a
// body, don't allow redefinition or reextern.
// If F conflicted, there was already something named 'Name'. If it has a
// body, don't allow redefinition or reextern.
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Error reading body, remove function.
TheFunction->eraseFromParent();
// Error reading body, remove function.
TheFunction->eraseFromParent();
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
fprintf(stderr, "Read function definition:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (Function *F = P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
fprintf(stderr, "Read extern: ");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read top-level expression:");
fprintf(stderr, "Read top-level expression:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
getNextToken();
// Make the module, which holds all the code.
getNextToken();
// Make the module, which holds all the code.
- TheModule = new Module("my cool jit", Context);
+ std::unique_ptr<Module> Owner = llvm::make_unique<Module>("my cool jit", Context);
+ TheModule = Owner.get();
// Run the main "interpreter loop" now.
MainLoop();
// Run the main "interpreter loop" now.
MainLoop();
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST *> Args;
-
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
-
+ PrototypeAST(const std::string &name, std::vector<std::string> Args)
+ : Name(name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
-
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
-
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
}
/// 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);
-PrototypeAST *ErrorP(const char *Str) {
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
-FunctionAST *ErrorF(const char *Str) {
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST *> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg)
- return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')')
break;
if (CurTok == ')')
break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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 (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
/// ::= identifierexpr
/// ::= numberexpr
/// ::= parenexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
/// binoprhs
/// ::= ('+' primary)*
/// binoprhs
/// ::= ('+' primary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
+ auto RHS = ParsePrimary();
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec + 1, RHS);
- if (RHS == 0)
- return 0;
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
}
}
/// expression
/// ::= primary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
}
/// prototype
/// ::= id '(' id* ')'
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
// success.
getNextToken(); // eat ')'.
// success.
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();
- if (Proto == 0)
- return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
Function *PF = OpenModule->getFunction(FnName);
if (PF && !PF->empty()) {
ErrorF("redefinition of function across modules");
Function *PF = OpenModule->getFunction(FnName);
if (PF && !PF->empty()) {
ErrorF("redefinition of function across modules");
}
// If we don't have a prototype yet, create one.
}
// If we don't have a prototype yet, create one.
Value *ErrorV(const char *Str) {
Error(Str);
Value *ErrorV(const char *Str) {
Error(Str);
}
Value *NumberExprAST::Codegen() {
}
Value *NumberExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0)
- return 0;
+ if (!L || !R)
+ return nullptr;
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = JITHelper->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = JITHelper->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0)
- return 0;
+ if (!ArgsV.back())
+ return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Error reading body, remove function.
TheFunction->eraseFromParent();
// Error reading body, remove function.
TheFunction->eraseFromParent();
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
//===----------------------------------------------------------------------===//
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
fprintf(stderr, "Read function definition:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (Function *F = P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
fprintf(stderr, "Read extern: ");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
// JIT the function, returning a function pointer.
// JIT the function, returning a function pointer.
- void *FPtr = JITHelper->getPointerToFunction(LF);
+ void *FPtr = JITHelper->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST *> Args;
-
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
-
+ std::unique_ptr<ExprAST> Cond, Then, Else;
- IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
- : Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
-
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
- PrototypeAST(const std::string &name, const std::vector<std::string> &args)
- : Name(name), Args(args) {}
-
+ PrototypeAST(const std::string &name, std::vector<std::string> Args)
+ : Name(name), Args(std::move(Args)) {}
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
Function *Codegen();
};
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
-
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
-
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
}
/// 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);
-PrototypeAST *ErrorP(const char *Str) {
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
-FunctionAST *ErrorF(const char *Str) {
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST *> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg)
- return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')')
break;
if (CurTok == ')')
break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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 (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
}
/// 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.
// condition.
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
+ auto Cond = ParseExpression();
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0)
- return 0;
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
+ auto Else = ParseExpression();
- 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.
if (CurTok != tok_identifier)
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
return Error("expected '=' after for");
getNextToken(); // eat '='.
return Error("expected '=' after for");
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0)
- return 0;
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0)
- return 0;
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
// The step value is optional.
// The step value is optional.
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0)
- return 0;
+ if (!Step)
+ return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
/// binoprhs
/// ::= ('+' primary)*
/// binoprhs
/// ::= ('+' primary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
getNextToken(); // eat binop
// Parse the primary expression after the binary operator.
- ExprAST *RHS = ParsePrimary();
+ auto RHS = ParsePrimary();
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec + 1, RHS);
- if (RHS == 0)
- return 0;
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS),
+ std::move(RHS));
}
}
/// expression
/// ::= primary binoprhs
///
}
}
/// expression
/// ::= primary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParsePrimary();
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParsePrimary();
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
}
/// prototype
/// ::= id '(' id* ')'
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
if (CurTok != tok_identifier)
return ErrorP("Expected function name in prototype");
// success.
getNextToken(); // eat ')'.
// success.
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();
- if (Proto == 0)
- return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("",
+ std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
Value *ErrorV(const char *Str) {
Error(Str);
Value *ErrorV(const char *Str) {
Error(Str);
}
Value *NumberExprAST::Codegen() {
}
Value *NumberExprAST::Codegen() {
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0)
- return 0;
+ if (!L || !R)
+ return nullptr;
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0)
- return 0;
+ if (!ArgsV.back())
+ return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
- if (CondV == 0)
- return 0;
+ if (!CondV)
+ return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
- if (ThenV == 0)
- return 0;
+ if (!ThenV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
- if (ElseV == 0)
- return 0;
+ if (!ElseV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
- if (StartVal == 0)
- return 0;
+ if (!StartVal)
+ return nullptr;
// Make the new basic block for the loop header, inserting after current
// block.
// Make the new basic block for the loop header, inserting after current
// block.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
- if (Body->Codegen() == 0)
- return 0;
+ if (!Body->Codegen())
+ return nullptr;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
- if (StepVal == 0)
- return 0;
+ if (!StepVal)
+ return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
// Compute the end condition.
Value *EndCond = End->Codegen();
// Compute the end condition.
Value *EndCond = End->Codegen();
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ return nullptr;
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Create a new basic block to start insertion into.
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// Error reading body, remove function.
TheFunction->eraseFromParent();
// Error reading body, remove function.
TheFunction->eraseFromParent();
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
fprintf(stderr, "Read function definition:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (Function *F = P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
fprintf(stderr, "Read extern: ");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
Value *Codegen() override;
};
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
Value *Codegen() override;
};
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
+ std::unique_ptr<ExprAST> Operand;
- UnaryExprAST(char opcode, ExprAST *operand)
- : Opcode(opcode), Operand(operand) {}
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST *> Args;
-
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
-
+ std::unique_ptr<ExprAST> Cond, Then, Else;
- IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
- : Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
-
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
unsigned Precedence; // Precedence if a binary op.
public:
unsigned Precedence; // Precedence if a binary op.
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args,
- bool isoperator = false, unsigned prec = 0)
- : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
- bool isUnaryOp() const { return isOperator && Args.size() == 1; }
- bool isBinaryOp() const { return isOperator && Args.size() == 2; }
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
-
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
-
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
}
/// 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);
-PrototypeAST *ErrorP(const char *Str) {
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
-FunctionAST *ErrorF(const char *Str) {
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST *> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg)
- return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')')
break;
if (CurTok == ')')
break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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 (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
}
/// 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.
// condition.
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
+ auto Cond = ParseExpression();
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0)
- return 0;
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
+ auto Else = ParseExpression();
- 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.
if (CurTok != tok_identifier)
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
return Error("expected '=' after for");
getNextToken(); // eat '='.
return Error("expected '=' after for");
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0)
- return 0;
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0)
- return 0;
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
// The step value is optional.
// The step value is optional.
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0)
- return 0;
+ if (!Step)
+ return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
/// ::= parenexpr
/// ::= ifexpr
/// ::= forexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
/// unary
/// ::= primary
/// ::= '!' unary
/// unary
/// ::= primary
/// ::= '!' unary
-static ExprAST *ParseUnary() {
+static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
- if (ExprAST *Operand = ParseUnary())
- return new UnaryExprAST(Opc, Operand);
- return 0;
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
}
/// binoprhs
/// ::= ('+' unary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
- ExprAST *RHS = ParseUnary();
+ auto RHS = ParseUnary();
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec + 1, RHS);
- if (RHS == 0)
- return 0;
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
}
}
/// expression
/// ::= unary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParseUnary();
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return 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();
- if (Proto == 0)
- return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
Value *ErrorV(const char *Str) {
Error(Str);
Value *ErrorV(const char *Str) {
Error(Str);
}
Value *NumberExprAST::Codegen() {
}
Value *NumberExprAST::Codegen() {
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
- if (OperandV == 0)
- return 0;
+ if (!OperandV)
+ return nullptr;
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *BinaryExprAST::Codegen() {
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0)
- return 0;
+ if (!L || !R)
+ return nullptr;
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0)
- return 0;
+ if (!ArgsV.back())
+ return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
- if (CondV == 0)
- return 0;
+ if (!CondV)
+ return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
- if (ThenV == 0)
- return 0;
+ if (!ThenV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
- if (ElseV == 0)
- return 0;
+ if (!ElseV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
- if (StartVal == 0)
- return 0;
+ if (!StartVal)
+ return nullptr;
// Make the new basic block for the loop header, inserting after current
// block.
// Make the new basic block for the loop header, inserting after current
// block.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
- if (Body->Codegen() == 0)
- return 0;
+ if (!Body->Codegen())
+ return nullptr;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
- if (StepVal == 0)
- return 0;
+ if (!StepVal)
+ return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
// Compute the end condition.
Value *EndCond = End->Codegen();
// Compute the end condition.
Value *EndCond = End->Codegen();
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
return EndCond;
// Convert condition to a bool by comparing equal to 0.0.
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ return nullptr;
// If this is an operator, install it.
if (Proto->isBinaryOp())
// If this is an operator, install it.
if (Proto->isBinaryOp())
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
fprintf(stderr, "Read function definition:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (Function *F = P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
fprintf(stderr, "Read extern: ");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
Value *Codegen() override;
};
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
- VariableExprAST(const std::string &name) : Name(name) {}
+ VariableExprAST(const std::string &Name) : Name(Name) {}
const std::string &getName() const { return Name; }
Value *Codegen() override;
};
const std::string &getName() const { return Name; }
Value *Codegen() override;
};
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
+ std::unique_ptr<ExprAST> Operand;
- UnaryExprAST(char opcode, ExprAST *operand)
- : Opcode(opcode), Operand(operand) {}
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
Value *Codegen() override;
};
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs)
- : Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
Value *Codegen() override;
};
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST *> Args;
-
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(const std::string &callee, std::vector<ExprAST *> &args)
- : Callee(callee), Args(args) {}
+ CallExprAST(const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : Callee(Callee), Args(std::move(Args)) {}
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
Value *Codegen() override;
};
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
-
+ std::unique_ptr<ExprAST> Cond, Then, Else;
- IfExprAST(ExprAST *cond, ExprAST *then, ExprAST *_else)
- : Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
+ std::unique_ptr<ExprAST> Else)
+ : Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
Value *Codegen() override;
};
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
-
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
Value *Codegen() override;
};
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
Value *Codegen() override;
};
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
- std::vector<std::pair<std::string, ExprAST *> > VarNames;
- ExprAST *Body;
-
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
- VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames,
- ExprAST *body)
- : VarNames(varnames), Body(body) {}
-
+ VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
Value *Codegen() override;
};
Value *Codegen() override;
};
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
unsigned Precedence; // Precedence if a binary op.
public:
unsigned Precedence; // Precedence if a binary op.
public:
- PrototypeAST(const std::string &name, const std::vector<std::string> &args,
- bool isoperator = false, unsigned prec = 0)
- : Name(name), Args(args), isOperator(isoperator), Precedence(prec) {}
+ PrototypeAST(const std::string &Name, std::vector<std::string> Args,
+ bool IsOperator = false, unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
- bool isUnaryOp() const { return isOperator && Args.size() == 1; }
- bool isBinaryOp() const { return isOperator && Args.size() == 2; }
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
-
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
-
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
} // end anonymous namespace
Function *Codegen();
};
} // end anonymous namespace
}
/// 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);
-PrototypeAST *ErrorP(const char *Str) {
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
-FunctionAST *ErrorF(const char *Str) {
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
std::string IdName = IdentifierStr;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(IdName);
+ return llvm::make_unique<VariableExprAST>(IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST *> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
- if (!Arg)
- return 0;
- Args.push_back(Arg);
+ if (auto Arg = ParseExpression())
+ Args.push_back(std::move(Arg));
+ else
+ return nullptr;
if (CurTok == ')')
break;
if (CurTok == ')')
break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(IdName, Args);
+ return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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 (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
}
/// 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.
// condition.
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
+ auto Cond = ParseExpression();
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0)
- return 0;
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
+ auto Else = ParseExpression();
- 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.
if (CurTok != tok_identifier)
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
return Error("expected '=' after for");
getNextToken(); // eat '='.
return Error("expected '=' after for");
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0)
- return 0;
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0)
- return 0;
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
// The step value is optional.
// The step value is optional.
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0)
- return 0;
+ if (!Step)
+ return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
}
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
}
/// varexpr ::= 'var' identifier ('=' 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.
if (CurTok != tok_identifier)
// At least one variable name is required.
if (CurTok != tok_identifier)
getNextToken(); // eat identifier.
// Read the optional initializer.
getNextToken(); // eat identifier.
// Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
- if (Init == 0)
- return 0;
+ if (!Init)
+ return nullptr;
- VarNames.push_back(std::make_pair(Name, Init));
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',')
// End of var list, exit loop.
if (CurTok != ',')
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new VarExprAST(VarNames, Body);
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
/// unary
/// ::= primary
/// ::= '!' unary
/// unary
/// ::= primary
/// ::= '!' unary
-static ExprAST *ParseUnary() {
+static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
- if (ExprAST *Operand = ParseUnary())
- return new UnaryExprAST(Opc, Operand);
- return 0;
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
}
/// binoprhs
/// ::= ('+' unary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+ static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
- ExprAST *RHS = ParseUnary();
+ auto RHS = ParseUnary();
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec + 1, RHS);
- if (RHS == 0)
- return 0;
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
- LHS = new BinaryExprAST(BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
}
}
/// expression
/// ::= unary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParseUnary();
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
std::string FnName;
unsigned Kind = 0; // 0 = identifier, 1 = unary, 2 = binary.
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return 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();
- if (Proto == 0)
- return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// toplevelexpr ::= expression
-static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
+static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
+ if (auto E = ParseExpression()) {
// Make an anonymous proto.
// Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
Value *ErrorV(const char *Str) {
Error(Str);
Value *ErrorV(const char *Str) {
Error(Str);
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
return ErrorV("Unknown variable name");
// Load the value.
return ErrorV("Unknown variable name");
// Load the value.
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
- if (OperandV == 0)
- return 0;
+ if (!OperandV)
+ return nullptr;
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
return ErrorV("Unknown unary operator");
return Builder.CreateCall(F, OperandV, "unop");
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
- VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
+ VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
- if (Val == 0)
- return 0;
+ if (!Val)
+ return nullptr;
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0)
- return 0;
+ if (!L || !R)
+ return nullptr;
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
Value *CallExprAST::Codegen() {
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0)
- return 0;
+ if (!ArgsV.back())
+ return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
Value *IfExprAST::Codegen() {
Value *CondV = Cond->Codegen();
- if (CondV == 0)
- return 0;
+ if (!CondV)
+ return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
- if (ThenV == 0)
- return 0;
+ if (!ThenV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
- if (ElseV == 0)
- return 0;
+ if (!ElseV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
- if (StartVal == 0)
- return 0;
+ if (!StartVal)
+ return nullptr;
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
- if (Body->Codegen() == 0)
- return 0;
+ if (!Body->Codegen())
+ return nullptr;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
- if (StepVal == 0)
- return 0;
+ if (!StepVal)
+ return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
// Compute the end condition.
Value *EndCond = End->Codegen();
// Compute the end condition.
Value *EndCond = End->Codegen();
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
- ExprAST *Init = VarNames[i].second;
+ ExprAST *Init = VarNames[i].second.get();
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
- if (InitVal == 0)
- return 0;
+ if (!InitVal)
+ return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
- if (BodyVal == 0)
- return 0;
+ if (!BodyVal)
+ return nullptr;
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ return nullptr;
// If this is an operator, install it.
if (Proto->isBinaryOp())
// If this is an operator, install it.
if (Proto->isBinaryOp())
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
if (Proto->isBinaryOp())
BinopPrecedence.erase(Proto->getOperatorName());
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (auto *FnIR = FnAST->Codegen()) {
fprintf(stderr, "Read function definition:");
fprintf(stderr, "Read function definition:");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (Function *F = P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (auto *FnIR = ProtoAST->Codegen()) {
fprintf(stderr, "Read extern: ");
fprintf(stderr, "Read extern: ");
}
} else {
// Skip token for error recovery.
}
} else {
// Skip token for error recovery.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (Function *LF = F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (auto *FnIR = FnAST->Codegen()) {
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
TheExecutionEngine->finalizeObject();
// JIT the function, returning a function pointer.
- void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
+ void *FPtr = TheExecutionEngine->getPointerToFunction(FnIR);
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
// Cast it to the right type (takes no arguments, returns a double) so we
// can call it as a native function.
/// ExprAST - Base class for all expression nodes.
class ExprAST {
SourceLocation Loc;
/// ExprAST - Base class for all expression nodes.
class ExprAST {
SourceLocation Loc;
public:
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
public:
int getLine() const { return Loc.Line; }
int getCol() const { return Loc.Col; }
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
- NumberExprAST(double val) : Val(val) {}
+ NumberExprAST(double Val) : Val(Val) {}
std::ostream &dump(std::ostream &out, int ind) override {
return ExprAST::dump(out << Val, ind);
}
std::ostream &dump(std::ostream &out, int ind) override {
return ExprAST::dump(out << Val, ind);
}
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
- VariableExprAST(SourceLocation Loc, const std::string &name)
- : ExprAST(Loc), Name(name) {}
+ VariableExprAST(SourceLocation Loc, const std::string &Name)
+ : ExprAST(Loc), Name(Name) {}
const std::string &getName() const { return Name; }
std::ostream &dump(std::ostream &out, int ind) override {
return ExprAST::dump(out << Name, ind);
const std::string &getName() const { return Name; }
std::ostream &dump(std::ostream &out, int ind) override {
return ExprAST::dump(out << Name, ind);
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
/// UnaryExprAST - Expression class for a unary operator.
class UnaryExprAST : public ExprAST {
char Opcode;
+ std::unique_ptr<ExprAST> Operand;
- UnaryExprAST(char opcode, ExprAST *operand)
- : Opcode(opcode), Operand(operand) {}
+ UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
+ : Opcode(Opcode), Operand(std::move(Operand)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "unary" << Opcode, ind);
Operand->dump(out, ind + 1);
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "unary" << Opcode, ind);
Operand->dump(out, ind + 1);
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
/// BinaryExprAST - Expression class for a binary operator.
class BinaryExprAST : public ExprAST {
char Op;
+ std::unique_ptr<ExprAST> LHS, RHS;
- BinaryExprAST(SourceLocation Loc, char op, ExprAST *lhs, ExprAST *rhs)
- : ExprAST(Loc), Op(op), LHS(lhs), RHS(rhs) {}
+ BinaryExprAST(SourceLocation Loc, char Op, std::unique_ptr<ExprAST> LHS,
+ std::unique_ptr<ExprAST> RHS)
+ : ExprAST(Loc), Op(Op), LHS(std::move(LHS)), RHS(std::move(RHS)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "binary" << Op, ind);
LHS->dump(indent(out, ind) << "LHS:", ind + 1);
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "binary" << Op, ind);
LHS->dump(indent(out, ind) << "LHS:", ind + 1);
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
/// CallExprAST - Expression class for function calls.
class CallExprAST : public ExprAST {
std::string Callee;
- std::vector<ExprAST *> Args;
-
+ std::vector<std::unique_ptr<ExprAST>> Args;
- CallExprAST(SourceLocation Loc, const std::string &callee,
- std::vector<ExprAST *> &args)
- : ExprAST(Loc), Callee(callee), Args(args) {}
+ CallExprAST(SourceLocation Loc, const std::string &Callee,
+ std::vector<std::unique_ptr<ExprAST>> Args)
+ : ExprAST(Loc), Callee(Callee), Args(std::move(Args)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "call " << Callee, ind);
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "call " << Callee, ind);
- for (ExprAST *Arg : Args)
+ for (const auto &Arg : Args)
Arg->dump(indent(out, ind + 1), ind + 1);
return out;
}
Arg->dump(indent(out, ind + 1), ind + 1);
return out;
}
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
- ExprAST *Cond, *Then, *Else;
-
+ std::unique_ptr<ExprAST> Cond, Then, Else;
- IfExprAST(SourceLocation Loc, ExprAST *cond, ExprAST *then, ExprAST *_else)
- : ExprAST(Loc), Cond(cond), Then(then), Else(_else) {}
+ IfExprAST(SourceLocation Loc, std::unique_ptr<ExprAST> Cond,
+ std::unique_ptr<ExprAST> Then, std::unique_ptr<ExprAST> Else)
+ : ExprAST(Loc), Cond(std::move(Cond)), Then(std::move(Then)), Else(std::move(Else)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "if", ind);
Cond->dump(indent(out, ind) << "Cond:", ind + 1);
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "if", ind);
Cond->dump(indent(out, ind) << "Cond:", ind + 1);
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
/// ForExprAST - Expression class for for/in.
class ForExprAST : public ExprAST {
std::string VarName;
- ExprAST *Start, *End, *Step, *Body;
-
+ std::unique_ptr<ExprAST> Start, End, Step, Body;
- ForExprAST(const std::string &varname, ExprAST *start, ExprAST *end,
- ExprAST *step, ExprAST *body)
- : VarName(varname), Start(start), End(end), Step(step), Body(body) {}
+ ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
+ std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
+ std::unique_ptr<ExprAST> Body)
+ : VarName(VarName), Start(std::move(Start)), End(std::move(End)),
+ Step(std::move(Step)), Body(std::move(Body)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "for", ind);
Start->dump(indent(out, ind) << "Cond:", ind + 1);
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "for", ind);
Start->dump(indent(out, ind) << "Cond:", ind + 1);
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
/// VarExprAST - Expression class for var/in
class VarExprAST : public ExprAST {
- std::vector<std::pair<std::string, ExprAST *> > VarNames;
- ExprAST *Body;
-
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
+ std::unique_ptr<ExprAST> Body;
- VarExprAST(const std::vector<std::pair<std::string, ExprAST *> > &varnames,
- ExprAST *body)
- : VarNames(varnames), Body(body) {}
-
+ VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "var", ind);
for (const auto &NamedVar : VarNames)
std::ostream &dump(std::ostream &out, int ind) override {
ExprAST::dump(out << "var", ind);
for (const auto &NamedVar : VarNames)
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
unsigned Precedence; // Precedence if a binary op.
int Line;
unsigned Precedence; // Precedence if a binary op.
int Line;
- PrototypeAST(SourceLocation Loc, const std::string &name,
- const std::vector<std::string> &args, bool isoperator = false,
- unsigned prec = 0)
- : Name(name), Args(args), isOperator(isoperator), Precedence(prec),
- Line(Loc.Line) {}
+ PrototypeAST(SourceLocation Loc, const std::string &Name,
+ std::vector<std::string> Args, bool IsOperator = false,
+ unsigned Prec = 0)
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec), Line(Loc.Line) {}
- bool isUnaryOp() const { return isOperator && Args.size() == 1; }
- bool isBinaryOp() const { return isOperator && Args.size() == 2; }
+ bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
+ bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
char getOperatorName() const {
assert(isUnaryOp() || isBinaryOp());
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
/// FunctionAST - This class represents a function definition itself.
class FunctionAST {
- PrototypeAST *Proto;
- ExprAST *Body;
-
+ std::unique_ptr<PrototypeAST> Proto;
+ std::unique_ptr<ExprAST> Body;
- FunctionAST(PrototypeAST *proto, ExprAST *body) : Proto(proto), Body(body) {}
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
+ : Proto(std::move(Proto)), Body(std::move(Body)) {}
std::ostream &dump(std::ostream &out, int ind) {
indent(out, ind) << "FunctionAST\n";
std::ostream &dump(std::ostream &out, int ind) {
indent(out, ind) << "FunctionAST\n";
}
/// 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);
-PrototypeAST *ErrorP(const char *Str) {
+std::unique_ptr<PrototypeAST> ErrorP(const char *Str) {
-FunctionAST *ErrorF(const char *Str) {
+std::unique_ptr<FunctionAST> ErrorF(const char *Str) {
-static ExprAST *ParseExpression();
+static std::unique_ptr<ExprAST> ParseExpression();
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
-static ExprAST *ParseIdentifierExpr() {
+ static std::unique_ptr<ExprAST> ParseIdentifierExpr() {
std::string IdName = IdentifierStr;
SourceLocation LitLoc = CurLoc;
std::string IdName = IdentifierStr;
SourceLocation LitLoc = CurLoc;
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
getNextToken(); // eat identifier.
if (CurTok != '(') // Simple variable ref.
- return new VariableExprAST(LitLoc, IdName);
+ return llvm::make_unique<VariableExprAST>(LitLoc, IdName);
// Call.
getNextToken(); // eat (
// Call.
getNextToken(); // eat (
- std::vector<ExprAST *> Args;
+ std::vector<std::unique_ptr<ExprAST>> Args;
if (CurTok != ')') {
while (1) {
if (CurTok != ')') {
while (1) {
- ExprAST *Arg = ParseExpression();
+ auto Arg = ParseExpression();
- return 0;
- Args.push_back(Arg);
+ return nullptr;
+ Args.push_back(std::move(Arg));
if (CurTok == ')')
break;
if (CurTok == ')')
break;
// Eat the ')'.
getNextToken();
// Eat the ')'.
getNextToken();
- return new CallExprAST(LitLoc, IdName, Args);
+ return llvm::make_unique<CallExprAST>(LitLoc, IdName, std::move(Args));
}
/// numberexpr ::= number
}
/// numberexpr ::= number
-static ExprAST *ParseNumberExpr() {
- ExprAST *Result = new NumberExprAST(NumVal);
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
getNextToken(); // consume the number
getNextToken(); // consume the number
+ 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 (CurTok != ')')
return Error("expected ')'");
if (CurTok != ')')
return Error("expected ')'");
}
/// 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;
getNextToken(); // eat the if.
// condition.
SourceLocation IfLoc = CurLoc;
getNextToken(); // eat the if.
// condition.
- ExprAST *Cond = ParseExpression();
+ auto Cond = ParseExpression();
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
if (CurTok != tok_then)
return Error("expected then");
getNextToken(); // eat the then
- ExprAST *Then = ParseExpression();
- if (Then == 0)
- return 0;
+ auto Then = ParseExpression();
+ if (!Then)
+ return nullptr;
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
if (CurTok != tok_else)
return Error("expected else");
getNextToken();
- ExprAST *Else = ParseExpression();
+ auto Else = ParseExpression();
- 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.
if (CurTok != tok_identifier)
getNextToken(); // eat the for.
if (CurTok != tok_identifier)
return Error("expected '=' after for");
getNextToken(); // eat '='.
return Error("expected '=' after for");
getNextToken(); // eat '='.
- ExprAST *Start = ParseExpression();
- if (Start == 0)
- return 0;
+ auto Start = ParseExpression();
+ if (!Start)
+ return nullptr;
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
if (CurTok != ',')
return Error("expected ',' after for start value");
getNextToken();
- ExprAST *End = ParseExpression();
- if (End == 0)
- return 0;
+ auto End = ParseExpression();
+ if (!End)
+ return nullptr;
// The step value is optional.
// The step value is optional.
+ std::unique_ptr<ExprAST> Step;
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
if (CurTok == ',') {
getNextToken();
Step = ParseExpression();
- if (Step == 0)
- return 0;
+ if (!Step)
+ return nullptr;
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
}
if (CurTok != tok_in)
return Error("expected 'in' after for");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new ForExprAST(IdName, Start, End, Step, Body);
+ return llvm::make_unique<ForExprAST>(IdName, std::move(Start), std::move(End),
+ std::move(Step), std::move(Body));
}
/// varexpr ::= 'var' identifier ('=' expression)?
// (',' identifier ('=' expression)?)* 'in' expression
}
/// varexpr ::= 'var' identifier ('=' 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.
if (CurTok != tok_identifier)
// At least one variable name is required.
if (CurTok != tok_identifier)
getNextToken(); // eat identifier.
// Read the optional initializer.
getNextToken(); // eat identifier.
// Read the optional initializer.
+ std::unique_ptr<ExprAST> Init = nullptr;
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
if (CurTok == '=') {
getNextToken(); // eat the '='.
Init = ParseExpression();
- if (Init == 0)
- return 0;
+ if (!Init)
+ return nullptr;
- VarNames.push_back(std::make_pair(Name, Init));
+ VarNames.push_back(std::make_pair(Name, std::move(Init)));
// End of var list, exit loop.
if (CurTok != ',')
// End of var list, exit loop.
if (CurTok != ',')
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
return Error("expected 'in' keyword after 'var'");
getNextToken(); // eat 'in'.
- ExprAST *Body = ParseExpression();
- if (Body == 0)
- return 0;
+ auto Body = ParseExpression();
+ if (!Body)
+ return nullptr;
- return new VarExprAST(VarNames, Body);
+ return llvm::make_unique<VarExprAST>(std::move(VarNames), std::move(Body));
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
/// ::= ifexpr
/// ::= forexpr
/// ::= varexpr
-static ExprAST *ParsePrimary() {
+static std::unique_ptr<ExprAST> ParsePrimary() {
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
switch (CurTok) {
default:
return Error("unknown token when expecting an expression");
/// unary
/// ::= primary
/// ::= '!' unary
/// unary
/// ::= primary
/// ::= '!' unary
-static ExprAST *ParseUnary() {
+static std::unique_ptr<ExprAST> ParseUnary() {
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If the current token is not an operator, it must be a primary expr.
if (!isascii(CurTok) || CurTok == '(' || CurTok == ',')
return ParsePrimary();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
// If this is a unary operator, read it.
int Opc = CurTok;
getNextToken();
- if (ExprAST *Operand = ParseUnary())
- return new UnaryExprAST(Opc, Operand);
- return 0;
+ if (auto Operand = ParseUnary())
+ return llvm::make_unique<UnaryExprAST>(Opc, std::move(Operand));
+ return nullptr;
}
/// binoprhs
/// ::= ('+' unary)*
}
/// binoprhs
/// ::= ('+' unary)*
-static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
getNextToken(); // eat binop
// Parse the unary expression after the binary operator.
- ExprAST *RHS = ParseUnary();
+ auto RHS = ParseUnary();
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
// If BinOp binds less tightly with RHS than the operator after RHS, let
// the pending operator take RHS as its LHS.
int NextPrec = GetTokPrecedence();
if (TokPrec < NextPrec) {
- RHS = ParseBinOpRHS(TokPrec + 1, RHS);
- if (RHS == 0)
- return 0;
+ RHS = ParseBinOpRHS(TokPrec + 1, std::move(RHS));
+ if (!RHS)
+ return nullptr;
- LHS = new BinaryExprAST(BinLoc, BinOp, LHS, RHS);
+ LHS = llvm::make_unique<BinaryExprAST>(BinLoc, BinOp, std::move(LHS),
+ std::move(RHS));
}
}
/// expression
/// ::= unary binoprhs
///
}
}
/// expression
/// ::= unary binoprhs
///
-static ExprAST *ParseExpression() {
- ExprAST *LHS = ParseUnary();
+static std::unique_ptr<ExprAST> ParseExpression() {
+ auto LHS = ParseUnary();
- return ParseBinOpRHS(0, LHS);
+ return ParseBinOpRHS(0, std::move(LHS));
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
}
/// prototype
/// ::= id '(' id* ')'
/// ::= binary LETTER number? (id, id)
/// ::= unary LETTER (id)
-static PrototypeAST *ParsePrototype() {
+static std::unique_ptr<PrototypeAST> ParsePrototype() {
std::string FnName;
SourceLocation FnLoc = CurLoc;
std::string FnName;
SourceLocation FnLoc = CurLoc;
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
if (Kind && ArgNames.size() != Kind)
return ErrorP("Invalid number of operands for operator");
- return 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();
- if (Proto == 0)
- return 0;
+ auto Proto = ParsePrototype();
+ if (!Proto)
+ return nullptr;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
+ if (auto E = ParseExpression())
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
+ return nullptr;
}
/// toplevelexpr ::= expression
}
/// 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 =
- new PrototypeAST(FnLoc, "main", std::vector<std::string>());
- return new FunctionAST(Proto, E);
+ auto Proto =
+ llvm::make_unique<PrototypeAST>(FnLoc, "main", std::vector<std::string>());
+ return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
/// external ::= 'extern' prototype
}
/// external ::= 'extern' prototype
-static PrototypeAST *ParseExtern() {
+static std::unique_ptr<PrototypeAST> ParseExtern() {
getNextToken(); // eat extern.
return ParsePrototype();
}
getNextToken(); // eat extern.
return ParsePrototype();
}
Value *ErrorV(const char *Str) {
Error(Str);
Value *ErrorV(const char *Str) {
Error(Str);
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
}
/// CreateEntryBlockAlloca - Create an alloca instruction in the entry block of
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
Value *VariableExprAST::Codegen() {
// Look this variable up in the function.
Value *V = NamedValues[Name];
return ErrorV("Unknown variable name");
KSDbgInfo.emitLocation(this);
return ErrorV("Unknown variable name");
KSDbgInfo.emitLocation(this);
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
Value *UnaryExprAST::Codegen() {
Value *OperandV = Operand->Codegen();
- if (OperandV == 0)
- return 0;
+ if (!OperandV)
+ return nullptr;
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
Function *F = TheModule->getFunction(std::string("unary") + Opcode);
return ErrorV("Unknown unary operator");
KSDbgInfo.emitLocation(this);
return ErrorV("Unknown unary operator");
KSDbgInfo.emitLocation(this);
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
- VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS);
+ VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Value *Val = RHS->Codegen();
- if (Val == 0)
- return 0;
+ if (!Val)
+ return nullptr;
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
// Look up the name.
Value *Variable = NamedValues[LHSE->getName()];
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
return ErrorV("Unknown variable name");
Builder.CreateStore(Val, Variable);
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
Value *L = LHS->Codegen();
Value *R = RHS->Codegen();
- if (L == 0 || R == 0)
- return 0;
+ if (!L || !R)
+ return nullptr;
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
// Look up the name in the global module table.
Function *CalleeF = TheModule->getFunction(Callee);
return ErrorV("Unknown function referenced");
// If argument mismatch error.
return ErrorV("Unknown function referenced");
// If argument mismatch error.
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
std::vector<Value *> ArgsV;
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
ArgsV.push_back(Args[i]->Codegen());
- if (ArgsV.back() == 0)
- return 0;
+ if (!ArgsV.back())
+ return nullptr;
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
}
return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
KSDbgInfo.emitLocation(this);
Value *CondV = Cond->Codegen();
KSDbgInfo.emitLocation(this);
Value *CondV = Cond->Codegen();
- if (CondV == 0)
- return 0;
+ if (!CondV)
+ return nullptr;
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
// Convert condition to a bool by comparing equal to 0.0.
CondV = Builder.CreateFCmpONE(
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
Builder.SetInsertPoint(ThenBB);
Value *ThenV = Then->Codegen();
- if (ThenV == 0)
- return 0;
+ if (!ThenV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Then' can change the current block, update ThenBB for the PHI.
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
Builder.SetInsertPoint(ElseBB);
Value *ElseV = Else->Codegen();
- if (ElseV == 0)
- return 0;
+ if (!ElseV)
+ return nullptr;
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
Builder.CreateBr(MergeBB);
// Codegen of 'Else' can change the current block, update ElseBB for the PHI.
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
// Emit the start code first, without 'variable' in scope.
Value *StartVal = Start->Codegen();
- if (StartVal == 0)
- return 0;
+ if (!StartVal)
+ return nullptr;
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Store the value into the alloca.
Builder.CreateStore(StartVal, Alloca);
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
// Emit the body of the loop. This, like any other expr, can change the
// current BB. Note that we ignore the value computed by the body, but don't
// allow an error.
- if (Body->Codegen() == 0)
- return 0;
+ if (!Body->Codegen())
+ return nullptr;
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
// Emit the step value.
Value *StepVal;
if (Step) {
StepVal = Step->Codegen();
- if (StepVal == 0)
- return 0;
+ if (!StepVal)
+ return nullptr;
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
} else {
// If not specified, use 1.0.
StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
// Compute the end condition.
Value *EndCond = End->Codegen();
// Compute the end condition.
Value *EndCond = End->Codegen();
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
return EndCond;
// Reload, increment, and restore the alloca. This handles the case where
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
// Register all variables and emit their initializer.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i) {
const std::string &VarName = VarNames[i].first;
- ExprAST *Init = VarNames[i].second;
+ ExprAST *Init = VarNames[i].second.get();
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
// Emit the initializer before adding the variable to scope, this prevents
// the initializer from referencing the variable itself, and permits stuff
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
Value *InitVal;
if (Init) {
InitVal = Init->Codegen();
- if (InitVal == 0)
- return 0;
+ if (!InitVal)
+ return nullptr;
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
} else { // If not specified, use 0.0.
InitVal = ConstantFP::get(getGlobalContext(), APFloat(0.0));
}
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
// Codegen the body, now that all vars are in scope.
Value *BodyVal = Body->Codegen();
- if (BodyVal == 0)
- return 0;
+ if (!BodyVal)
+ return nullptr;
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
// Pop all our variables from scope.
for (unsigned i = 0, e = VarNames.size(); i != e; ++i)
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
// If F already has a body, reject this.
if (!F->empty()) {
ErrorF("redefinition of function");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
}
// If F took a different number of args, reject.
if (F->arg_size() != Args.size()) {
ErrorF("redefinition of function with different # args");
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
NamedValues.clear();
Function *TheFunction = Proto->Codegen();
- if (TheFunction == 0)
- return 0;
+ if (!TheFunction)
+ 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
// location in a function are considered part of the prologue and the debugger
// Unset the location for the prologue emission (leading instructions with no
// location in a function are considered part of the prologue and the debugger
// Add all arguments to the symbol table and create their allocas.
Proto->CreateArgumentAllocas(TheFunction);
// Add all arguments to the symbol table and create their allocas.
Proto->CreateArgumentAllocas(TheFunction);
- KSDbgInfo.emitLocation(Body);
+ KSDbgInfo.emitLocation(Body.get());
if (Value *RetVal = Body->Codegen()) {
// Finish off the function.
if (Value *RetVal = Body->Codegen()) {
// Finish off the function.
// unconditionally.
KSDbgInfo.LexicalBlocks.pop_back();
// unconditionally.
KSDbgInfo.LexicalBlocks.pop_back();
}
//===----------------------------------------------------------------------===//
}
//===----------------------------------------------------------------------===//
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
static ExecutionEngine *TheExecutionEngine;
static void HandleDefinition() {
- if (FunctionAST *F = ParseDefinition()) {
- if (!F->Codegen()) {
+ if (auto FnAST = ParseDefinition()) {
+ if (!FnAST->Codegen()) {
fprintf(stderr, "Error reading function definition:");
}
} else {
fprintf(stderr, "Error reading function definition:");
}
} else {
}
static void HandleExtern() {
}
static void HandleExtern() {
- if (PrototypeAST *P = ParseExtern()) {
- if (!P->Codegen()) {
+ if (auto ProtoAST = ParseExtern()) {
+ if (!ProtoAST->Codegen()) {
fprintf(stderr, "Error reading extern");
}
} else {
fprintf(stderr, "Error reading extern");
}
} else {
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
static void HandleTopLevelExpression() {
// Evaluate a top-level expression into an anonymous function.
- if (FunctionAST *F = ParseTopLevelExpr()) {
- if (!F->Codegen()) {
+ if (auto FnAST = ParseTopLevelExpr()) {
+ if (!FnAST->Codegen()) {
fprintf(stderr, "Error generating code for top level expr");
}
} else {
fprintf(stderr, "Error generating code for top level expr");
}
} else {