+
+Value *IfExprAST::codegen() {
+ Value *condV = Cond->codegen();
+ if (!condV) return nullptr;
+
+ //convert to bool
+ condV = Builder.CreateFCmpONE(condV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *func = Builder.GetInsertBlock()->getParent();
+
+ BasicBlock *thenBB = BasicBlock::Create(TheContext, "then", func);
+ BasicBlock *elseBB = BasicBlock::Create(TheContext, "else", func);
+ BasicBlock *mergeBB = BasicBlock::Create(TheContext, "merge", func);
+
+ Builder.CreateCondBr(condV, thenBB, elseBB);
+
+ Builder.SetInsertPoint(thenBB);
+
+ Value *thenV = Then->codegen();
+ if (!thenV) return nullptr;
+
+ Builder.CreateBr(mergeBB);
+
+ //codegen of then can change the current block, so get then again
+ thenBB = Builder.GetInsertBlock();
+
+ Builder.SetInsertPoint(elseBB);
+
+ Value *elseV = Else->codegen();
+ if (!elseV) return nullptr;
+
+ Builder.CreateBr(mergeBB);
+
+ //codegen of else can change the current block, so get else again
+ elseBB = Builder.GetInsertBlock();
+
+ Builder.SetInsertPoint(mergeBB);
+ PHINode *phiNode = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+ phiNode->addIncoming(thenV, thenBB);
+ phiNode->addIncoming(elseV, elseBB);
+
+ return phiNode;
+}
+
+Value *ForExprAST::codegen() {
+ auto *startValue = Start->codegen();
+ if (!startValue) return nullptr;
+
+ auto *func = Builder.GetInsertBlock()->getParent();
+ auto *preheaderBB = Builder.GetInsertBlock();
+ auto *loopBB = BasicBlock::Create(TheContext, "loop", func);
+
+ Builder.CreateBr(loopBB);
+
+ Builder.SetInsertPoint(loopBB);
+
+ auto *index = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName.c_str());
+ index->addIncoming(startValue, preheaderBB);
+
+ // if the index variable shadows an existing value, save it to restore later
+ auto *oldVal = NamedValues[VarName];
+ NamedValues[VarName] = index;
+
+ // emit the loop body
+ if (!Body->codegen()) return nullptr;
+
+ Value *stepVal = nullptr;
+ if (Step) {
+ stepVal = Step->codegen();
+ if (!stepVal) return nullptr;
+ } else {
+ stepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // increment the index
+ auto *nextVar = Builder.CreateFAdd(index, stepVal, "nextvar");
+
+ auto *endCond = End->codegen();
+ if (!endCond) return nullptr;
+
+ endCond = Builder.CreateFCmpONE(endCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ auto *loopEndBB = Builder.GetInsertBlock();
+ auto *afterBB = BasicBlock::Create(TheContext, "afterloop", func);
+
+ Builder.CreateCondBr(endCond, loopBB, afterBB);
+
+ Builder.SetInsertPoint(afterBB);
+
+ index->addIncoming(nextVar, loopEndBB);
+
+ // restore shadowed index variable
+ if (oldVal)
+ NamedValues[VarName] = oldVal;
+ else
+ NamedValues.erase(VarName);
+
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}