switch (CurTok) { case tok_identifier: returnParseIdentifierExpr(); case tok_number: returnParseNumberExpr(); case'(': returnParseParenExpr(); case tok_if: returnParseIfExpr(); default: returnLogError("unknown token when expecting an expression"); }
// convert condition to a bool by comparing non-equal to 0.0 CondV = Builder.CreateFCmpONE(CondV, llvm::ConstantFP::get(TheContext, llvm::APFloat(0.0)), "ifcond");
// Create blocks for the then and else // cases. Insert the 'then' block at the // end of the function llvm::BasicBlock *ThenBB = llvm::BasicBlock::Create(TheContext, "then", TheFunction); llvm::BasicBlock *ElseBB = llvm::BasicBlock::Create(TheContext, "else"); llvm::BasicBlock *MergeBB = llvm::BasicBlock::Create(TheContext, "ifcont"); Builder.CreateCondBr(CondV, ThenBB, ElseBB);
// Emit then Value Builder.SetInsertPoint(ThenBB); llvm::Value *ThenV = Then->codegen(); if (!ThenV) { returnnullptr; }
llvm::Value *ForExprAST::codegen(){ // Emit the start code first, without 'variable' in scope llvm::Value *StartVal = Start->codegen(); if (!StartVal) { returnnullptr; }
// Make the new basic block for the loop header, // inserting after current block llvm::Function *TheFunction = Builder.GetInsertBlock()->getParent(); llvm::BasicBlock *PreheaderBB = Builder.GetInsertBlock(); llvm::BasicBlock *LoopBB = llvm::BasicBlock::Create(TheContext, "loop", TheFunction);
// Inserting an explict fall-through from current (PreheaderBB) to LoopBB. Builder.CreateBr(LoopBB);
// Start insertion to LoopBB Builder.SetInsertPoint(LoopBB); // Start the PHI node with one Incoming basic block llvm::PHINode *Variable = Builder.CreatePHI(llvm::Type::getDoubleTy(TheContext), 2, VarName.c_str()); Variable->addIncoming(StartVal, PreheaderBB);
// Within the loop, the variable is defined equal to // the PHI node, If it shadows an existing variable, // we have to restore it, so save it now. llvm::Value *OldVal = NamedValues[VarName]; NamedValues[VarName] = Variable;
// 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()) { returnnullptr; }
// Emit the step value llvm::Value *StepVal = nullptr; if (Step) { StepVal = Step->codegen(); if (!StepVal) { returnnullptr; } } else { // if not specified, use 1.0 StepVal = llvm::ConstantFP::get(TheContext, llvm::APFloat(1.0)); }
// add the step value llvm::Value *NextVal = Builder.CreateFAdd(Variable, StepVal, "nextvar");
// Compute the end condition llvm::Value *EndCond = End->codegen(); if (!EndCond) { returnnullptr; }
// Convert condition to a bool by comparing non-equal to 0.0 EndCond = Builder.CreateFCmpONE(EndCond, llvm::ConstantFP::get(TheContext, llvm::APFloat(0.0)), "loopcond");
// Create the "after loop" block and insert it llvm::BasicBlock *LoopEndBB = Builder.GetInsertBlock(); llvm::BasicBlock *AfterBB = llvm::BasicBlock::Create(TheContext, "afterloop", TheFunction);
// Insert the conditional branch into the end of LoopEndBB Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
// Any new code will be inserted in AfterBB Builder.SetInsertPoint(AfterBB);
// Add a new entry to the PHI node for the backage Variable->addIncoming(NextVal, LoopEndBB);
// Restore the unshadowed variable if (OldVal) { NamedValues[VarName] = OldVal; } else { NamedValues.erase(VarName); }