summaryrefslogtreecommitdiff
path: root/node/StatementNode.cc
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/StatementNode.cc
parentc84e212d0de5ff9f14ab14ac5143e56d2839ac82 (diff)
add if, while, repeat
fix function call modify syntax
Diffstat (limited to 'node/StatementNode.cc')
-rw-r--r--node/StatementNode.cc104
1 files changed, 104 insertions, 0 deletions
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