CodegenVisitor.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include "CodegenVisitor.h"
  2. #include "CodeGeneration.h"
  3. #include "Type.h"
  4. #include <llvm/IR/Constants.h>
  5. #include <llvm/IR/IRBuilder.h>
  6. using namespace qlow;
  7. std::pair<llvm::Value*, sem::Type*> ExpressionVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder)
  8. {
  9. assert(lve.var->allocaInst != nullptr);
  10. if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
  11. llvm::Value* val = builder.CreateLoad(lve.var->allocaInst);
  12. return { val, lve.var->type };
  13. }
  14. else {
  15. return { lve.var->allocaInst, lve.var->type };
  16. }
  17. }
  18. std::pair<llvm::Value*, sem::Type*> ExpressionVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder)
  19. {
  20. using llvm::Value;
  21. using sem::Type;
  22. auto [left, leftType] = binop.left->accept(*this, builder);
  23. auto [right, rightType] = binop.right->accept(*this, builder);
  24. if (!leftType->equals(Type::INTEGER) || !rightType->equals(Type::INTEGER))
  25. throw "invalid types in BinaryOperation";
  26. if (left == nullptr) {
  27. printf("WOW: %s\n", binop.left->toString().c_str());
  28. }
  29. // TODO insert type checks
  30. switch (binop.op) {
  31. case ast::Operation::Operator::PLUS:
  32. return { builder.CreateAdd(left, right, "add"), Type::INTEGER };
  33. case ast::Operation::Operator::MINUS:
  34. return { builder.CreateSub(left, right, "sub"), Type::INTEGER };
  35. case ast::Operation::Operator::ASTERISK:
  36. return { builder.CreateMul(left, right, "mul"), Type::INTEGER };
  37. case ast::Operation::Operator::SLASH:
  38. return { builder.CreateSDiv(left, right, "add"), Type::INTEGER };
  39. case ast::Operation::Operator::EQUALS:
  40. return { builder.CreateICmpEQ(left, right, "equals"), Type::BOOLEAN };
  41. case ast::Operation::Operator::AND:
  42. return { builder.CreateAnd(left, right, "and"), Type::BOOLEAN };
  43. case ast::Operation::Operator::OR:
  44. return { builder.CreateOr(left, right, "or"), Type::BOOLEAN };
  45. case ast::Operation::Operator::XOR:
  46. return { builder.CreateXor(left, right, "xor"), Type::BOOLEAN };
  47. }
  48. }
  49. std::pair<llvm::Value*, sem::Type*> ExpressionVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder)
  50. {
  51. using llvm::Value;
  52. auto [value, type] = unop.arg->accept(*this, builder);
  53. if (type != sem::Type::INTEGER)
  54. throw "invalid type to negate";
  55. switch (unop.op) {
  56. case ast::Operation::Operator::MINUS:
  57. return { builder.CreateNeg(value, "negate"), sem::Type::INTEGER };
  58. case ast::Operation::Operator::NOT:
  59. return { builder.CreateNot(value, "not"), sem::Type::BOOLEAN };
  60. default:
  61. throw "operator not supported";
  62. }
  63. }
  64. std::pair<llvm::Value*, sem::Type*> ExpressionVisitor::visit(sem::FeatureCallExpression& call, llvm::IRBuilder<>& builder)
  65. {
  66. using llvm::Value;
  67. std::vector<Value*> arguments;
  68. if (call.arguments.size() != call.callee->arguments.size()) {
  69. throw "wrong number of arguments";
  70. }
  71. for (size_t i = 0; i < call.arguments.size(); i++) {
  72. // : call.arguments) {
  73. auto& arg = call.arguments[i];
  74. auto [value, type] = arg->accept(*this, builder);
  75. if (!type->equals(call.callee->arguments[i]->type)) {
  76. throw "argument type mismatch";
  77. }
  78. arguments.push_back(value);
  79. }
  80. auto returnType = call.callee->returnType;
  81. llvm::CallInst* callInst = builder.CreateCall(call.callee->llvmNode, arguments);
  82. return { callInst, returnType };
  83. //return { nullptr, sem::Type::NULL_TYPE };
  84. }
  85. std::pair<llvm::Value*, sem::Type*> ExpressionVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
  86. {
  87. return {
  88. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, std::to_string(node.value), 10)),
  89. sem::Type::INTEGER
  90. };
  91. }
  92. llvm::Value* StatementVisitor::visit(sem::DoEndBlock& assignment,
  93. qlow::gen::FunctionGenerator& fg)
  94. {
  95. for (auto& statement : assignment.statements) {
  96. statement->accept(*this, fg);
  97. }
  98. return nullptr;
  99. }
  100. llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
  101. qlow::gen::FunctionGenerator& fg)
  102. {
  103. using llvm::Value;
  104. using llvm::BasicBlock;
  105. llvm::IRBuilder<> builder(fg.getContext());
  106. builder.SetInsertPoint(fg.getCurrentBlock());
  107. auto [condition, condType] = ifElseBlock.condition->accept(fg.expressionVisitor, builder);
  108. llvm::Function* function = fg.getCurrentBlock()->getParent();
  109. BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
  110. BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else", function);
  111. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  112. Value* boolCond = builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  113. builder.CreateCondBr(boolCond, thenB, elseB);
  114. fg.pushBlock(thenB);
  115. ifElseBlock.ifBlock->accept(*this, fg);
  116. builder.SetInsertPoint(thenB);
  117. builder.CreateBr(merge);
  118. fg.popBlock();
  119. fg.pushBlock(elseB);
  120. ifElseBlock.elseBlock->accept(*this, fg);
  121. builder.SetInsertPoint(elseB);
  122. builder.CreateBr(merge);
  123. fg.popBlock();
  124. fg.popBlock();
  125. fg.pushBlock(merge);
  126. }
  127. llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
  128. qlow::gen::FunctionGenerator& fg)
  129. {
  130. llvm::IRBuilder<> builder(fg.getContext());
  131. builder.SetInsertPoint(fg.getCurrentBlock());
  132. auto [val, type] = assignment.value->accept(fg.expressionVisitor, builder);
  133. if (auto* targetVar =
  134. dynamic_cast<sem::LocalVariableExpression*>(assignment.target.get()); targetVar) {
  135. builder.CreateStore(val, targetVar->var->allocaInst);
  136. }
  137. else
  138. throw "only local variables are assignable at the moment";
  139. return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5123.0));
  140. }
  141. llvm::Value* StatementVisitor::visit(sem::ReturnStatement& returnStatement,
  142. qlow::gen::FunctionGenerator& fg)
  143. {
  144. llvm::IRBuilder<> builder(fg.getContext());
  145. builder.SetInsertPoint(fg.getCurrentBlock());
  146. auto [val, type] = returnStatement.value->accept(fg.expressionVisitor, builder);
  147. builder.CreateRet(val);
  148. return val;
  149. }
  150. llvm::Value* StatementVisitor::visit(sem::FeatureCallStatement& fc, gen::FunctionGenerator& fg)
  151. {
  152. llvm::Module* module = fg.getModule();
  153. llvm::IRBuilder<> builder(fg.getContext());
  154. builder.SetInsertPoint(fg.getCurrentBlock());
  155. //llvm::Constant* c = module->getOrInsertFunction(fc.expr->callee->name, {});
  156. llvm::Function* f = fc.expr->callee->llvmNode;
  157. builder.CreateCall(f, {});
  158. return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5.0));
  159. }