summaryrefslogtreecommitdiff
path: root/node/ExprNode.cc
diff options
context:
space:
mode:
Diffstat (limited to 'node/ExprNode.cc')
-rw-r--r--node/ExprNode.cc60
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