Value *BinaryExprAST::Codegen() { KSDbgInfo.emitLocation(this); // Special case '=' because we don't want to emit the LHS as an expression. if (Op == '=') { // Assignment requires the LHS to be an identifier. // 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); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. Value *Val = RHS->Codegen(); if (Val == 0) return 0; // Look up the name. Value *Variable = NamedValues[LHSE->getName()]; if (Variable == 0) return ErrorV("Unknown variable name"); Builder.CreateStore(Val, Variable); return Val; } Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); if (L == 0 || R == 0) return 0; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); default: break; } // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. Function *F = TheModule->getFunction(std::string("binary") + Op); assert(F && "binary operator not found!"); Value *Ops[] = { L, R }; return Builder.CreateCall(F, Ops, "binop"); }
Value *Codegen::Generate(BinaryExprAST *expr) { using namespace boost; // treat assignment separately if (expr->GetOp() == '=') { VariableExprAST *identifier = dynamic_cast<VariableExprAST*>(expr->GetLHS()); if ( !identifier) return BaseError::Throw<Value*>("Left hand of assignment must be a variable"); Value *val = this->Generate(expr->GetRHS()); if ( !val) return BaseError::Throw<Value*>("Invalid assignment value to variable"); Value *variable = NamedValues[identifier->GetName()]; if ( !variable) return BaseError::Throw<Value*>("Unknown variable, cannot assign"); Builder.CreateStore(val, variable); return val; } Value *L = this->Generate(expr->GetLHS()); Value *R = this->Generate(expr->GetRHS()); if (L == 0 || R == 0) return 0; switch (expr->GetOp()) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '/': return Builder.CreateFDiv(L, R, "divtmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); default: break; } Function *opFunc = TheModule->getFunction("binary" + expr->GetOp()); if ( !opFunc) return BaseError::Throw<Value*>(str(format("Unknown binary operator '%1%'") % expr->GetOp())); Value *args[2] = { L, R }; return Builder.CreateCall(opFunc, args, "binop"); }
Value *BinaryExprAST::Codegen() { // 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 = static_cast<VariableExprAST*>(LHS); if (!LHSE) return ErrorV("destination of '=' must be a variable"); // Codegen the RHS. Value *Val = RHS->Codegen(); if (Val == 0) return 0; // Look up the name. Value *Variable = NamedValues[LHSE->getName()]; if (Variable == 0) return ErrorV("Unknown variable name"); Builder.CreateStore(Val, Variable); return Val; } Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); if (L == 0 || R == 0) return 0; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '/': return Builder.CreateFDiv(L, R, "divtmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); // Convert bool 0/1 to double 0.0 or 1.0 return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); default: break; } // If it wasn't a builtin binary operator, it must be a user defined one. Emit // a call to it. Function *F = TheHelper->getFunction(MakeLegalFunctionName(std::string("binary")+Op)); assert(F && "binary operator not found!"); Value *Ops[] = { L, R }; return Builder.CreateCall(F, Ops, "binop"); }
Value *BinaryExprAST::Codegen() { KSDbgInfo.emitLocation(this); if (Op == '=') { VariableExprAST *LHSE = dynamic_cast<VariableExprAST *>(LHS); if (!LHSE) return ErrorV("destination of '=' must be a variable"); Value *Val = RHS->Codegen(); if (!Val) return 0; Value *Variable = NamedValues[LHSE->getName()]; if (!Variable) return 0; Builder.CreateStore(Val, Variable); return Val; } Value *L = LHS->Codegen(); Value *R = RHS->Codegen(); if (L == 0 || R == 0) return 0; switch (Op) { case '+': return Builder.CreateFAdd(L, R, "addtmp"); case '-': return Builder.CreateFSub(L, R, "subtmp"); case '*': return Builder.CreateFMul(L, R, "multmp"); case '<': L = Builder.CreateFCmpULT(L, R, "cmptmp"); return Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()), "booltmp"); default: break; } // user defined operators Function *F = TheModule->getFunction(std::string("binary")+Op); assert(F && "binary operator not found!"); Value *Ops[2] = { L, R }; return Builder.CreateCall(F, Ops, "binop"); }