CodegenVisitor.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include "CodegenVisitor.h"
  2. #include "CodeGeneration.h"
  3. #include "Type.h"
  4. #include "Builtin.h"
  5. #include "ErrorReporting.h"
  6. #include <llvm/IR/Constants.h>
  7. #include <llvm/IR/IRBuilder.h>
  8. using namespace qlow;
  9. llvm::Value* ExpressionCodegenVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder)
  10. {
  11. assert(lve.var->allocaInst != nullptr);
  12. if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
  13. llvm::Value* val = builder.CreateLoad(lve.var->allocaInst);
  14. return val;
  15. }
  16. else {
  17. return lve.var->allocaInst;
  18. }
  19. }
  20. llvm::Value* ExpressionCodegenVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder)
  21. {
  22. using llvm::Value;
  23. auto value = unop.arg->accept(*this, builder);
  24. auto& type = unop.arg->type;
  25. if (type->equals(sem::NativeType(sem::NativeType::Type::VOID)))
  26. throw "invalid type to negate";
  27. /*
  28. switch (unop.op) {
  29. case ast::Operation::Operator::MINUS:
  30. return builder.CreateNeg(value, "negate");
  31. case ast::Operation::Operator::NOT:
  32. return builder.CreateNot(value, "not");
  33. default:
  34. throw "operator not supported";
  35. }*/
  36. }
  37. llvm::Value* ExpressionCodegenVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder)
  38. {
  39. using llvm::Value;
  40. using sem::Type;
  41. auto left = binop.left->accept(*this, builder);
  42. auto right = binop.right->accept(*this, builder);
  43. auto& leftType = binop.left->type;
  44. auto& rightType = binop.right->type;
  45. sem::Method* operation = binop.operationMethod;
  46. if (operation != nullptr) {
  47. if (sem::NativeMethod* nm = dynamic_cast<sem::NativeMethod*>(operation); nm) {
  48. return nm->generateCode(builder, {left, right});
  49. }
  50. else
  51. throw "only native operations supported at the moment";
  52. }
  53. else {
  54. throw "internal error: operation method null";
  55. }
  56. if (left == nullptr) {
  57. printf("WOW: %s\n", binop.left->toString().c_str());
  58. }
  59. Value* implicitelyCastedRight = right;
  60. if (!leftType->equals(*rightType))
  61. implicitelyCastedRight = dynamic_cast<sem::NativeType*>(leftType.get())->generateImplicitCast(right);
  62. if (dynamic_cast<sem::NativeType*>(leftType.get())->isIntegerType()) {
  63. // TODO allow integer operations
  64. }
  65. /*
  66. // TODO insert type checks
  67. switch (binop.op) {
  68. case ast::Operation::Operator::PLUS:
  69. return builder.CreateAdd(left, right, "add");
  70. case ast::Operation::Operator::MINUS:
  71. return builder.CreateSub(left, right, "sub");
  72. case ast::Operation::Operator::ASTERISK:
  73. return builder.CreateMul(left, right, "mul");
  74. case ast::Operation::Operator::SLASH:
  75. return builder.CreateSDiv(left, right, "sdiv");
  76. case ast::Operation::Operator::AND:
  77. return builder.CreateAnd(left, right, "and");
  78. case ast::Operation::Operator::OR:
  79. return builder.CreateOr(left, right, "or");
  80. case ast::Operation::Operator::XOR:
  81. return builder.CreateXor(left, right, "xor");
  82. case ast::Operation::Operator::EQUALS:
  83. return builder.CreateICmpEQ(left, right, "equals");
  84. case ast::Operation::Operator::NOT_EQUALS:
  85. return builder.CreateICmpNE(left, right, "not_equals");
  86. }*/
  87. }
  88. llvm::Value* ExpressionCodegenVisitor::visit(sem::CastExpression& cast, llvm::IRBuilder<>& builder)
  89. {
  90. return builder.CreateCast(
  91. llvm::Instruction::CastOps::SExt,
  92. cast.expression->accept(*this, builder),
  93. cast.targetType->getLlvmType(builder.getContext())
  94. );
  95. }
  96. llvm::Value* ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, llvm::IRBuilder<>& builder)
  97. {
  98. using llvm::Value;
  99. // TODO implement
  100. }
  101. llvm::Value* ExpressionCodegenVisitor::visit(sem::MethodCallExpression& call, llvm::IRBuilder<>& builder)
  102. {
  103. using llvm::Value;
  104. if (call.arguments.size() != call.callee->arguments.size()) {
  105. throw "wrong number of arguments";
  106. }
  107. std::vector<Value*> arguments;
  108. if (call.target != nullptr) {
  109. auto* target = call.target->accept(*this, builder);
  110. arguments.push_back(target);
  111. }
  112. for (size_t i = 0; i < call.arguments.size(); i++) {
  113. // : call.arguments) {
  114. auto& arg = call.arguments[i];
  115. auto value = arg->accept(*this, builder);
  116. if (!arg->type->equals(*call.callee->arguments[i]->type.get())) {
  117. throw "argument type mismatch";
  118. }
  119. arguments.push_back(value);
  120. }
  121. auto returnType = call.callee->returnType;
  122. llvm::CallInst* callInst = builder.CreateCall(call.callee->llvmNode, arguments);
  123. return callInst;
  124. }
  125. llvm::Value* ExpressionCodegenVisitor::visit(sem::FieldAccessExpression& access, llvm::IRBuilder<>& builder)
  126. {
  127. using llvm::Value;
  128. builder.CreateStructGEP(access.type->getLlvmType(builder.getContext()), llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false)), 0);
  129. }
  130. llvm::Value* ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
  131. {
  132. return llvm::ConstantInt::get(builder.getContext(),
  133. llvm::APInt(32, std::to_string(node.value), 10));
  134. }
  135. llvm::Value* ExpressionCodegenVisitor::visit(sem::ThisExpression& thisExpr, llvm::IRBuilder<>& builder)
  136. {
  137. return thisExpr.allocaInst;
  138. }
  139. llvm::Value* StatementVisitor::visit(sem::DoEndBlock& assignment,
  140. qlow::gen::FunctionGenerator& fg)
  141. {
  142. for (auto& statement : assignment.statements) {
  143. statement->accept(*this, fg);
  144. }
  145. return nullptr;
  146. }
  147. llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
  148. qlow::gen::FunctionGenerator& fg)
  149. {
  150. using llvm::Value;
  151. using llvm::BasicBlock;
  152. llvm::IRBuilder<> builder(fg.getContext());
  153. builder.SetInsertPoint(fg.getCurrentBlock());
  154. auto condition = ifElseBlock.condition->accept(fg.expressionVisitor, builder);
  155. llvm::Function* function = fg.getCurrentBlock()->getParent();
  156. BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
  157. BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else", function);
  158. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  159. Value* boolCond = builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  160. builder.CreateCondBr(boolCond, thenB, elseB);
  161. fg.pushBlock(thenB);
  162. ifElseBlock.ifBlock->accept(*this, fg);
  163. builder.SetInsertPoint(thenB);
  164. if (!thenB->getTerminator())
  165. builder.CreateBr(merge);
  166. fg.popBlock();
  167. fg.pushBlock(elseB);
  168. ifElseBlock.elseBlock->accept(*this, fg);
  169. builder.SetInsertPoint(elseB);
  170. if (!elseB->getTerminator())
  171. builder.CreateBr(merge);
  172. fg.popBlock();
  173. fg.popBlock();
  174. fg.pushBlock(merge);
  175. }
  176. llvm::Value* StatementVisitor::visit(sem::WhileBlock& whileBlock,
  177. qlow::gen::FunctionGenerator& fg)
  178. {
  179. using llvm::Value;
  180. using llvm::BasicBlock;
  181. llvm::IRBuilder<> builder(fg.getContext());
  182. builder.SetInsertPoint(fg.getCurrentBlock());
  183. llvm::Function* function = fg.getCurrentBlock()->getParent();
  184. BasicBlock* startloop = BasicBlock::Create(fg.getContext(), "startloop", function);
  185. BasicBlock* body = BasicBlock::Create(fg.getContext(), "loopbody", function);
  186. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  187. //builder.CreateCondBr(boolCond, body, merge);
  188. builder.CreateBr(startloop);
  189. fg.pushBlock(startloop);
  190. builder.SetInsertPoint(startloop);
  191. auto condition = whileBlock.condition->accept(fg.expressionVisitor, builder);
  192. Value* boolCond = builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  193. builder.CreateCondBr(condition, body, merge);
  194. fg.popBlock();
  195. fg.pushBlock(body);
  196. whileBlock.body->accept(*this, fg);
  197. builder.SetInsertPoint(body);
  198. builder.CreateBr(startloop);
  199. fg.popBlock();
  200. fg.pushBlock(merge);
  201. return nullptr;
  202. }
  203. llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
  204. qlow::gen::FunctionGenerator& fg)
  205. {
  206. Logger& logger = Logger::getInstance();
  207. llvm::IRBuilder<> builder(fg.getContext());
  208. builder.SetInsertPoint(fg.getCurrentBlock());
  209. auto val = assignment.value->accept(fg.expressionVisitor, builder);
  210. if (auto* targetVar =
  211. dynamic_cast<sem::LocalVariableExpression*>(assignment.target.get()); targetVar) {
  212. logger.debug() << "assigning to LocalVariableExpression" << std::endl;
  213. builder.CreateStore(val, targetVar->var->allocaInst);
  214. }
  215. else if (auto* targetVar =
  216. dynamic_cast<sem::FieldAccessExpression*>(assignment.target.get()); targetVar) {
  217. logger.debug() << "assigning to FieldAccessExpression" << std::endl;
  218. if (targetVar->target) {
  219. llvm::Value* target = targetVar->target->accept(fg.expressionVisitor, builder);
  220. auto elementPtr = builder.CreateGEP(target, llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0)));
  221. builder.CreateStore(val, elementPtr);
  222. }
  223. else {
  224. throw "field access without target";
  225. }
  226. }
  227. else {
  228. logger.debug() << "assigning to instance of " << assignment.target->toString() << std::endl;
  229. throw "only local variables are assignable at the moment";
  230. }
  231. return nullptr;
  232. //return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5123.0));
  233. }
  234. llvm::Value* StatementVisitor::visit(sem::ReturnStatement& returnStatement,
  235. qlow::gen::FunctionGenerator& fg)
  236. {
  237. llvm::IRBuilder<> builder(fg.getContext());
  238. builder.SetInsertPoint(fg.getCurrentBlock());
  239. auto val = returnStatement.value->accept(fg.expressionVisitor, builder);
  240. builder.CreateRet(val);
  241. return val;
  242. }
  243. llvm::Value* StatementVisitor::visit(sem::FeatureCallStatement& fc, gen::FunctionGenerator& fg)
  244. {
  245. llvm::Module* module = fg.getModule();
  246. llvm::IRBuilder<> builder(fg.getContext());
  247. builder.SetInsertPoint(fg.getCurrentBlock());
  248. //llvm::Constant* c = module->getOrInsertFunction(fc.expr->callee->name, {});
  249. return fc.expr->accept(fg.expressionVisitor, builder);
  250. /*
  251. llvm::Function* f = fc.expr->callee->llvmNode;
  252. std::vector<llvm::Value*> arguments;
  253. for (auto& arg : fc.expr->arguments) {
  254. arguments
  255. }
  256. builder.CreateCall(f, {});
  257. */
  258. // return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5.0));
  259. }