Some fixes for statements to string, added more tests
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2019-09-05 12:22:10 +02:00
parent fb142c7f25
commit 256969e912
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
3 changed files with 166 additions and 48 deletions

View File

@ -27,6 +27,11 @@ namespace Porygon::Binder {
}; };
class BoundStatement { class BoundStatement {
protected:
inline void DrawIndents(std::stringstream& stream, size_t indents) const{
for (size_t i = 0; i < indents; i++)
stream << "\t";
}
public: public:
[[nodiscard]] [[nodiscard]]
virtual BoundStatementKind GetKind() const = 0; virtual BoundStatementKind GetKind() const = 0;
@ -58,8 +63,7 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const final{ void GetTreeString(std::stringstream& stream, size_t indents) const final{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "BreakStatement"; stream << "BreakStatement";
} }
}; };
@ -88,8 +92,7 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "BlockStatement"; stream << "BlockStatement";
for (auto s : _statements){ for (auto s : _statements){
stream << endl; stream << endl;
@ -140,8 +143,7 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "ExpressionStatement" << endl; stream << "ExpressionStatement" << endl;
_expression->GetTreeString(stream, indents + 1); _expression->GetTreeString(stream, indents + 1);
} }
@ -176,9 +178,8 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t"; stream << "Assignment -> " << _key->GetIdentifier()->GetDebugString() << endl;
stream << "Assignment -> " << _key->GetIdentifier()->GetString() << endl;
_expression->GetTreeString(stream, indents + 1); _expression->GetTreeString(stream, indents + 1);
} }
}; };
@ -212,8 +213,7 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "IndexAssignment" << endl; stream << "IndexAssignment" << endl;
_indexExpression->GetTreeString(stream, indents + 1); _indexExpression->GetTreeString(stream, indents + 1);
stream << endl; stream << endl;
@ -243,10 +243,10 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t"; stream << "ReturnStatement";
stream << "ReturnStatement" << endl;
if (_expression != nullptr){ if (_expression != nullptr){
stream << endl;
_expression->GetTreeString(stream, indents + 1); _expression->GetTreeString(stream, indents + 1);
} }
} }
@ -289,20 +289,18 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "ConditionalStatement" << endl; stream << "ConditionalStatement" << endl;
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "Condition:" << endl; stream << "Condition:" << endl;
_condition->GetTreeString(stream, indents + 1); _condition->GetTreeString(stream, indents + 1);
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "If True:" << endl; stream << "If True:" << endl;
_block->GetTreeString(stream, indents + 1); _block->GetTreeString(stream, indents + 1);
if (_elseStatement != nullptr){ if (_elseStatement != nullptr){
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "Else:" << endl; stream << "Else:" << endl;
_elseStatement->GetTreeString(stream, indents + 1); _elseStatement->GetTreeString(stream, indents + 1);
} }
@ -362,25 +360,23 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "NumericForLoopStatement" << endl; stream << "NumericForLoopStatement" << endl;
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "Start:" << endl; stream << "Start:" << endl;
_start->GetTreeString(stream, indents + 1); _start->GetTreeString(stream, indents + 1);
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "End:" << endl; stream << "End:" << endl;
_end->GetTreeString(stream, indents + 1); _end->GetTreeString(stream, indents + 1);
if (_step != nullptr){ if (_step != nullptr){
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "Step:" << endl; stream << "Step:" << endl;
_step->GetTreeString(stream, indents + 1); _step->GetTreeString(stream, indents + 1);
} }
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "Do:" << endl; stream << "Do:" << endl;
_block->GetTreeString(stream, indents + 1); _block->GetTreeString(stream, indents + 1);
} }
@ -432,18 +428,18 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t";
stream << "GenericForLoopStatement" << endl; stream << "GenericForLoopStatement" << endl;
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t"; stream << "Key: " << _keyIdentifier->GetIdentifier()->GetDebugString() << endl;
stream << "Key: " << _keyIdentifier->GetIdentifier()->GetString().get() << endl; DrawIndents(stream, indents);
for (size_t i = 0; i < indents; i++) stream << "Value: " << _valueIdentifier->GetIdentifier()->GetDebugString() << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "Value: " << _valueIdentifier->GetIdentifier()->GetString().get() << endl;
stream << "Iterator:" << endl; stream << "Iterator:" << endl;
_iterator->GetTreeString(stream, indents + 1); _iterator->GetTreeString(stream, indents + 1);
stream << endl; stream << endl;
DrawIndents(stream, indents);
stream << "Do:" << endl;
_block->GetTreeString(stream, indents + 1); _block->GetTreeString(stream, indents + 1);
} }
}; };
@ -477,15 +473,13 @@ namespace Porygon::Binder {
} }
void GetTreeString(std::stringstream& stream, size_t indents) const override{ void GetTreeString(std::stringstream& stream, size_t indents) const override{
for (size_t i = 0; i < indents; i++) DrawIndents(stream, indents);
stream << "\t"; stream << "WhileStatement" << endl;
stream << "ConditionalStatement" << endl; DrawIndents(stream, indents);
for (size_t i = 0; i < indents; i++)
stream << "\t";
stream << "Condition:" << endl; stream << "Condition:" << endl;
_condition->GetTreeString(stream, indents + 1); _condition->GetTreeString(stream, indents + 1);
for (size_t i = 0; i < indents; i++) stream << endl;
stream << "\t"; DrawIndents(stream, indents);
stream << "While True:" << endl; stream << "While True:" << endl;
_block->GetTreeString(stream, indents + 1); _block->GetTreeString(stream, indents + 1);
} }

