diff --git a/src/Binder/BoundExpressions/BoundExpression.hpp b/src/Binder/BoundExpressions/BoundExpression.hpp index 1ce25d3..4897391 100644 --- a/src/Binder/BoundExpressions/BoundExpression.hpp +++ b/src/Binder/BoundExpressions/BoundExpression.hpp @@ -34,9 +34,15 @@ namespace Porygon::Binder { }; class BoundExpression { + private: const unsigned int _start; const unsigned int _length; const shared_ptr _type; + protected: + inline void DrawIndents(std::stringstream& stream, size_t indents) const{ + for (size_t i = 0; i < indents; i++) + stream << "\t"; + } public: BoundExpression(unsigned int start, unsigned int length, shared_ptr type) : _start(start), @@ -79,8 +85,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "BadExpression"; } }; @@ -104,8 +109,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "LiteralInteger: " << _value << " (" << GetType()->ToString() << ")"; } }; @@ -129,8 +133,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "LiteralFloat: " << _value << " (" << GetType()->ToString() << ")"; } }; @@ -155,10 +158,9 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; - stream << "LiteralString: " << Utilities::StringUtils::FromUTF8(_value) - << " (" << GetType()->ToString() << ")"; + DrawIndents(stream, indents); + stream << "LiteralString: \"" << Utilities::StringUtils::FromUTF8(_value) + << "\" (" << GetType()->ToString() << ")"; } }; @@ -181,8 +183,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "LiteralBool: " << _value << " (" << GetType()->ToString() << ")"; } }; @@ -199,8 +200,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "NilExpression" << " (" << GetType()->ToString() << ")"; } }; @@ -229,9 +229,8 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; - stream << "VariableExpression: " << _key->GetIdentifier()->GetString().get() + DrawIndents(stream, indents); + stream << "VariableExpression: " << _key->GetIdentifier()->GetDebugString() << " (" << GetType()->ToString() << ")"; } }; @@ -296,11 +295,11 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "BinaryExpression: " << GetOperationString(_operation) << " (" << GetType()->ToString() << ")" << endl; _left->GetTreeString(stream, indents + 1); + stream << endl; _right->GetTreeString(stream, indents + 1); } }; @@ -344,8 +343,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "UnaryExpression: " << GetOperationString(_operation) << " (" << GetType()->ToString() << ")" << endl; _operand->GetTreeString(stream, indents + 1); @@ -383,8 +381,7 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; + DrawIndents(stream, indents); stream << "IndexExpression" << " (" << GetType()->ToString() << ")" << endl; _indexableExpression->GetTreeString(stream, indents + 1); stream << endl; @@ -423,10 +420,8 @@ namespace Porygon::Binder { } void GetTreeString(std::stringstream& stream, size_t indents) const final{ - for (size_t i = 0; i < indents; i++) - stream << "\t"; - stream << "PeriodIndex: " << _index.GetString().get() << " (" << GetType()->ToString() << ")" << endl; - stream << endl; + DrawIndents(stream, indents); + stream << "PeriodIndex: " << _index.GetDebugString() << " (" << GetType()->ToString() << ")" << endl; _indexableExpression->GetTreeString(stream, indents + 1); } @@ -476,7 +471,7 @@ namespace Porygon::Binder { _expression(expression) {} - const BoundExpression* GetExpression() const{ + [[nodiscard]] const BoundExpression* GetExpression() const{ return _expression; } diff --git a/tests/TreeStringTests.cpp b/tests/TreeStringTests.cpp index fc37f3f..cac98d4 100644 --- a/tests/TreeStringTests.cpp +++ b/tests/TreeStringTests.cpp @@ -162,6 +162,125 @@ TEST_CASE( "Function Declaration To String", "[BoundTreeString]" ) { delete s; } +TEST_CASE( "Bad Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundBadExpression(0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tBadExpression"); + delete s; +} + +TEST_CASE( "Literal Integer Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundLiteralIntegerExpression(684,0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tLiteralInteger: 684 (number)"); + delete s; +} + +TEST_CASE( "Literal Float Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundLiteralFloatExpression(5.5,0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tLiteralFloat: 5.5 (number)"); + delete s; +} + +TEST_CASE( "Literal String Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundLiteralStringExpression(u"foobar",0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tLiteralString: \"foobar\" (string)"); + delete s; +} + +TEST_CASE( "Literal Bool Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundLiteralBoolExpression(true, 0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tLiteralBool: 1 (bool)"); + delete s; +} + +TEST_CASE( "Nil Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundNilExpression(0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tNilExpression (nil)"); + delete s; +} + +TEST_CASE( "Variable Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto type = ScriptType::BoolType; + auto key = new BoundVariableKey(HashedString(new u16string(u"var")), 0, false); + auto s = new BoundVariableExpression(key, type,0,0); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tVariableExpression: var (bool)"); + delete s; +} + +TEST_CASE( "Binary Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundBinaryExpression( + new BoundLiteralIntegerExpression(5,0,0), + new BoundLiteralIntegerExpression(200,0,0), + BoundBinaryOperation ::Addition, + NumericScriptType::AwareInt, 0,0 + ); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tBinaryExpression: addition (number)\n\t\tLiteralInteger: 5 (number)\n\t\tLiteralInteger: 200 (number)"); + delete s; +} + +TEST_CASE( "Unary Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundUnaryExpression( + new BoundLiteralIntegerExpression(5,0,0), + BoundUnaryOperation ::Negation, + NumericScriptType::AwareInt, 0,0 + ); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tUnaryExpression: negation (number)\n\t\tLiteralInteger: 5 (number)"); + delete s; +} + +TEST_CASE( "Index Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundIndexExpression( + new BoundBadExpression(0,0), + new BoundBadExpression(0,0), + ScriptType::NilType, + 0,0 + ); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tIndexExpression (nil)\n\t\tBadExpression\n\t\tBadExpression"); + delete s; +} + +TEST_CASE( "Period Index Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundPeriodIndexExpression( + new BoundBadExpression(0,0), + HashedString(new u16string(u"key")), + ScriptType::NilType, + 0,0 + ); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tPeriodIndex: key (nil)\n\t\tBadExpression"); + delete s; +} + +TEST_CASE( "Cast Expression To String", "[BoundTreeString]" ) { + std::stringstream stream; + auto s = new BoundCastExpression( + new BoundBadExpression(0,0), + ScriptType::BoolType + ); + s->GetTreeString(stream, 1); + REQUIRE(stream.str() == "\tCastExpression (bool)\n\t\tBadExpression"); + delete s; +}