Ast.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "Ast.h"
  2. using namespace ast;
  3. // attributes added from chapter 3 of the tutorial
  4. std::unique_ptr<Module> AstObjects::TheModule = make_unique<Module>("my cool jit", getGlobalContext());;
  5. IRBuilder<> AstObjects::Builder(getGlobalContext());
  6. std::map<std::string, Value *> AstObjects::NamedValues;
  7. // error method from chapter 3
  8. // HACK: duplicated function already present in example
  9. std::unique_ptr<ExprAST> Error_Ast(const char *Str) {
  10. fprintf(stderr, "Error: %s\n", Str);
  11. return nullptr;
  12. }
  13. Value *ErrorV(const char *Str) {
  14. Error_Ast(Str);
  15. return nullptr;
  16. }
  17. Value *NumberExprAST::codegen() {
  18. return ConstantFP::get(getGlobalContext(), APFloat(Val));
  19. }
  20. Value *VariableExprAST::codegen() {
  21. // Look this variable up in the function.
  22. Value *V = AstObjects::NamedValues[Name];
  23. if (!V)
  24. ErrorV("Unknown variable name");
  25. return V;
  26. }
  27. Value *BinaryExprAST::codegen() {
  28. Value *L = LHS->codegen();
  29. Value *R = RHS->codegen();
  30. if (!L || !R)
  31. return nullptr;
  32. switch (Op) {
  33. case '+':
  34. return AstObjects::Builder.CreateFAdd(L, R, "addtmp");
  35. case '-':
  36. return AstObjects::Builder.CreateFSub(L, R, "subtmp");
  37. case '*':
  38. return AstObjects::Builder.CreateFMul(L, R, "multmp");
  39. case '<':
  40. L = AstObjects::Builder.CreateFCmpULT(L, R, "cmptmp");
  41. // Convert bool 0/1 to double 0.0 or 1.0
  42. return AstObjects::Builder.CreateUIToFP(L, Type::getDoubleTy(getGlobalContext()),
  43. "booltmp");
  44. default:
  45. return ErrorV("invalid binary operator");
  46. }
  47. }
  48. Value *CallExprAST::codegen() {
  49. // Look up the name in the global module table.
  50. Function *CalleeF = AstObjects::TheModule->getFunction(Callee);
  51. if (!CalleeF)
  52. return ErrorV("Unknown function referenced");
  53. // If argument mismatch error.
  54. if (CalleeF->arg_size() != Args.size())
  55. return ErrorV("Incorrect # arguments passed");
  56. std::vector<Value *> ArgsV;
  57. for (unsigned i = 0, e = Args.size(); i != e; ++i) {
  58. ArgsV.push_back(Args[i]->codegen());
  59. if (!ArgsV.back())
  60. return nullptr;
  61. }
  62. return AstObjects::Builder.CreateCall(CalleeF, ArgsV, "calltmp");
  63. }
  64. Function *PrototypeAST::codegen() {
  65. // Make the function type: double(double,double) etc.
  66. std::vector<Type *> Doubles(Args.size(),
  67. Type::getDoubleTy(getGlobalContext()));
  68. FunctionType *FT =
  69. FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false);
  70. Function *F =
  71. Function::Create(FT, Function::ExternalLinkage, Name, AstObjects::TheModule.get());
  72. // Set names for all arguments.
  73. unsigned Idx = 0;
  74. for (auto &Arg : F->args())
  75. Arg.setName(Args[Idx++]);
  76. return F;
  77. }
  78. Function *FunctionAST::codegen() {
  79. // First, check for an existing function from a previous 'extern' declaration.
  80. Function *TheFunction = AstObjects::TheModule->getFunction(Proto->getName());
  81. if (!TheFunction)
  82. TheFunction = Proto->codegen();
  83. if (!TheFunction)
  84. return nullptr;
  85. if (!TheFunction->empty())
  86. return (Function*)ErrorV("Function cannot be redefined.");
  87. // Create a new basic block to start insertion into.
  88. BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
  89. AstObjects::Builder.SetInsertPoint(BB);
  90. // Record the function arguments in the NamedValues map.
  91. AstObjects::NamedValues.clear();
  92. for (auto &Arg : TheFunction->args())
  93. AstObjects::NamedValues[Arg.getName()] = &Arg;
  94. if (Value *RetVal = Body->codegen()) {
  95. // Finish off the function.
  96. AstObjects::Builder.CreateRet(RetVal);
  97. // Validate the generated code, checking for consistency.
  98. verifyFunction(*TheFunction);
  99. return TheFunction;
  100. }
  101. // Error reading body, remove function.
  102. TheFunction->eraseFromParent();
  103. return nullptr;
  104. }