View File

@ -4,6 +4,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include "StringUtils.hpp"
namespace Porygon::Utilities{ namespace Porygon::Utilities{
class HashedString{ class HashedString{
@ -51,6 +52,13 @@ namespace Porygon::Utilities{
return _string; return _string;
} }
inline const std::string GetDebugString() const{
if (_string){
return Utilities::StringUtils::FromUTF8(*_string.get());
}
return std::to_string(_hash);
}
inline bool operator==(const HashedString& b) const{ inline bool operator==(const HashedString& b) const{
return _hash == b._hash; return _hash == b._hash;
} }

View File

@ -3,7 +3,9 @@
#include <sstream> #include <sstream>
#include "../src/Binder/BoundStatements/BoundStatement.hpp" #include "../src/Binder/BoundStatements/BoundStatement.hpp"
#include "../src/Utilities/HashedString.hpp"
using namespace Porygon::Binder; using namespace Porygon::Binder;
using namespace Porygon::Utilities;
TEST_CASE( "Bad Statement To String", "[BoundTreeString]" ) { TEST_CASE( "Bad Statement To String", "[BoundTreeString]" ) {
std::stringstream stream; std::stringstream stream;
@ -29,4 +31,118 @@ TEST_CASE( "Block Statement To String", "[BoundTreeString]" ) {
delete s; delete s;
} }
TEST_CASE( "Expression Statement To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundExpressionStatement(new BoundNilExpression(0,0));
s->GetTreeString(stream, 1);
REQUIRE(stream.str() == "\tExpressionStatement\n\t\tNilExpression (nil)");
delete s;
}
TEST_CASE( "Assignment Statement To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto key = new u16string(u"key");
const BoundVariableKey *keyObj = new BoundVariableKey(HashedString(key), 0, true);
auto s = new BoundAssignmentStatement(keyObj, new BoundLiteralIntegerExpression(5, 0,0));
s->GetTreeString(stream, 1);
REQUIRE(stream.str() == "\tAssignment -> key\n\t\tLiteralInteger: 5 (number)");
delete s;
}
TEST_CASE( "Index Assignment Statement To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundIndexAssignmentStatement(new BoundNilExpression(0,0), new BoundNilExpression(0,0));
s->GetTreeString(stream, 1);
REQUIRE(stream.str() == "\tIndexAssignment\n\t\tNilExpression (nil)\n\t\tNilExpression (nil)");
delete s;
}
TEST_CASE( "Return Statement with expression To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundReturnStatement(new BoundNilExpression(0,0));
s->GetTreeString(stream, 1);
REQUIRE(stream.str() == "\tReturnStatement\n\t\tNilExpression (nil)");
delete s;
}
TEST_CASE( "Return Statement without expression To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundReturnStatement(nullptr);
s->GetTreeString(stream, 1);
REQUIRE(stream.str() == "\tReturnStatement");
delete s;
}
TEST_CASE( "Conditional To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundConditionalStatement(new BoundLiteralBoolExpression(true,0,0),
new BoundBadStatement(), new BoundBadStatement());
s->GetTreeString(stream, 1);
REQUIRE(stream.str() ==
R"( ConditionalStatement
Condition:
LiteralBool: 1 (bool)
If True:
BadStatement
Else:
BadStatement)");
delete s;
}
TEST_CASE( "Numerical For to String", "[BoundTreeString]" ) {
std::stringstream stream;
auto key = new u16string(u"i");
const BoundVariableKey *keyObj = new BoundVariableKey(HashedString(key), 0, true);
auto s = new BoundNumericalForStatement(keyObj, new BoundLiteralIntegerExpression(0,0,0),
new BoundLiteralIntegerExpression(5,0,0),
new BoundLiteralIntegerExpression(1,0,0),
new BoundBadStatement());
s->GetTreeString(stream, 1);
REQUIRE(stream.str() ==
R"( NumericForLoopStatement
Start:
LiteralInteger: 0 (number)
End:
LiteralInteger: 5 (number)
Step:
LiteralInteger: 1 (number)
Do:
BadStatement)");
delete s;
}
TEST_CASE( "Generic For to String", "[BoundTreeString]" ) {
std::stringstream stream;
auto key = new u16string(u"k");
const BoundVariableKey *keyObj = new BoundVariableKey(HashedString(key), 0, true);
auto valueKey = new u16string(u"v");
const BoundVariableKey *valueKeyObj = new BoundVariableKey(HashedString(valueKey), 0, true);
auto s = new BoundGenericForStatement(keyObj, valueKeyObj, new BoundNilExpression(0,0), new BoundBadStatement());
s->GetTreeString(stream, 1);
REQUIRE(stream.str() ==
R"( GenericForLoopStatement
Key: k
Value: v
Iterator:
NilExpression (nil)
Do:
BadStatement)");
delete s;
}
TEST_CASE( "While To String", "[BoundTreeString]" ) {
std::stringstream stream;
auto s = new BoundWhileStatement(new BoundLiteralBoolExpression(true,0,0),
new BoundBadStatement());
s->GetTreeString(stream, 1);
REQUIRE(stream.str() ==
R"( WhileStatement
Condition:
LiteralBool: 1 (bool)
While True:
BadStatement)");
delete s;
}
#endif #endif