Reader+Env: Add dump function
This commit is contained in:
+2
-2
@@ -225,9 +225,9 @@ Callable::Callable(ValuePtr meta)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
Function::Function(std::string_view name, std::string_view signature, std::string_view documentation, FunctionType function)
|
Function::Function(std::string_view name, std::string_view bindings, std::string_view documentation, FunctionType function)
|
||||||
: m_name(name)
|
: m_name(name)
|
||||||
, m_signature(signature)
|
, m_bindings(bindings)
|
||||||
, m_documentation(documentation)
|
, m_documentation(documentation)
|
||||||
, m_function(function)
|
, m_function(function)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -332,12 +332,12 @@ using FunctionType = std::function<ValuePtr(ValueVectorConstIt, ValueVectorConst
|
|||||||
|
|
||||||
class Function final : public Callable {
|
class Function final : public Callable {
|
||||||
public:
|
public:
|
||||||
Function(std::string_view name, std::string_view signature, std::string_view documentation, FunctionType function);
|
Function(std::string_view name, std::string_view bindings, std::string_view documentation, FunctionType function);
|
||||||
Function(const Function& that, ValuePtr meta);
|
Function(const Function& that, ValuePtr meta);
|
||||||
virtual ~Function() = default;
|
virtual ~Function() = default;
|
||||||
|
|
||||||
std::string_view name() const { return m_name; }
|
std::string_view name() const { return m_name; }
|
||||||
std::string_view signature() const { return m_signature; }
|
std::string_view bindings() const { return m_bindings; }
|
||||||
std::string_view documentation() const { return m_documentation; }
|
std::string_view documentation() const { return m_documentation; }
|
||||||
FunctionType function() const { return m_function; }
|
FunctionType function() const { return m_function; }
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ private:
|
|||||||
virtual bool isFunction() const override { return true; }
|
virtual bool isFunction() const override { return true; }
|
||||||
|
|
||||||
std::string_view m_name;
|
std::string_view m_name;
|
||||||
std::string_view m_signature;
|
std::string_view m_bindings;
|
||||||
std::string_view m_documentation;
|
std::string_view m_documentation;
|
||||||
const FunctionType m_function;
|
const FunctionType m_function;
|
||||||
};
|
};
|
||||||
|
|||||||
Vendored
+16
@@ -7,6 +7,7 @@
|
|||||||
#include <iterator> // std::next
|
#include <iterator> // std::next
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "reader.h"
|
||||||
#include "ruc/format/print.h"
|
#include "ruc/format/print.h"
|
||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
@@ -54,6 +55,21 @@ void Environment::loadFormat()
|
|||||||
|
|
||||||
ADD_FUNCTION("prn", "", "", PRINTER_PRINT(true));
|
ADD_FUNCTION("prn", "", "", PRINTER_PRINT(true));
|
||||||
ADD_FUNCTION("println", "", "", PRINTER_PRINT(false));
|
ADD_FUNCTION("println", "", "", PRINTER_PRINT(false));
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
ADD_FUNCTION(
|
||||||
|
"dump",
|
||||||
|
"arg",
|
||||||
|
"Print AST of the value ARG.",
|
||||||
|
{
|
||||||
|
CHECK_ARG_COUNT_IS("dump", SIZE(), 1);
|
||||||
|
|
||||||
|
Reader reader;
|
||||||
|
reader.dump(*begin);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blaze
|
} // namespace blaze
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ ValuePtr Eval::evalDescribe(const ValueVector& nodes, EnvironmentPtr env)
|
|||||||
type = "function";
|
type = "function";
|
||||||
|
|
||||||
auto function = std::static_pointer_cast<Function>(value);
|
auto function = std::static_pointer_cast<Function>(value);
|
||||||
signature += !function->signature().empty() ? " " : "";
|
signature += !function->bindings().empty() ? " " : "";
|
||||||
signature += function->signature();
|
signature += function->bindings();
|
||||||
|
|
||||||
documentation = function->documentation();
|
documentation = function->documentation();
|
||||||
}
|
}
|
||||||
|
|||||||
+94
-17
@@ -16,10 +16,15 @@
|
|||||||
|
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "reader.h"
|
#include "reader.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
|
Reader::Reader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Reader::Reader(std::vector<Token>&& tokens) noexcept
|
Reader::Reader(std::vector<Token>&& tokens) noexcept
|
||||||
: m_tokens(std::move(tokens))
|
: m_tokens(std::move(tokens))
|
||||||
{
|
{
|
||||||
@@ -362,55 +367,127 @@ void Reader::retreat()
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
void Reader::dump()
|
void Reader::dump(ValuePtr node)
|
||||||
{
|
{
|
||||||
dumpImpl(m_node);
|
m_indentation = 0;
|
||||||
|
dumpImpl((node != nullptr) ? node : m_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reader::dumpImpl(ValuePtr node)
|
void Reader::dumpImpl(ValuePtr node)
|
||||||
{
|
{
|
||||||
std::string indentation = std::string(m_indentation * 2, ' ');
|
std::string indentation = std::string(m_indentation * INDENTATION_WIDTH, ' ');
|
||||||
|
print("{}", indentation);
|
||||||
|
|
||||||
|
bool pretty_print = Settings::the().get("pretty-print") == "1";
|
||||||
|
auto blue = fg(ruc::format::TerminalColor::BrightBlue);
|
||||||
|
auto yellow = fg(ruc::format::TerminalColor::Yellow);
|
||||||
|
|
||||||
Value* node_raw_ptr = node.get();
|
Value* node_raw_ptr = node.get();
|
||||||
if (is<Collection>(node_raw_ptr)) {
|
if (is<Collection>(node_raw_ptr)) {
|
||||||
auto nodes = std::static_pointer_cast<List>(node)->nodesRead();
|
auto container = (is<List>(node_raw_ptr)) ? "List" : "Vector";
|
||||||
print("{}", indentation);
|
auto parens = (is<List>(node_raw_ptr)) ? "()" : "[]";
|
||||||
print(fg(ruc::format::TerminalColor::Blue), "{}Container", (is<List>(node_raw_ptr)) ? "List" : "Vector");
|
pretty_print ? print(blue, "{}", container) : print("{}", container);
|
||||||
print(" <");
|
print(" <");
|
||||||
print(fg(ruc::format::TerminalColor::Blue), "{}", (is<List>(node_raw_ptr)) ? "()" : "{}");
|
pretty_print ? print(blue, "{}", parens) : print("{}", parens);
|
||||||
print(">\n");
|
print(">\n");
|
||||||
m_indentation++;
|
m_indentation++;
|
||||||
|
auto nodes = std::static_pointer_cast<List>(node)->nodesRead();
|
||||||
for (auto node : nodes) {
|
for (auto node : nodes) {
|
||||||
dumpImpl(node);
|
dumpImpl(node);
|
||||||
}
|
}
|
||||||
m_indentation--;
|
m_indentation--;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (is<HashMap>(node_raw_ptr)) {
|
||||||
|
auto hash_map = std::static_pointer_cast<HashMap>(node);
|
||||||
|
auto elements = hash_map->elements();
|
||||||
|
pretty_print ? print(blue, "HashMap") : print("HashMap");
|
||||||
|
print(" <");
|
||||||
|
pretty_print ? print(blue, "{{}}") : print("{{}}");
|
||||||
|
print(">\n");
|
||||||
|
m_indentation++;
|
||||||
|
ValuePtr key_node = nullptr;
|
||||||
|
for (auto element : elements) {
|
||||||
|
bool is_keyword = element.first.front() == 0x7f; // 127
|
||||||
|
is_keyword
|
||||||
|
? dumpImpl(makePtr<Keyword>(element.first.substr(1)))
|
||||||
|
: dumpImpl(makePtr<String>(element.first));
|
||||||
|
m_indentation++;
|
||||||
|
dumpImpl(element.second);
|
||||||
|
m_indentation--;
|
||||||
|
}
|
||||||
|
m_indentation--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (is<String>(node_raw_ptr)) {
|
else if (is<String>(node_raw_ptr)) {
|
||||||
print("{}", indentation);
|
pretty_print ? print(yellow, "StringNode") : print("StringNode");
|
||||||
print(fg(ruc::format::TerminalColor::Yellow), "StringNode");
|
|
||||||
print(" <{}>", node);
|
print(" <{}>", node);
|
||||||
}
|
}
|
||||||
else if (is<Keyword>(node_raw_ptr)) {
|
else if (is<Keyword>(node_raw_ptr)) {
|
||||||
print("{}", indentation);
|
pretty_print ? print(yellow, "KeywordNode") : print("KeywordNode");
|
||||||
print(fg(ruc::format::TerminalColor::Yellow), "KeywordNode");
|
|
||||||
print(" <{}>", node);
|
print(" <{}>", node);
|
||||||
}
|
}
|
||||||
else if (is<Number>(node_raw_ptr)) {
|
else if (is<Number>(node_raw_ptr)) {
|
||||||
print("{}", indentation);
|
pretty_print ? print(yellow, "NumberNode") : print("NumberNode");
|
||||||
print(fg(ruc::format::TerminalColor::Yellow), "NumberNode");
|
|
||||||
print(" <{}>", node);
|
print(" <{}>", node);
|
||||||
}
|
}
|
||||||
else if (is<Constant>(node_raw_ptr)) {
|
else if (is<Constant>(node_raw_ptr)) {
|
||||||
print("{}", indentation);
|
pretty_print ? print(yellow, "ValueNode") : print("ValueNode");
|
||||||
print(fg(ruc::format::TerminalColor::Yellow), "ValueNode");
|
|
||||||
print(" <{}>", node);
|
print(" <{}>", node);
|
||||||
}
|
}
|
||||||
else if (is<Symbol>(node_raw_ptr)) {
|
else if (is<Symbol>(node_raw_ptr)) {
|
||||||
print("{}", indentation);
|
pretty_print ? print(yellow, "SymbolNode") : print("SymbolNode");
|
||||||
print(fg(ruc::format::TerminalColor::Yellow), "SymbolNode");
|
|
||||||
print(" <{}>", node);
|
print(" <{}>", node);
|
||||||
}
|
}
|
||||||
|
else if (is<Function>(node_raw_ptr)) {
|
||||||
|
auto function = std::static_pointer_cast<Function>(node);
|
||||||
|
pretty_print ? print(blue, "Function") : print("Function");
|
||||||
|
print(" <");
|
||||||
|
pretty_print ? print(blue, "{}", function->name()) : print("{}", function->name());
|
||||||
|
print(">\n");
|
||||||
|
|
||||||
|
m_indentation++;
|
||||||
|
indentation = std::string(m_indentation * INDENTATION_WIDTH, ' ');
|
||||||
|
|
||||||
|
// bindings
|
||||||
|
print("{}", indentation);
|
||||||
|
pretty_print ? print(blue, "Bindings") : print("Bindings");
|
||||||
|
print(" <{}>\n", function->bindings());
|
||||||
|
|
||||||
|
m_indentation--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (is<Lambda>(node_raw_ptr) || is<Macro>(node_raw_ptr)) {
|
||||||
|
auto container = (is<Lambda>(node_raw_ptr)) ? "Lambda" : "Macro";
|
||||||
|
auto lambda = std::static_pointer_cast<Lambda>(node);
|
||||||
|
pretty_print ? print(blue, "{}", container) : print("{}", container);
|
||||||
|
print(" <");
|
||||||
|
pretty_print ? print(blue, "{:p}", node_raw_ptr) : print("{:p}", node_raw_ptr);
|
||||||
|
print(">\n");
|
||||||
|
|
||||||
|
m_indentation++;
|
||||||
|
indentation = std::string(m_indentation * INDENTATION_WIDTH, ' ');
|
||||||
|
|
||||||
|
// bindings
|
||||||
|
print("{}", indentation);
|
||||||
|
pretty_print ? print(blue, "Bindings") : print("Bindings");
|
||||||
|
print(" <");
|
||||||
|
const auto& bindings = lambda->bindings();
|
||||||
|
for (size_t i = 0; i < bindings.size(); ++i) {
|
||||||
|
print("{}{}", (i > 0) ? " " : "", bindings[i]);
|
||||||
|
}
|
||||||
|
print(">\n");
|
||||||
|
|
||||||
|
// body
|
||||||
|
dumpImpl(lambda->body());
|
||||||
|
|
||||||
|
m_indentation--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (is<Atom>(node_raw_ptr)) {
|
||||||
|
pretty_print ? print(yellow, "AtomNode") : print("AtomNode");
|
||||||
|
print(" <{}>", std::static_pointer_cast<Atom>(node)->deref());
|
||||||
|
}
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -13,17 +13,20 @@
|
|||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
|
#define INDENTATION_WIDTH 2
|
||||||
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
// Parsing -> creates AST
|
// Parsing -> creates AST
|
||||||
class Reader {
|
class Reader {
|
||||||
public:
|
public:
|
||||||
|
Reader();
|
||||||
Reader(std::vector<Token>&& tokens) noexcept;
|
Reader(std::vector<Token>&& tokens) noexcept;
|
||||||
virtual ~Reader();
|
virtual ~Reader();
|
||||||
|
|
||||||
void read();
|
void read();
|
||||||
|
|
||||||
void dump();
|
void dump(ValuePtr node = nullptr);
|
||||||
|
|
||||||
ValuePtr node() { return m_node; }
|
ValuePtr node() { return m_node; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user