summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-05-28 01:26:57 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-05-28 01:26:57 +0800
commit5fc580a0fe1ef35f0706394ec9ebb2a088deb5e9 (patch)
tree8ebc5bf451f73fee141372c18aaf7041fca09254 /node
parentc84e212d0de5ff9f14ab14ac5143e56d2839ac82 (diff)
add if, while, repeat
fix function call modify syntax
Diffstat (limited to 'node')
-rw-r--r--node/ExprNode.cc4
-rw-r--r--node/StatementNode.cc104
-rw-r--r--node/StatementNode.hh35
3 files changed, 141 insertions, 2 deletions
diff --git a/node/ExprNode.cc b/node/ExprNode.cc
index 6127f6f..4183120 100644
--- a/node/ExprNode.cc
+++ b/node/ExprNode.cc
@@ -90,8 +90,8 @@ Value FunctionCallNode::CodeGen() {
name_.c_str());
return nullptr;
}
- llvm::FunctionCallee fp =
- context_->GetModule()->getOrInsertFunction(name_, type->GetLLVMType());
+ llvm::FunctionCallee fp = context_->GetModule()->getOrInsertFunction(
+ name_, llvm::cast<llvm::FunctionType>(type->GetLLVMType()));
const std::vector<std::shared_ptr<Type>>& ArgTypes = type->GetArgTypes();
std::vector<Value> ArgValues(args_.size());
auto ArgTypeIt = ArgTypes.begin();
diff --git a/node/StatementNode.cc b/node/StatementNode.cc
index fd8ee94..e29398d 100644
--- a/node/StatementNode.cc
+++ b/node/StatementNode.cc
@@ -29,4 +29,108 @@ Value AssignStatementNode::CodeGen() {
context_->GetBuilder()->CreateStore(RightValue, LeftValue);
return nullptr;
}
+
+IfStatementNode::IfStatementNode(Context* context,
+ std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> ThenPart,
+ std::shared_ptr<BaseNode> ElsePart)
+ : BaseNode(context)
+ , expr_(expr)
+ , ThenPart_(ThenPart)
+ , ElsePart_(ElsePart) {}
+
+Value IfStatementNode::CodeGen() {
+ llvm::IRBuilder<>* builder = context_->GetBuilder();
+ TypeManager* manager = context_->GetTypeManager();
+ std::shared_ptr<Type> boolean =
+ manager->GetBuiltinType(BuiltinType::BOOLEAN);
+ llvm::Function* body = builder->GetInsertBlock()->getParent();
+ llvm::BasicBlock* ThenBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "then", body);
+ llvm::BasicBlock* EndBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "endif");
+ Value ExprValue = manager->CreateCast(boolean, expr_->GetType(),
+ expr_->CodeGen(), context_);
+ if (ElsePart_ != nullptr) {
+ llvm::BasicBlock* ElseBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "else");
+ builder->CreateCondBr(ExprValue, ThenBlock, ElseBlock);
+ builder->SetInsertPoint(ThenBlock);
+ ThenPart_->CodeGen();
+ builder->CreateBr(EndBlock);
+ body->getBasicBlockList().push_back(ElseBlock);
+ builder->SetInsertPoint(ElseBlock);
+ ElsePart_->CodeGen();
+ builder->CreateBr(EndBlock);
+ body->getBasicBlockList().push_back(EndBlock);
+ builder->SetInsertPoint(EndBlock);
+ return nullptr;
+ }
+ builder->CreateCondBr(ExprValue, ThenBlock, EndBlock);
+ builder->SetInsertPoint(ThenBlock);
+ ThenPart_->CodeGen();
+ builder->CreateBr(EndBlock);
+ body->getBasicBlockList().push_back(EndBlock);
+ builder->SetInsertPoint(EndBlock);
+ return nullptr;
+}
+
+WhileStatementNode::WhileStatementNode(Context* context,
+ std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> WhileBody)
+ : BaseNode(context)
+ , expr_(expr)
+ , WhileBody_(WhileBody) {}
+
+Value WhileStatementNode::CodeGen() {
+ llvm::IRBuilder<>* builder = context_->GetBuilder();
+ TypeManager* manager = context_->GetTypeManager();
+ std::shared_ptr<Type> boolean =
+ manager->GetBuiltinType(BuiltinType::BOOLEAN);
+ llvm::Function* body = builder->GetInsertBlock()->getParent();
+ llvm::BasicBlock* StartBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "start", body);
+ llvm::BasicBlock* LoopBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "loop");
+ llvm::BasicBlock* EndBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "done");
+ builder->SetInsertPoint(StartBlock);
+ Value ExprValue = manager->CreateCast(boolean, expr_->GetType(),
+ expr_->CodeGen(), context_);
+ builder->CreateCondBr(ExprValue, LoopBlock, EndBlock);
+ body->getBasicBlockList().push_back(LoopBlock);
+ builder->SetInsertPoint(LoopBlock);
+ WhileBody_->CodeGen();
+ builder->CreateBr(StartBlock);
+ body->getBasicBlockList().push_back(EndBlock);
+ builder->SetInsertPoint(EndBlock);
+ return nullptr;
+}
+
+RepeatStatementNode::RepeatStatementNode(Context* context,
+ std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> RepeatBody)
+ : BaseNode(context)
+ , expr_(expr)
+ , RepeatBody_(RepeatBody) {}
+
+Value RepeatStatementNode::CodeGen() {
+ llvm::IRBuilder<>* builder = context_->GetBuilder();
+ TypeManager* manager = context_->GetTypeManager();
+ std::shared_ptr<Type> boolean =
+ manager->GetBuiltinType(BuiltinType::BOOLEAN);
+ llvm::Function* body = builder->GetInsertBlock()->getParent();
+ llvm::BasicBlock* LoopBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "loop", body);
+ llvm::BasicBlock* EndBlock =
+ llvm::BasicBlock::Create(GlobalLLVMContext, "done");
+ builder->SetInsertPoint(LoopBlock);
+ RepeatBody_->CodeGen();
+ Value ExprValue = manager->CreateCast(boolean, expr_->GetType(),
+ expr_->CodeGen(), context_);
+ builder->CreateCondBr(ExprValue, EndBlock, LoopBlock);
+ body->getBasicBlockList().push_back(EndBlock);
+ builder->SetInsertPoint(EndBlock);
+ return nullptr;
+}
} // namespace pcc
diff --git a/node/StatementNode.hh b/node/StatementNode.hh
index 68c808f..1bd0cb6 100644
--- a/node/StatementNode.hh
+++ b/node/StatementNode.hh
@@ -25,6 +25,41 @@ class AssignStatementNode : public BaseNode {
std::shared_ptr<ExprNode> lhs_;
std::shared_ptr<ExprNode> rhs_;
};
+
+class IfStatementNode : public BaseNode {
+ public:
+ IfStatementNode(Context* context, std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> ThenPart,
+ std::shared_ptr<BaseNode> ElsePart);
+ virtual Value CodeGen() override;
+
+ protected:
+ std::shared_ptr<ExprNode> expr_;
+ std::shared_ptr<BaseNode> ThenPart_;
+ std::shared_ptr<BaseNode> ElsePart_;
+};
+
+class WhileStatementNode : public BaseNode {
+ public:
+ WhileStatementNode(Context* context, std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> WhileBody);
+ virtual Value CodeGen() override;
+
+ protected:
+ std::shared_ptr<ExprNode> expr_;
+ std::shared_ptr<BaseNode> WhileBody_;
+};
+
+class RepeatStatementNode : public BaseNode {
+ public:
+ RepeatStatementNode(Context* context, std::shared_ptr<ExprNode> expr,
+ std::shared_ptr<BaseNode> RepeatBody);
+ virtual Value CodeGen() override;
+
+ protected:
+ std::shared_ptr<ExprNode> expr_;
+ std::shared_ptr<BaseNode> RepeatBody_;
+};
} // namespace pcc
#endif