diff options
| author | Nagi5Yeq <wu@x-nagi.com> | 2020-05-25 16:14:41 +0800 |
|---|---|---|
| committer | Nagi5Yeq <wu@x-nagi.com> | 2020-05-25 16:14:41 +0800 |
| commit | 958a811b18aee04e4795cf003fd8e3db00312c91 (patch) | |
| tree | 92cbc52f7560af0e08febfe1da38ed657ad29735 /node/ExprNode.cc | |
| parent | c5e9f890dab0e4595482301d77876793c8bceb8c (diff) | |
finish function calls and lvalue
Diffstat (limited to 'node/ExprNode.cc')
| -rw-r--r-- | node/ExprNode.cc | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/node/ExprNode.cc b/node/ExprNode.cc index 8034fb8..e7ef2aa 100644 --- a/node/ExprNode.cc +++ b/node/ExprNode.cc @@ -1,3 +1,5 @@ +#include <vector> + #include "ExprNode.hh" #include "Log.hh" #include "TypeManager.hh" @@ -51,4 +53,62 @@ Value UnaryExprNode::CodeGen() { } return result; } + +L2RCastingNode::L2RCastingNode(Context* context, + std::shared_ptr<ExprNode> lvalue) + : ExprNode(context) + , lvalue_(lvalue) {} + +Value L2RCastingNode::CodeGen() { + Value left = lvalue_->CodeGen(); + type_ = lvalue_->GetType(); + return context_->GetBuilder()->CreateLoad(type_->GetLLVMType(), left); +} + +IdentifierNode::IdentifierNode(Context* context, const std::string& name) + : ExprNode(context) + , name_(name) {} + +Value IdentifierNode::CodeGen() { + Variable var = context_->GetCurrentScope()->Find(name_); + type_ = std::get<0>(var); + return std::get<1>(var); +} + +FunctionCallNode::FunctionCallNode(Context* context, const std::string& name, + std::list<std::shared_ptr<ExprNode>> args) + : ExprNode(context) + , name_(name) + , args_(args) {} + +Value FunctionCallNode::CodeGen() { + TypeManager* manager = context_->GetTypeManager(); + std::shared_ptr<FunctionType> type = context_->GetFunctionType(name_); + if (type == nullptr) { + Log(LogLevel::PCC_ERROR, "call to undefined function %s", + name_.c_str()); + return nullptr; + } + llvm::FunctionCallee fp = + context_->GetModule()->getOrInsertFunction(name_, type->GetLLVMType()); + const std::vector<std::shared_ptr<Type>>& ArgTypes = type->GetArgTypes(); + std::vector<Value> ArgValues(args_.size()); + auto ArgTypeIt = ArgTypes.begin(); + auto ArgValueIt = ArgValues.begin(); + for (auto arg : args_) { + Value argv = arg->CodeGen(); + Value ConvertedArgv = + manager->CreateCast(*ArgTypeIt, arg->GetType(), argv, context_); + if (ConvertedArgv == nullptr) { + Log(LogLevel ::PCC_ERROR, + "argument type mismatch, the function type is %s, an argument " + "of type %s needed", + type->GetCommonName(), (*ArgTypeIt)->GetCommonName()); + } + *ArgValueIt = ConvertedArgv; + ++ArgTypeIt, ++ArgValueIt; + } + type_ = type->GetReturnType(); + return context_->GetBuilder()->CreateCall(fp, ArgValues); +} } // namespace pcc |
