Move parse tree stringification away from the main parsed statements, and into a helper function class.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2021-01-03 15:10:43 +01:00
parent 4c4faac899
commit 08a0859539
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
3 changed files with 119 additions and 73 deletions

View File

@ -2,6 +2,7 @@
#include <sstream>
#include "../src/Parser/Lexer/Lexer.hpp"
#include "../src/Parser/Parser.hpp"
#include "../src/Parser/Statements/ParsedStatementStringifier.hpp"
void UpdateScriptWithParseInfo(WINDOW* inputWindow, const std::u8string& script,
const MalachScript::Diagnostics::Diagnostic* diag,
@ -82,7 +83,7 @@ void ParseAndUpdate(const std::vector<std::u8string> lines, WINDOW* diagnosticsW
wclear(parsedWindow);
if (logger.GetMessages().empty()) {
std::stringstream ss;
parsedResult->Stringify(ss, "", true);
MalachScript::Parser::ParsedStatementStringifier::Stringify(parsedResult, ss, "", true);
waddstr(parsedWindow, ss.str().c_str());
}

View File

@ -20,12 +20,6 @@ namespace MalachScript::Parser {
virtual ~ParsedStatement() = default;
[[nodiscard]] virtual ParsedStatementKind GetKind() const noexcept = 0;
[[nodiscard]] inline const TextSpan& GetSpan() const noexcept { return _span; }
virtual void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const {
stream << prefix;
stream << (isLast ? "└──" : "├──");
stream << ParsedStatementKindHelper::ToString(GetKind());
}
};
template <ParsedStatementKind kind> class ParsedStatementImpl : public ParsedStatement {
@ -47,14 +41,6 @@ namespace MalachScript::Parser {
[[nodiscard]] inline const std::vector<std::unique_ptr<const ParsedStatement>>& GetStatements() const noexcept {
return _statements;
}
void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const override {
ParsedStatement::Stringify(stream, prefix, isLast);
stream << std::endl;
for (size_t i = 0; i < _statements.size(); i++) {
_statements[i]->Stringify(stream, prefix + (isLast ? " " : ""), i == _statements.size() - 1);
}
}
};
class ParsedClassStatement : public ParsedStatementImpl<ParsedStatementKind::Class> {
@ -74,15 +60,6 @@ namespace MalachScript::Parser {
return _body;
}
void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const override {
ParsedStatement::Stringify(stream, prefix, isLast);
stream << " " << _identifier;
stream << std::endl;
for (size_t i = 0; i < _body.size(); i++) {
_body[i]->Stringify(stream, prefix + (isLast ? " " : ""), i == _body.size() - 1);
}
}
private:
ClassAttr _classAttr;
Identifier _identifier;
@ -133,24 +110,6 @@ namespace MalachScript::Parser {
[[nodiscard]] inline bool IsArray() const noexcept { return _isArray; }
[[nodiscard]] inline bool IsHandle() const noexcept { return _isHandle; }
[[nodiscard]] inline const ScopedIdentifier& GetScopedIdentifier() const noexcept { return _scopedIdentifier; }
void Stringify(std::stringstream& stream, [[maybe_unused]] const std::string& prefix,
[[maybe_unused]] bool isLast) const override {
if (_isConst) {
stream << "const ";
}
for (auto identifier : _scopedIdentifier.GetScope()) {
stream << identifier;
stream << "::";
}
stream << _scopedIdentifier.GetIdentifier();
if (_isArray) {
stream << "[]";
}
if (_isHandle) {
stream << "&";
}
}
};
class ParsedParamListStatement : public ParsedStatementImpl<ParsedStatementKind::ParamList> {
@ -203,19 +162,6 @@ namespace MalachScript::Parser {
[[nodiscard]] const std::vector<std::unique_ptr<const ParsedParameter>>& GetParameters() const noexcept {
return _parameters;
}
void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const override {
stream << "(";
for (size_t i = 0; i < _parameters.size(); i++) {
auto& param = _parameters[i];
param->GetTypeStatement()->Stringify(stream, prefix, isLast);
stream << " " << param->GetIdentifier();
if (i != _parameters.size() - 1) {
stream << ", ";
}
}
stream << ")";
}
};
class ParsedFuncStatement : public ParsedStatementImpl<ParsedStatementKind::Func> {
@ -256,15 +202,6 @@ namespace MalachScript::Parser {
[[nodiscard]] inline const std::unique_ptr<const ParsedStatement>& GetStatBlock() const noexcept {
return _statBlock;
}
void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const override {
ParsedStatement::Stringify(stream, prefix, isLast);
stream << " " << _identifier;
GetParamList()->Stringify(stream, prefix, isLast);
stream << std::endl;
GetStatBlock()->Stringify(stream, prefix + (isLast ? " " : ""), true);
}
};
class ParsedVirtPropStatement : public ParsedStatementImpl<ParsedStatementKind::VirtProp> {
@ -327,15 +264,7 @@ namespace MalachScript::Parser {
[[nodiscard]] const std::vector<std::unique_ptr<const ParsedStatement>>& GetStatements() const noexcept {
return _statements;
}
void Stringify(std::stringstream& stream, const std::string& prefix, bool isLast) const override {
ParsedStatement::Stringify(stream, prefix, isLast);
stream << std::endl;
for (size_t i = 0; i < _statements.size(); i++) {
_statements[i]->Stringify(stream, prefix + (isLast ? " " : ""), i == _statements.size() - 1);
}
}
private:
std::vector<std::unique_ptr<const ParsedStatement>> _statements;
};

View File

@ -0,0 +1,116 @@
#ifndef MALACHSCRIPT_PARSEDSTATEMENTSTRINGIFIER_HPP
#define MALACHSCRIPT_PARSEDSTATEMENTSTRINGIFIER_HPP
#include "ParsedStatement.hpp"
namespace MalachScript::Parser {
class ParsedStatementStringifier {
static void DefaultStringify(const ParsedStatement* statement, std::stringstream& stream,
const std::string& prefix, bool isLast) {
stream << prefix;
stream << (isLast ? "└──" : "├──");
stream << ParsedStatementKindHelper::ToString(statement->GetKind());
}
static void StringifyType(const ParsedTypeStatement* statement, std::stringstream& stream) {
if (statement->IsConst()) {
stream << "const ";
}
for (auto identifier : statement->GetScopedIdentifier().GetScope()) {
stream << identifier;
stream << "::";
}
stream << statement->GetScopedIdentifier().GetIdentifier();
if (statement->IsArray()) {
stream << "[]";
}
if (statement->IsHandle()) {
stream << "&";
}
}
static void StringifyParamList(const ParsedParamListStatement* statement, std::stringstream& stream) {
stream << "(";
auto& params = statement->GetParameters();
for (size_t i = 0; i < params.size(); i++) {
auto& param = params[i];
StringifyType(param->GetTypeStatement().get(), stream);
stream << " " << param->GetIdentifier();
if (i != params.size() - 1) {
stream << ", ";
}
}
stream << ")";
}
public:
static void Stringify(const ParsedStatement* statement, std::stringstream& stream, const std::string& prefix,
bool isLast) {
DefaultStringify(statement, stream, prefix, isLast);
switch (statement->GetKind()) {
case ParsedStatementKind::Unknown: break;
case ParsedStatementKind::Script: {
stream << std::endl;
auto& stats = static_cast<const ParsedScriptStatement*>(statement)->GetStatements();
for (size_t i = 0; i < stats.size(); i++) {
Stringify(stats[i].get(), stream, prefix + (isLast ? " " : ""), i == stats.size() - 1);
}
break;
}
case ParsedStatementKind::Class: {
const auto* c = static_cast<const ParsedClassStatement*>(statement);
stream << " " << c->GetIdentifier();
stream << std::endl;
auto& stats = c->GetBody();
for (size_t i = 0; i < stats.size(); i++) {
Stringify(stats[i].get(), stream, prefix + (isLast ? " " : ""), i == stats.size() - 1);
}
break;
}
case ParsedStatementKind::TypeDef: break;
case ParsedStatementKind::Namespace: break;
case ParsedStatementKind::Type: break;
case ParsedStatementKind::ParamList: break;
case ParsedStatementKind::Func: {
const auto* func = static_cast<const ParsedFuncStatement*>(statement);
stream << " " << func->GetIdentifier();
StringifyParamList(dynamic_cast<const ParsedParamListStatement*>(func->GetParamList().get()),
stream);
stream << std::endl;
Stringify(func->GetStatBlock().get(), stream, prefix + (isLast ? " " : ""), true);
break;
}
case ParsedStatementKind::VirtProp: break;
case ParsedStatementKind::StatBlock: {
stream << std::endl;
auto& stats = static_cast<const ParsedStatBlockStatement*>(statement)->GetStatements();
for (size_t i = 0; i < stats.size(); i++) {
Stringify(stats[i].get(), stream, prefix + (isLast ? " " : ""), i == stats.size() - 1);
}
break;
}
case ParsedStatementKind::If: break;
case ParsedStatementKind::Assign: break;
case ParsedStatementKind::BinaryExpression: break;
case ParsedStatementKind::Void: break;
case ParsedStatementKind::Literal: break;
case ParsedStatementKind::Return: break;
case ParsedStatementKind::VarAccess: break;
case ParsedStatementKind::Increment: break;
case ParsedStatementKind::Decrement: break;
case ParsedStatementKind::Continue: break;
case ParsedStatementKind::Break: break;
case ParsedStatementKind::For: break;
case ParsedStatementKind::While: break;
case ParsedStatementKind::DoWhile: break;
case ParsedStatementKind::Try: break;
case ParsedStatementKind::Switch: break;
case ParsedStatementKind::Case: break;
}
}
};
}
#endif // MALACHSCRIPT_PARSEDSTATEMENTSTRINGIFIER_HPP