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 | |
| parent | c84e212d0de5ff9f14ab14ac5143e56d2839ac82 (diff) | |
add if, while, repeat
fix function call
modify syntax
Diffstat (limited to 'node')
| -rw-r--r-- | node/ExprNode.cc | 4 | ||||
| -rw-r--r-- | node/StatementNode.cc | 104 | ||||
| -rw-r--r-- | node/StatementNode.hh | 35 |
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 |
