diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-28 01:26:57 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-28 01:26:57 +0800 |
| commit | 5fc580a0fe1ef35f0706394ec9ebb2a088deb5e9 (patch) | |
| tree | 8ebc5bf451f73fee141372c18aaf7041fca09254 /node/StatementNode.cc | |
| parent | c84e212d0de5ff9f14ab14ac5143e56d2839ac82 (diff) | |
add if, while, repeat
fix function call
modify syntax
Diffstat (limited to 'node/StatementNode.cc')
| -rw-r--r-- | node/StatementNode.cc | 104 |
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 |
