/// NumberExprAST - Expression class for numeric literals like "1.0".
class NumberExprAST : public ExprAST {
double Val;
+
public:
NumberExprAST(double Val) : Val(Val) {}
Value *Codegen() override;
/// VariableExprAST - Expression class for referencing a variable, like "a".
class VariableExprAST : public ExprAST {
std::string Name;
+
public:
VariableExprAST(const std::string &Name) : Name(Name) {}
const std::string &getName() const { return Name; }
class UnaryExprAST : public ExprAST {
char Opcode;
std::unique_ptr<ExprAST> Operand;
+
public:
UnaryExprAST(char Opcode, std::unique_ptr<ExprAST> Operand)
: Opcode(Opcode), Operand(std::move(Operand)) {}
class BinaryExprAST : public ExprAST {
char Op;
std::unique_ptr<ExprAST> LHS, RHS;
+
public:
BinaryExprAST(char Op, std::unique_ptr<ExprAST> LHS,
std::unique_ptr<ExprAST> RHS)
class CallExprAST : public ExprAST {
std::string Callee;
std::vector<std::unique_ptr<ExprAST>> Args;
+
public:
CallExprAST(const std::string &Callee,
std::vector<std::unique_ptr<ExprAST>> Args)
/// IfExprAST - Expression class for if/then/else.
class IfExprAST : public ExprAST {
std::unique_ptr<ExprAST> Cond, Then, Else;
+
public:
IfExprAST(std::unique_ptr<ExprAST> Cond, std::unique_ptr<ExprAST> Then,
std::unique_ptr<ExprAST> Else)
class ForExprAST : public ExprAST {
std::string VarName;
std::unique_ptr<ExprAST> Start, End, Step, Body;
+
public:
ForExprAST(const std::string &VarName, std::unique_ptr<ExprAST> Start,
std::unique_ptr<ExprAST> End, std::unique_ptr<ExprAST> Step,
class VarExprAST : public ExprAST {
std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames;
std::unique_ptr<ExprAST> Body;
+
public:
- VarExprAST(std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
- std::unique_ptr<ExprAST> Body)
- : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
+ VarExprAST(
+ std::vector<std::pair<std::string, std::unique_ptr<ExprAST>>> VarNames,
+ std::unique_ptr<ExprAST> Body)
+ : VarNames(std::move(VarNames)), Body(std::move(Body)) {}
Value *Codegen() override;
};
/// PrototypeAST - This class represents the "prototype" for a function,
-/// which captures its argument names as well as if it is an operator.
+/// which captures its name, and its argument names (thus implicitly the number
+/// of arguments the function takes), as well as if it is an operator.
class PrototypeAST {
std::string Name;
std::vector<std::string> Args;
bool IsOperator;
unsigned Precedence; // Precedence if a binary op.
+
public:
PrototypeAST(const std::string &Name, std::vector<std::string> Args,
bool IsOperator = false, unsigned Prec = 0)
- : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
- Precedence(Prec) {}
+ : Name(Name), Args(std::move(Args)), IsOperator(IsOperator),
+ Precedence(Prec) {}
bool isUnaryOp() const { return IsOperator && Args.size() == 1; }
bool isBinaryOp() const { return IsOperator && Args.size() == 2; }
class FunctionAST {
std::unique_ptr<PrototypeAST> Proto;
std::unique_ptr<ExprAST> Body;
+
public:
- FunctionAST(std::unique_ptr<PrototypeAST> Proto, std::unique_ptr<ExprAST> Body)
+ FunctionAST(std::unique_ptr<PrototypeAST> Proto,
+ std::unique_ptr<ExprAST> Body)
: Proto(std::move(Proto)), Body(std::move(Body)) {}
Function *Codegen();
};
static std::unique_ptr<ExprAST> ParseExpression();
+/// numberexpr ::= number
+static std::unique_ptr<ExprAST> ParseNumberExpr() {
+ auto Result = llvm::make_unique<NumberExprAST>(NumVal);
+ getNextToken(); // consume the number
+ return std::move(Result);
+}
+
+/// parenexpr ::= '(' expression ')'
+static std::unique_ptr<ExprAST> ParseParenExpr() {
+ getNextToken(); // eat (.
+ auto V = ParseExpression();
+ if (!V)
+ return nullptr;
+
+ if (CurTok != ')')
+ return Error("expected ')'");
+ getNextToken(); // eat ).
+ return V;
+}
+
/// identifierexpr
/// ::= identifier
/// ::= identifier '(' expression* ')'
return llvm::make_unique<CallExprAST>(IdName, std::move(Args));
}
-/// numberexpr ::= number
-static std::unique_ptr<ExprAST> ParseNumberExpr() {
- auto Result = llvm::make_unique<NumberExprAST>(NumVal);
- getNextToken(); // consume the number
- return std::move(Result);
-}
-
-/// parenexpr ::= '(' expression ')'
-static std::unique_ptr<ExprAST> ParseParenExpr() {
- getNextToken(); // eat (.
- auto V = ParseExpression();
- if (!V)
- return nullptr;
-
- if (CurTok != ')')
- return Error("expected ')'");
- getNextToken(); // eat ).
- return V;
-}
-
/// ifexpr ::= 'if' expression 'then' expression 'else' expression
static std::unique_ptr<ExprAST> ParseIfExpr() {
getNextToken(); // eat the if.
/// binoprhs
/// ::= ('+' unary)*
- static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec, std::unique_ptr<ExprAST> LHS) {
+static std::unique_ptr<ExprAST> ParseBinOpRHS(int ExprPrec,
+ std::unique_ptr<ExprAST> LHS) {
// If this is a binop, find its precedence.
while (1) {
int TokPrec = GetTokPrecedence();
}
// Merge LHS/RHS.
- LHS = llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
+ LHS =
+ llvm::make_unique<BinaryExprAST>(BinOp, std::move(LHS), std::move(RHS));
}
}
static std::unique_ptr<FunctionAST> ParseTopLevelExpr() {
if (auto E = ParseExpression()) {
// Make an anonymous proto.
- auto Proto = llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
+ auto Proto =
+ llvm::make_unique<PrototypeAST>("", std::vector<std::string>());
return llvm::make_unique<FunctionAST>(std::move(Proto), std::move(E));
}
return nullptr;
// This assume we're building without RTTI because LLVM builds that way by
// default. If you build LLVM with RTTI this can be changed to a
// dynamic_cast for automatic error checking.
- VariableExprAST *LHSE = static_cast<VariableExprAST*>(LHS.get());
+ VariableExprAST *LHSE = static_cast<VariableExprAST *>(LHS.get());
if (!LHSE)
return ErrorV("destination of '=' must be a variable");
// Codegen the RHS.
Function *F = TheModule->getFunction(std::string("binary") + Op);
assert(F && "binary operator not found!");
- Value *Ops[] = { L, R };
+ Value *Ops[] = {L, R};
return Builder.CreateCall(F, Ops, "binop");
}
return PN;
}
+// Output for-loop as:
+// var = alloca double
+// ...
+// start = startexpr
+// store start -> var
+// goto loop
+// loop:
+// ...
+// bodyexpr
+// ...
+// loopend:
+// step = stepexpr
+// endcond = endexpr
+//
+// curvar = load var
+// nextvar = curvar + step
+// store nextvar -> var
+// br endcond, loop, endloop
+// outloop:
Value *ForExprAST::Codegen() {
- // Output this as:
- // var = alloca double
- // ...
- // start = startexpr
- // store start -> var
- // goto loop
- // loop:
- // ...
- // bodyexpr
- // ...
- // loopend:
- // step = stepexpr
- // endcond = endexpr
- //
- // curvar = load var
- // nextvar = curvar + step
- // store nextvar -> var
- // br endcond, loop, endloop
- // outloop:
-
Function *TheFunction = Builder.GetInsertBlock()->getParent();
// Create an alloca for the variable in the entry block.
return nullptr;
// Emit the step value.
- Value *StepVal;
+ Value *StepVal = nullptr;
if (Step) {
StepVal = Step->Codegen();
if (!StepVal)
// Compute the end condition.
Value *EndCond = End->Codegen();
if (!EndCond)
- return EndCond;
+ return nullptr;
// Reload, increment, and restore the alloca. This handles the case where
// the body of the loop mutates the variable.
switch (CurTok) {
case tok_eof:
return;
- case ';':
+ case ';': // ignore top-level semicolons.
getNextToken();
- break; // ignore top-level semicolons.
+ break;
case tok_def:
HandleDefinition();
break;