diff options
Diffstat (limited to 'node')
| -rw-r--r-- | node/BaseNode.hh | 3 | ||||
| -rw-r--r-- | node/DeclNode.cc | 4 | ||||
| -rw-r--r-- | node/DeclNode.hh | 3 | ||||
| -rw-r--r-- | node/ExprNode.cc | 12 | ||||
| -rw-r--r-- | node/ExprNode.hh | 13 | ||||
| -rw-r--r-- | node/FunctionNode.cc | 11 | ||||
| -rw-r--r-- | node/FunctionNode.hh | 2 | ||||
| -rw-r--r-- | node/LiteralNode.cc | 12 | ||||
| -rw-r--r-- | node/LiteralNode.hh | 5 | ||||
| -rw-r--r-- | node/Node.cc | 506 | ||||
| -rw-r--r-- | node/StatementNode.hh | 11 |
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 |
