Printer: Return string instead of printing directly
This commit is contained in:
+3
-17
@@ -8,6 +8,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
#include "printer.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
@@ -79,21 +80,6 @@ Function::Function(Lambda lambda)
|
|||||||
|
|
||||||
void Formatter<blaze::ASTNode*>::format(Builder& builder, blaze::ASTNode* value) const
|
void Formatter<blaze::ASTNode*>::format(Builder& builder, blaze::ASTNode* value) const
|
||||||
{
|
{
|
||||||
// TODO: Call into Printer::dumpImp(), instead of doing it manually
|
blaze::Printer printer;
|
||||||
if (is<blaze::String>(value)) {
|
return Formatter<std::string>::format(builder, printer.printNoErrorCheck(value));
|
||||||
return Formatter<std::string>::format(builder, static_cast<blaze::String*>(value)->data());
|
|
||||||
}
|
|
||||||
if (is<blaze::Keyword>(value)) {
|
|
||||||
return Formatter<std::string>::format(builder, ":" + static_cast<blaze::Keyword*>(value)->keyword().substr(1));
|
|
||||||
}
|
|
||||||
else if (is<blaze::Number>(value)) {
|
|
||||||
Formatter<int64_t> formatter { .specifier = specifier };
|
|
||||||
return formatter.format(builder, static_cast<blaze::Number*>(value)->number());
|
|
||||||
}
|
|
||||||
else if (is<blaze::Value>(value)) {
|
|
||||||
return Formatter<std::string>::format(builder, static_cast<blaze::Value*>(value)->value());
|
|
||||||
}
|
|
||||||
else if (is<blaze::Symbol>(value)) {
|
|
||||||
return Formatter<std::string>::format(builder, static_cast<blaze::Symbol*>(value)->symbol());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+60
-43
@@ -5,9 +5,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iterator> // std::next
|
#include <iterator> // std::next
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "ruc/format/print.h"
|
#include "ruc/format/format.h"
|
||||||
|
|
||||||
|
#include "ast.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "printer.h"
|
#include "printer.h"
|
||||||
@@ -15,113 +17,128 @@
|
|||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
Printer::Printer(ASTNode* node)
|
Printer::Printer()
|
||||||
: m_node(node)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Printer::~Printer()
|
Printer::~Printer()
|
||||||
{
|
{
|
||||||
delete m_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
void Printer::dump()
|
std::string Printer::print(ASTNode* node)
|
||||||
{
|
{
|
||||||
if (Error::the().hasAnyError()) {
|
if (Error::the().hasAnyError()) {
|
||||||
dumpError();
|
init();
|
||||||
return;
|
printError();
|
||||||
|
return m_print;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_node == nullptr) {
|
return printNoErrorCheck(node);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dumpImpl(m_node);
|
std::string Printer::printNoErrorCheck(ASTNode* node)
|
||||||
print("\n");
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
if (node == nullptr) {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Printer::dumpImpl(ASTNode* node)
|
printImpl(node);
|
||||||
|
|
||||||
|
return m_print;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
void Printer::init()
|
||||||
|
{
|
||||||
|
m_first_node = true;
|
||||||
|
m_previous_node_is_list = false;
|
||||||
|
m_print = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Printer::printImpl(ASTNode* node)
|
||||||
{
|
{
|
||||||
auto printSpacing = [this]() -> void {
|
auto printSpacing = [this]() -> void {
|
||||||
if (!m_firstNode && !m_previousNodeIsList) {
|
if (!m_first_node && !m_previous_node_is_list) {
|
||||||
print(" ");
|
m_print += ' ';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is<List>(node)) {
|
if (is<List>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("(");
|
m_print += '(';
|
||||||
m_firstNode = false;
|
m_first_node = false;
|
||||||
m_previousNodeIsList = true;
|
m_previous_node_is_list = true;
|
||||||
auto nodes = static_cast<List*>(node)->nodes();
|
auto nodes = static_cast<List*>(node)->nodes();
|
||||||
for (size_t i = 0; i < nodes.size(); ++i) {
|
for (size_t i = 0; i < nodes.size(); ++i) {
|
||||||
dumpImpl(nodes[i]);
|
printImpl(nodes[i]);
|
||||||
m_previousNodeIsList = false;
|
m_previous_node_is_list = false;
|
||||||
}
|
}
|
||||||
print(")");
|
m_print += ')';
|
||||||
}
|
}
|
||||||
else if (is<Vector>(node)) {
|
else if (is<Vector>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("[");
|
m_print += '[';
|
||||||
m_firstNode = false;
|
m_first_node = false;
|
||||||
m_previousNodeIsList = true;
|
m_previous_node_is_list = true;
|
||||||
auto nodes = static_cast<Vector*>(node)->nodes();
|
auto nodes = static_cast<Vector*>(node)->nodes();
|
||||||
for (size_t i = 0; i < nodes.size(); ++i) {
|
for (size_t i = 0; i < nodes.size(); ++i) {
|
||||||
dumpImpl(nodes[i]);
|
printImpl(nodes[i]);
|
||||||
m_previousNodeIsList = false;
|
m_previous_node_is_list = false;
|
||||||
}
|
}
|
||||||
print("]");
|
m_print += ']';
|
||||||
}
|
}
|
||||||
else if (is<HashMap>(node)) {
|
else if (is<HashMap>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("{{");
|
m_print += "{";
|
||||||
m_firstNode = false;
|
m_first_node = false;
|
||||||
m_previousNodeIsList = true;
|
m_previous_node_is_list = true;
|
||||||
auto elements = static_cast<HashMap*>(node)->elements();
|
auto elements = static_cast<HashMap*>(node)->elements();
|
||||||
for (auto it = elements.begin(); it != elements.end(); ++it) {
|
for (auto it = elements.begin(); it != elements.end(); ++it) {
|
||||||
print("{} ", it->first.front() == 0x7f ? ":" + it->first.substr(1) : it->first); // 127
|
m_print += format("{} ", it->first.front() == 0x7f ? ":" + it->first.substr(1) : it->first); // 127
|
||||||
dumpImpl(it->second);
|
printImpl(it->second);
|
||||||
|
|
||||||
if (it != elements.end() && std::next(it) != elements.end()) {
|
if (it != elements.end() && std::next(it) != elements.end()) {
|
||||||
print(" ");
|
m_print += ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_previousNodeIsList = false;
|
m_previous_node_is_list = false;
|
||||||
print("}}");
|
m_print += '}';
|
||||||
}
|
}
|
||||||
else if (is<String>(node)) {
|
else if (is<String>(node)) {
|
||||||
// TODO: Implement string readably printing
|
// TODO: Implement string readably printing
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("{}", static_cast<String*>(node)->data());
|
m_print += format("{}", static_cast<String*>(node)->data());
|
||||||
}
|
}
|
||||||
else if (is<Keyword>(node)) {
|
else if (is<Keyword>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print(":{}", static_cast<Keyword*>(node)->keyword().substr(1));
|
m_print += format(":{}", static_cast<Keyword*>(node)->keyword().substr(1));
|
||||||
}
|
}
|
||||||
else if (is<Number>(node)) {
|
else if (is<Number>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("{}", static_cast<Number*>(node)->number());
|
m_print += format("{}", static_cast<Number*>(node)->number());
|
||||||
}
|
}
|
||||||
else if (is<Symbol>(node)) {
|
else if (is<Symbol>(node)) {
|
||||||
printSpacing();
|
printSpacing();
|
||||||
print("{}", static_cast<Symbol*>(node)->symbol());
|
m_print += format("{}", static_cast<Symbol*>(node)->symbol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Printer::dumpError()
|
void Printer::printError()
|
||||||
{
|
{
|
||||||
print("Error: ");
|
m_print = "Error: ";
|
||||||
if (Error::the().hasTokenError()) {
|
if (Error::the().hasTokenError()) {
|
||||||
Token error = Error::the().tokenError();
|
Token error = Error::the().tokenError();
|
||||||
print("{}", error.symbol);
|
m_print += format("{}", error.symbol);
|
||||||
}
|
}
|
||||||
else if (Error::the().hasOtherError()) {
|
else if (Error::the().hasOtherError()) {
|
||||||
std::string error = Error::the().otherError();
|
std::string error = Error::the().otherError();
|
||||||
print("{}", error);
|
m_print += format("{}", error);
|
||||||
}
|
}
|
||||||
print("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+10
-7
@@ -7,24 +7,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
// Serializer -> return to string
|
// Serializer -> return to string
|
||||||
class Printer {
|
class Printer {
|
||||||
public:
|
public:
|
||||||
Printer(ASTNode* node);
|
Printer();
|
||||||
virtual ~Printer();
|
virtual ~Printer();
|
||||||
|
|
||||||
void dump();
|
std::string print(ASTNode* node);
|
||||||
|
std::string printNoErrorCheck(ASTNode* node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void dumpImpl(ASTNode* node);
|
void init();
|
||||||
void dumpError();
|
void printImpl(ASTNode* node);
|
||||||
|
void printError();
|
||||||
|
|
||||||
bool m_firstNode { true };
|
bool m_first_node { true };
|
||||||
bool m_previousNodeIsList { false };
|
bool m_previous_node_is_list { false };
|
||||||
ASTNode* m_node { nullptr };
|
std::string m_print;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
+8
-6
@@ -38,21 +38,23 @@ auto eval(blaze::ASTNode* ast) -> blaze::ASTNode*
|
|||||||
blaze::GlobalEnvironment env;
|
blaze::GlobalEnvironment env;
|
||||||
blaze::Eval eval(ast, &env);
|
blaze::Eval eval(ast, &env);
|
||||||
eval.eval();
|
eval.eval();
|
||||||
|
|
||||||
return eval.ast();
|
return eval.ast();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto print(blaze::ASTNode* exp) -> void
|
auto print(blaze::ASTNode* exp) -> std::string
|
||||||
{
|
{
|
||||||
blaze::Printer printer(exp);
|
blaze::Printer printer;
|
||||||
printer.dump();
|
|
||||||
|
return printer.print(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rep(std::string_view input) -> void
|
auto rep(std::string_view input) -> std::string
|
||||||
{
|
{
|
||||||
blaze::Error::the().clearErrors();
|
blaze::Error::the().clearErrors();
|
||||||
blaze::Error::the().setInput(input);
|
blaze::Error::the().setInput(input);
|
||||||
|
|
||||||
print(eval(read(input)));
|
return print(eval(read(input)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto cleanup(int signal) -> void
|
static auto cleanup(int signal) -> void
|
||||||
@@ -92,7 +94,7 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
if (pretty_print) {
|
if (pretty_print) {
|
||||||
print("\033[0m");
|
print("\033[0m");
|
||||||
}
|
}
|
||||||
rep(input);
|
print("{}\n", rep(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pretty_print) {
|
if (pretty_print) {
|
||||||
|
|||||||
Reference in New Issue
Block a user