Browse Source

Printer: Return string instead of printing directly

master
Riyyi 2 years ago
parent
commit
d772495f1a
  1. 20
      src/ast.cpp
  2. 103
      src/printer.cpp
  3. 17
      src/printer.h
  4. 14
      src/step2_eval.cpp

20
src/ast.cpp

@ -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());
}
} }

103
src/printer.cpp

@ -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; }
std::string Printer::printNoErrorCheck(ASTNode* node)
{
init();
if (node == nullptr) {
return {};
} }
dumpImpl(m_node); printImpl(node);
print("\n");
return m_print;
}
// -----------------------------------------
void Printer::init()
{
m_first_node = true;
m_previous_node_is_list = false;
m_print = "";
} }
void Printer::dumpImpl(ASTNode* node) 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

17
src/printer.h

@ -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

14
src/step2_eval.cpp

@ -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) {

Loading…
Cancel
Save