summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorNagi5Yeq <wu@x-nagi.com>2020-06-03 02:36:05 +0800
committerNagi5Yeq <wu@x-nagi.com>2020-06-03 02:36:05 +0800
commit2d6ab4b7f207a746a7caaa93466b410cbe328626 (patch)
tree570a2d7776e616309149adf065acc474c0c0de98 /node
parentcd1466f30c146e12faa0db7e1b53b508bf2274c6 (diff)
support for short, int64 and AST dump
Diffstat (limited to 'node')
-rw-r--r--node/BaseNode.hh3
-rw-r--r--node/DeclNode.cc4
-rw-r--r--node/DeclNode.hh3
-rw-r--r--node/ExprNode.cc12
-rw-r--r--node/ExprNode.hh13
-rw-r--r--node/FunctionNode.cc11
-rw-r--r--node/FunctionNode.hh2
-rw-r--r--node/LiteralNode.cc12
-rw-r--r--node/LiteralNode.hh5
-rw-r--r--node/Node.cc506
-rw-r--r--node/StatementNode.hh11
11 files changed, 562 insertions, 20 deletions
diff --git a/node/BaseNode.hh b/node/BaseNode.hh
index 22ab93a..8916ef1 100644
--- a/node/BaseNode.hh
+++ b/node/BaseNode.hh
@@ -4,12 +4,14 @@
#include <list>
#include "Context.hh"
+#include "Traveler.hh"
namespace pcc {
class BaseNode {
public:
BaseNode(Context* context);
virtual Value CodeGen() = 0;
+ virtual int Travel(Traveler& traveler) = 0;
protected:
Context* context_;
@@ -24,6 +26,7 @@ class ProgramNode : public BaseNode {
std::list<std::shared_ptr<DeclNode>>&& GlobalDeclarations,
std::list<std::shared_ptr<FunctionNode>>&& functions);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::string name_;
diff --git a/node/DeclNode.cc b/node/DeclNode.cc
index 4d2f8aa..d22c847 100644
--- a/node/DeclNode.cc
+++ b/node/DeclNode.cc
@@ -75,9 +75,9 @@ TypeDeclNode::TypeDeclNode(Context* context, VariableList* scope,
, decls_(std::move(decls)) {}
Value TypeDeclNode::CodeGen() {
- scope_ = (scope_ == nullptr ? context_->GetGlobals() : scope_);
+ VariableList* scope = (scope_ == nullptr ? context_->GetGlobals() : scope_);
for (auto&& decl : decls_) {
- scope_->AddTypeAlias(std::get<0>(decl), std::get<1>(decl)->GetType());
+ scope->AddTypeAlias(std::get<0>(decl), std::get<1>(decl)->GetType());
}
return nullptr;
}
diff --git a/node/DeclNode.hh b/node/DeclNode.hh
index 3858fc6..735ba4e 100644
--- a/node/DeclNode.hh
+++ b/node/DeclNode.hh
@@ -25,6 +25,7 @@ class VarDeclNode : public DeclNode {
VarDeclNode(Context* context, VariableList* scope,
std::list<Declaration>&& decls);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::list<Declaration> decls_;
@@ -38,6 +39,7 @@ class ConstDeclNode : public DeclNode {
ConstDeclNode(Context* context, VariableList* scope,
std::list<Constant>&& decls);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::list<Constant> decls_;
@@ -48,6 +50,7 @@ class TypeDeclNode : public DeclNode {
TypeDeclNode(Context* context, VariableList* scope,
std::list<Declaration>&& decls);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::list<Declaration> decls_;
diff --git a/node/ExprNode.cc b/node/ExprNode.cc
index c0a3f41..9610420 100644
--- a/node/ExprNode.cc
+++ b/node/ExprNode.cc
@@ -242,9 +242,9 @@ Value FunctionCallNode::CodeGen() {
args_.size());
return nullptr;
}
- std::vector<Value> ArgValues(args_.size());
+ std::vector<Value> ArgValues;
+ ArgValues.reserve(args_.size());
auto ArgIt = args_.begin();
- auto ArgValueIt = ArgValues.begin();
for (auto&& ArgType : ArgTypes) {
Value argv = (*ArgIt)->CodeGen();
Value ConvertedArgv =
@@ -255,12 +255,12 @@ Value FunctionCallNode::CodeGen() {
"of type %s needed",
type->GetCommonName(), ArgType->GetCommonName());
}
- *ArgValueIt = ConvertedArgv;
- ++ArgIt, ++ArgValueIt;
+ ArgValues.push_back(ConvertedArgv);
+ ++ArgIt;
}
while (ArgIt != args_.end()) {
- *ArgValueIt = (*ArgIt)->CodeGen();
- ++ArgIt, ++ArgValueIt;
+ ArgValues.push_back((*ArgIt)->CodeGen());
+ ++ArgIt;
}
type_ = type->GetReturnType();
return context_->GetBuilder()->CreateCall(std::get<1>(function), ArgValues);
diff --git a/node/ExprNode.hh b/node/ExprNode.hh
index aeb3ef8..291186c 100644
--- a/node/ExprNode.hh
+++ b/node/ExprNode.hh
@@ -22,7 +22,8 @@ class BinaryExprNode : public ExprNode {
BinaryExprNode(Context* context, BinaryOperator op,
std::shared_ptr<ExprNode> left,
std::shared_ptr<ExprNode> right);
- virtual Value CodeGen();
+ virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
BinaryOperator op_;
@@ -33,7 +34,8 @@ class UnaryExprNode : public ExprNode {
public:
UnaryExprNode(Context* context, UnaryOperator op,
std::shared_ptr<ExprNode> value);
- virtual Value CodeGen();
+ virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
UnaryOperator op_;
@@ -55,6 +57,7 @@ class L2RCastingNode : public ExprNode {
public:
L2RCastingNode(Context* context, std::shared_ptr<ExprNode> lvalue);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lvalue_;
@@ -66,6 +69,7 @@ class PointerAccessNode : public ExprNode {
PointerAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
std::shared_ptr<ExprNode> rhs);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lhs_;
@@ -78,6 +82,7 @@ class ArrayAccessNode : public ExprNode {
ArrayAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
std::shared_ptr<ExprNode> rhs);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lhs_;
@@ -88,6 +93,7 @@ class DereferenceNode : public ExprNode {
public:
DereferenceNode(Context* context, std::shared_ptr<ExprNode> lhs);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lhs_;
@@ -98,6 +104,7 @@ class MemberAccessNode : public ExprNode {
MemberAccessNode(Context* context, std::shared_ptr<ExprNode> lhs,
std::string&& rhs);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lhs_;
@@ -108,6 +115,7 @@ class IdentifierNode : public ExprNode {
public:
IdentifierNode(Context* context, const std::string& name);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::string name_;
@@ -118,6 +126,7 @@ class FunctionCallNode : public ExprNode {
FunctionCallNode(Context* context, const std::string& name,
std::list<std::shared_ptr<ExprNode>>&& args);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::string name_;
diff --git a/node/FunctionNode.cc b/node/FunctionNode.cc
index 4fb5138..eaf2a0d 100644
--- a/node/FunctionNode.cc
+++ b/node/FunctionNode.cc
@@ -1,3 +1,4 @@
+#include <iterator>
#include <memory>
#include <vector>
@@ -31,9 +32,10 @@ Value FunctionNode::CodeGen() {
llvm::Module* module = context_->GetModule();
llvm::IRBuilder<>* builder = context_->GetBuilder();
TypeManager* manager = context_->GetTypeManager();
- std::vector<std::shared_ptr<Type>> params(arguments_.size());
+ std::vector<std::shared_ptr<Type>> params;
+ params.reserve(arguments_.size());
std::transform(
- arguments_.cbegin(), arguments_.cend(), params.begin(),
+ arguments_.cbegin(), arguments_.cend(), std::back_inserter(params),
[](const Declaration& decl) { return std::get<1>(decl)->GetType(); });
std::shared_ptr<Type> ReturnType = ReturnTypeIdentifier_->GetType();
std::shared_ptr<FunctionType> type =
@@ -104,9 +106,10 @@ Value ExternNode::CodeGen() {
llvm::Module* module = context_->GetModule();
llvm::IRBuilder<>* builder = context_->GetBuilder();
TypeManager* manager = context_->GetTypeManager();
- std::vector<std::shared_ptr<Type>> params(arguments_.size());
+ std::vector<std::shared_ptr<Type>> params;
+ params.reserve(arguments_.size());
std::transform(
- arguments_.cbegin(), arguments_.cend(), params.begin(),
+ arguments_.cbegin(), arguments_.cend(), std::back_inserter(params),
[](const Declaration& decl) { return std::get<1>(decl)->GetType(); });
std::shared_ptr<Type> ReturnType = ReturnTypeIdentifier_->GetType();
std::shared_ptr<FunctionType> type =
diff --git a/node/FunctionNode.hh b/node/FunctionNode.hh
index 6860c45..56a019b 100644
--- a/node/FunctionNode.hh
+++ b/node/FunctionNode.hh
@@ -16,6 +16,7 @@ class FunctionNode : public BaseNode {
std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier,
std::shared_ptr<StatementListNode> body);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::string name_;
@@ -33,6 +34,7 @@ class ExternNode : public FunctionNode {
std::shared_ptr<TypeIdentifier> ReturnTypeIdentifier,
bool IsVariadic);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
bool IsVariadic_;
diff --git a/node/LiteralNode.cc b/node/LiteralNode.cc
index 43bddb6..2c5d6c6 100644
--- a/node/LiteralNode.cc
+++ b/node/LiteralNode.cc
@@ -5,7 +5,8 @@
#include "LiteralNode.hh"
namespace pcc {
-template <> Value BooleanLiteralNode::CodeGen() {
+template <>
+Value BooleanLiteralNode::CodeGen() {
if (value_ == true) {
return llvm::ConstantInt::getTrue(GlobalLLVMContext);
} else {
@@ -13,15 +14,18 @@ template <> Value BooleanLiteralNode::CodeGen() {
}
}
-template <> Value CharLiteralNode::CodeGen() {
+template <>
+Value CharLiteralNode::CodeGen() {
return llvm::ConstantInt::get(type_->GetLLVMType(), value_, true);
}
-template <> Value IntegerLiteralNode::CodeGen() {
+template <>
+Value IntegerLiteralNode::CodeGen() {
return llvm::ConstantInt::get(type_->GetLLVMType(), value_, true);
}
-template <> Value RealLiteralNode::CodeGen() {
+template <>
+Value RealLiteralNode::CodeGen() {
llvm::APFloat value(value_);
return llvm::ConstantFP::get(GlobalLLVMContext, value);
}
diff --git a/node/LiteralNode.hh b/node/LiteralNode.hh
index f93c171..3923334 100644
--- a/node/LiteralNode.hh
+++ b/node/LiteralNode.hh
@@ -7,10 +7,12 @@
#include "ExprNode.hh"
namespace pcc {
-template <typename T> class LiteralNode : public ExprNode {
+template <typename T>
+class LiteralNode : public ExprNode {
public:
LiteralNode(Context* context, std::shared_ptr<Type> type, T value);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
private:
T value_;
@@ -36,6 +38,7 @@ class StringLiteralNode : public ExprNode {
StringLiteralNode(Context* context, std::shared_ptr<Type> type,
std::vector<char> value);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
private:
std::vector<char> value_;
diff --git a/node/Node.cc b/node/Node.cc
new file mode 100644
index 0000000..d9eb806
--- /dev/null
+++ b/node/Node.cc
@@ -0,0 +1,506 @@
+#include <cctype>
+#include <type_traits>
+
+#include "Node.hh"
+#include "Type.hh"
+#include "TypeIdentifier.hh"
+
+namespace pcc {
+Traveler& Traveler::operator<<(std::shared_ptr<Type> type) {
+ out_ << type->GetCommonName();
+ return *this;
+}
+
+Traveler& Traveler::operator<<(std::shared_ptr<TypeIdentifier> identifier) {
+ return *this << identifier->GetType();
+}
+
+template <typename Lambda, typename Container>
+void NonterminalContainerTravel(Traveler& traveler, Lambda&& lambda,
+ Container&& childs) {
+ for (auto&& child : childs) {
+ traveler << TravelPart::CHILD_BEGIN;
+ std::forward<Lambda>(lambda)(traveler, child);
+ traveler << TravelPart::CHILD_END;
+ }
+}
+
+template <typename Lambda, typename Container>
+void TerminalContainerTravel(Traveler& traveler, Lambda&& lambda,
+ Container&& childs) {
+ if (childs.empty()) {
+ return;
+ }
+ auto LastOne = childs.end();
+ --LastOne;
+ for (auto child = childs.begin(); child != LastOne; ++child) {
+ traveler << TravelPart::CHILD_BEGIN;
+ std::forward<Lambda>(lambda)(traveler, *child);
+ traveler << TravelPart::CHILD_END;
+ }
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ std::forward<Lambda>(lambda)(traveler, *LastOne);
+ traveler << TravelPart::LAST_CHILD_END;
+}
+
+template <typename L0, typename C0, typename L1, typename C1>
+void MultipleContainerTravel(Traveler& traveler, L0&& ThisLambda, C0&& ThisOne,
+ L1&& LastLambda, C1&& LastOne) {
+ if (LastOne.empty()) {
+ TerminalContainerTravel(traveler, std::forward<L0>(ThisLambda),
+ std::forward<C0>(ThisOne));
+ return;
+ }
+ NonterminalContainerTravel(traveler, std::forward<L0>(ThisLambda),
+ std::forward<C0>(ThisOne));
+ TerminalContainerTravel(traveler, std::forward<L1>(LastLambda),
+ std::forward<C1>(LastOne));
+}
+
+int ProgramNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ProgramNode" << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "program " + name_
+ << TravelPart::DESCRPTION_END;
+ MultipleContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto&& decl) { decl->Travel(traveler); },
+ GlobalDeclarations_,
+ [](Traveler& traveler, auto&& decl) { decl->Travel(traveler); },
+ functions_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int VarDeclNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "VarDeclNode" << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << (scope_ == nullptr ? "global size=" : "local size=")
+ << decls_.size() << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, Declaration& decl) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "Variable"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "name=" << std::get<0>(decl)
+ << " type=" << (std::get<1>(decl)->GetType())
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ },
+ decls_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int ConstDeclNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ConstDeclNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "const size=" << decls_.size()
+ << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, Constant& decl) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "Constant"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "name=" << std::get<0>(decl)
+ << " type=" << (std::get<1>(decl)->GetType())
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ },
+ decls_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int TypeDeclNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "TypeDeclNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << (scope_ == nullptr ? "global size=" : "local size=")
+ << decls_.size() << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, Declaration& decl) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "TypeAlias"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "name=" << std::get<0>(decl)
+ << " type=" << (std::get<1>(decl)->GetType())
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ },
+ decls_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int BinaryExprNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "BinaryExprNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "op='" << GetOperatorName(op_)
+ << "' ResultType=" << type_ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ left_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ right_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int UnaryExprNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "UnaryExprNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "op='" << GetOperatorName(op_)
+ << " ResultType='" << type_ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ value_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int L2RCastingNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "L2RCastingNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "ResultType=" << type_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ lvalue_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int PointerAccessNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "PointerAccessNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "ResultType=" << type_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ lhs_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ rhs_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int ArrayAccessNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ArrayAccessNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "ResultType=" << type_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ lhs_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ rhs_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int DereferenceNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "DereferenceNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "ResultType=" << type_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ lhs_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int MemberAccessNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "MemberAccessNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "MemberName=" << rhs_
+ << " ResultType=" << type_ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ lhs_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int IdentifierNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "IdentifierNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "lvalue name=" << name_
+ << " type=" << type_ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int FunctionCallNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "FunctionCallNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "FunctionName=" << name_
+ << " ResultType=" << type_ << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler, [](Traveler& traveler, auto&& arg) { arg->Travel(traveler); },
+ args_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int FunctionNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "FunctionNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "FunctionName=" << name_
+ << " ReturnType=" << ReturnTypeIdentifier_
+ << TravelPart::DESCRPTION_END;
+ NonterminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto& arg) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "Argument"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "name=" << std::get<0>(arg)
+ << " type=" << std::get<1>(arg)
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ },
+ arguments_);
+ NonterminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto&& decl) { decl->Travel(traveler); },
+ LocalDeclarations_);
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ body_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int ExternNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ExternNode" << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "FunctionName=" << name_
+ << " ReturnType=" << ReturnTypeIdentifier_
+ << (IsVariadic_ ? "Variadic" : "") << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto& arg) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "Argument"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "name=" << std::get<0>(arg)
+ << " type=" << std::get<1>(arg)
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ },
+ arguments_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+template <>
+int BooleanLiteralNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "BooleanLiteralNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "value=" << (value_ == true ? "true" : "false")
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+template <>
+int CharLiteralNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "CharLiteralNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "value=0x" << std::hex
+ << (int) value_ << std::dec << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+template <>
+int IntegerLiteralNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "IntegerLiteralNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "value=" << value_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+template <>
+int RealLiteralNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "RealLiteralNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "value=" << value_
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int StringLiteralNode::Travel(Traveler& traveler) {
+ const char HexChars[] = "0123456789abcdef";
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "StringLiteralNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "value=\'";
+ std::string escaped;
+ escaped.reserve(value_.size() * 2);
+ for (char c : value_) {
+ if (std::isprint(c)) {
+ escaped.push_back(c);
+ } else {
+ auto hex = {'\\', 'x', HexChars[c & 0xf], HexChars[(c >> 4) & 0xf]};
+ escaped.append(hex);
+ }
+ }
+ traveler << escaped << '\'' << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int StatementListNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "StatementListNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "size=" << childs_.size()
+ << TravelPart::DESCRPTION_END;
+ TerminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto&& child) { child->Travel(traveler); },
+ childs_);
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int EmptyStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "EmptyStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "empty"
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int AssignStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "AssignStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "ValueType=" << rhs_->GetType()
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ lhs_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ rhs_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int IfStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "IfStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "HasElse=" << (ElsePart_ == nullptr ? "false" : "true")
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ expr_->Travel(traveler);
+ traveler << TravelPart::CHILD_END;
+ if (ElsePart_ == nullptr) {
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ ThenPart_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END;
+ } else {
+ traveler << TravelPart::CHILD_BEGIN;
+ ThenPart_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ ElsePart_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END;
+ }
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int WhileStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "WhileStatementNode"
+ << TravelPart::NAME_END << TravelPart::DESCRPTION_BEGIN
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ expr_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ WhileBody_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int RepeatStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "RepeatStatementNode"
+ << TravelPart::NAME_END << TravelPart::DESCRPTION_BEGIN
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::CHILD_BEGIN;
+ expr_->Travel(traveler);
+ traveler << TravelPart::CHILD_END << TravelPart::LAST_CHILD_BEGIN;
+ RepeatBody_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int ForStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ForStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN
+ << "direction=" << (IsUpward_ ? "up" : "down")
+ << TravelPart::DESCRPTION_END;
+ auto childs = {variable_, start_, end_};
+ NonterminalContainerTravel(
+ traveler,
+ [](Traveler& traveler, auto&& child) { child->Travel(traveler); },
+ childs);
+ traveler << TravelPart::LAST_CHILD_BEGIN;
+ ForBody_->Travel(traveler);
+ traveler << TravelPart::LAST_CHILD_END << TravelPart::END;
+ return 0;
+}
+
+int BreakStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "BreakStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "break"
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+
+int ContinueStatementNode::Travel(Traveler& traveler) {
+ traveler << TravelPart::PREFIX;
+ traveler << TravelPart::NAME_BEGIN << "ContinueStatementNode"
+ << TravelPart::NAME_END;
+ traveler << TravelPart::DESCRPTION_BEGIN << "continue"
+ << TravelPart::DESCRPTION_END;
+ traveler << TravelPart::END;
+ return 0;
+}
+} // namespace pcc
diff --git a/node/StatementNode.hh b/node/StatementNode.hh
index fa8fbe4..b729001 100644
--- a/node/StatementNode.hh
+++ b/node/StatementNode.hh
@@ -11,7 +11,8 @@ class StatementListNode : public BaseNode {
public:
StatementListNode(Context* context);
void Append(std::shared_ptr<BaseNode> child);
- virtual Value CodeGen();
+ virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
private:
std::list<std::shared_ptr<BaseNode>> childs_;
@@ -21,6 +22,7 @@ class EmptyStatementNode : public BaseNode {
public:
EmptyStatementNode(Context* context);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
};
class AssignStatementNode : public BaseNode {
@@ -28,6 +30,7 @@ class AssignStatementNode : public BaseNode {
AssignStatementNode(Context* context, std::shared_ptr<ExprNode> lhs,
std::shared_ptr<ExprNode> rhs);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> lhs_;
@@ -40,6 +43,7 @@ class IfStatementNode : public BaseNode {
std::shared_ptr<BaseNode> ThenPart,
std::shared_ptr<BaseNode> ElsePart);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> expr_;
@@ -52,6 +56,7 @@ class WhileStatementNode : public BaseNode {
WhileStatementNode(Context* context, std::shared_ptr<ExprNode> expr,
std::shared_ptr<BaseNode> WhileBody);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> expr_;
@@ -63,6 +68,7 @@ class RepeatStatementNode : public BaseNode {
RepeatStatementNode(Context* context, std::shared_ptr<ExprNode> expr,
std::shared_ptr<BaseNode> RepeatBody);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> expr_;
@@ -76,6 +82,7 @@ class ForStatementNode : public BaseNode {
std::shared_ptr<ExprNode> end, bool IsUpward,
std::shared_ptr<BaseNode> ForBody);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
protected:
std::shared_ptr<ExprNode> variable_;
@@ -89,12 +96,14 @@ class BreakStatementNode : public BaseNode {
public:
BreakStatementNode(Context* context);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
};
class ContinueStatementNode : public BaseNode {
public:
ContinueStatementNode(Context* context);
virtual Value CodeGen() override;
+ virtual int Travel(Traveler& traveler) override;
};
} // namespace pcc