Browse Source

Everywhere: Put ASTNodes into a smart pointer

master
Riyyi 2 years ago
parent
commit
9bbf238c34
  1. 14
      src/ast.cpp
  2. 44
      src/ast.h
  3. 51
      src/environment.h
  4. 51
      src/eval.cpp
  5. 12
      src/eval.h
  6. 35
      src/printer.cpp
  7. 6
      src/printer.h
  8. 105
      src/reader.cpp
  9. 33
      src/reader.h
  10. 12
      src/step1_read_print.cpp
  11. 6
      src/step2_eval.cpp

14
src/ast.cpp

@ -5,6 +5,7 @@
*/
#include <cstdint> // int64_t
#include <memory>
#include <string>
#include "ast.h"
@ -13,21 +14,14 @@
namespace blaze {
Collection::~Collection()
{
for (auto node : m_nodes) {
delete node;
}
}
void Collection::addNode(ASTNode* node)
void Collection::addNode(ASTNodePtr node)
{
m_nodes.push_back(node);
}
// -----------------------------------------
void HashMap::addElement(const std::string& key, ASTNode* value)
void HashMap::addElement(const std::string& key, ASTNodePtr value)
{
m_elements.emplace(key, value);
}
@ -78,7 +72,7 @@ Function::Function(Lambda lambda)
// -----------------------------------------
void Formatter<blaze::ASTNode*>::format(Builder& builder, blaze::ASTNode* value) const
void Formatter<blaze::ASTNodePtr>::format(Builder& builder, blaze::ASTNodePtr value) const
{
blaze::Printer printer;
return Formatter<std::string>::format(builder, printer.printNoErrorCheck(value));

44
src/ast.h

@ -8,6 +8,7 @@
#include <cstdint> // int64_t
#include <functional> // std::function
#include <memory> // std::shared_ptr
#include <span>
#include <string>
#include <string_view>
@ -19,6 +20,9 @@
namespace blaze {
class ASTNode;
typedef std::shared_ptr<ASTNode> ASTNodePtr;
class ASTNode {
public:
virtual ~ASTNode() = default;
@ -47,13 +51,13 @@ protected:
class Collection : public ASTNode {
public:
virtual ~Collection() override;
virtual ~Collection() = default;
virtual bool isCollection() const override { return true; }
void addNode(ASTNode* node);
void addNode(ASTNodePtr node);
const std::vector<ASTNode*>& nodes() const { return m_nodes; }
const std::vector<ASTNodePtr>& nodes() const { return m_nodes; }
size_t size() const { return m_nodes.size(); }
bool empty() const { return m_nodes.size() == 0; }
@ -61,7 +65,7 @@ protected:
Collection() {}
private:
std::vector<ASTNode*> m_nodes;
std::vector<ASTNodePtr> m_nodes;
};
// -----------------------------------------
@ -98,14 +102,14 @@ public:
virtual bool isHashMap() const override { return true; }
void addElement(const std::string& key, ASTNode* value);
void addElement(const std::string& key, ASTNodePtr value);
const std::unordered_map<std::string, ASTNode*>& elements() const { return m_elements; }
const std::unordered_map<std::string, ASTNodePtr>& elements() const { return m_elements; }
size_t size() const { return m_elements.size(); }
bool empty() const { return m_elements.size() == 0; }
private:
std::unordered_map<std::string, ASTNode*> m_elements;
std::unordered_map<std::string, ASTNodePtr> m_elements;
};
// -----------------------------------------
@ -113,7 +117,7 @@ private:
// "string"
class String final : public ASTNode {
public:
String(const std::string& data);
explicit String(const std::string& data);
virtual ~String() = default;
virtual bool isString() const override { return true; }
@ -129,7 +133,7 @@ private:
// :keyword
class Keyword final : public ASTNode {
public:
Keyword(const std::string& data);
explicit Keyword(const std::string& data);
virtual ~Keyword() = default;
virtual bool isKeyword() const override { return true; }
@ -144,7 +148,7 @@ private:
// 123
class Number final : public ASTNode {
public:
Number(int64_t number);
explicit Number(int64_t number);
virtual ~Number() = default;
virtual bool isNumber() const override { return true; }
@ -160,7 +164,7 @@ private:
// Symbols
class Symbol final : public ASTNode {
public:
Symbol(const std::string& symbol);
explicit Symbol(const std::string& symbol);
virtual ~Symbol() = default;
virtual bool isSymbol() const override { return true; }
@ -176,7 +180,7 @@ private:
// true, false, nil
class Value final : public ASTNode {
public:
Value(const std::string& value);
explicit Value(const std::string& value);
virtual ~Value() = default;
virtual bool isValue() const override { return true; }
@ -189,11 +193,11 @@ private:
// -----------------------------------------
using Lambda = std::function<ASTNode*(std::span<ASTNode*>)>;
using Lambda = std::function<ASTNodePtr(std::span<ASTNodePtr>)>;
class Function final : public ASTNode {
public:
Function(Lambda lambda);
explicit Function(Lambda lambda);
virtual ~Function() = default;
virtual bool isFunction() const override { return true; }
@ -206,6 +210,14 @@ private:
// -----------------------------------------
template<typename T, typename... Args>
std::shared_ptr<T> makePtr(Args&&... args)
{
return std::make_shared<T>(std::forward<Args>(args)...);
}
// -----------------------------------------
// clang-format off
template<>
inline bool ASTNode::fastIs<Collection>() const { return isCollection(); }
@ -243,6 +255,6 @@ inline bool ASTNode::fastIs<Function>() const { return isFunction(); }
// -----------------------------------------
template<>
struct ruc::format::Formatter<blaze::ASTNode*> : public Formatter<std::string> {
void format(Builder& builder, blaze::ASTNode* value) const;
struct ruc::format::Formatter<blaze::ASTNodePtr> : public Formatter<std::string> {
void format(Builder& builder, blaze::ASTNodePtr value) const;
};

51
src/environment.h

@ -8,6 +8,7 @@
#include <cstdint> // int64_t
#include <iostream>
#include <memory>
#include <span>
#include <string_view>
#include <unordered_map>
@ -27,7 +28,7 @@ public:
Environment() = default;
virtual ~Environment() = default;
ASTNode* lookup(const std::string& symbol)
ASTNodePtr lookup(const std::string& symbol)
{
m_current_key = symbol;
return m_values.find(symbol) != m_values.end() ? m_values[symbol] : nullptr;
@ -35,7 +36,7 @@ public:
protected:
std::string m_current_key;
std::unordered_map<std::string, ASTNode*> m_values;
std::unordered_map<std::string, ASTNodePtr> m_values;
};
class GlobalEnvironment final : public Environment {
@ -44,62 +45,62 @@ public:
{
// TODO: Add more native functions
// TODO: Move the functions to their own file
auto add = [](std::span<ASTNode*> nodes) -> ASTNode* {
auto add = [](std::span<ASTNodePtr> nodes) -> ASTNodePtr {
int64_t result = 0;
for (auto node : nodes) {
if (!is<Number>(node)) {
if (!is<Number>(node.get())) {
Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node));
return nullptr;
}
result += static_cast<Number*>(node)->number();
result += static_pointer_cast<Number>(node)->number();
}
return new Number(result);
return makePtr<Number>(result);
};
auto sub = [](std::span<ASTNode*> nodes) -> ASTNode* {
auto sub = [](std::span<ASTNodePtr> nodes) -> ASTNodePtr {
int64_t result = 0;
if (nodes.size() == 0) {
return new Number(0);
return makePtr<Number>(0);
}
for (auto node : nodes) {
if (!is<Number>(node)) {
if (!is<Number>(node.get())) {
Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node));
return nullptr;
}
}
// Start with the first number
result += static_cast<Number*>(nodes[0])->number();
result += static_pointer_cast<Number>(nodes[0])->number();
// Skip the first node
for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) {
result -= static_cast<Number*>(*it)->number();
result -= static_pointer_cast<Number>(*it)->number();
}
return new Number(result);
return makePtr<Number>(result);
};
auto mul = [](std::span<ASTNode*> nodes) -> ASTNode* {
auto mul = [](std::span<ASTNodePtr> nodes) -> ASTNodePtr {
int64_t result = 1;
for (auto node : nodes) {
if (!is<Number>(node)) {
if (!is<Number>(node.get())) {
Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node));
return nullptr;
}
result *= static_cast<Number*>(node)->number();
result *= static_pointer_cast<Number>(node)->number();
}
return new Number(result);
return makePtr<Number>(result);
};
auto div = [this](std::span<ASTNode*> nodes) -> ASTNode* {
auto div = [this](std::span<ASTNodePtr> nodes) -> ASTNodePtr {
double result = 0;
if (nodes.size() == 0) {
@ -108,27 +109,27 @@ public:
}
for (auto node : nodes) {
if (!is<Number>(node)) {
if (!is<Number>(node.get())) {
Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node));
return nullptr;
}
}
// Start with the first number
result += static_cast<Number*>(nodes[0])->number();
result += static_pointer_cast<Number>(nodes[0])->number();
// Skip the first node
for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) {
result /= static_cast<Number*>(*it)->number();
result /= static_pointer_cast<Number>(*it)->number();
}
return new Number((int64_t)result);
return makePtr<Number>((int64_t)result);
};
m_values.emplace("+", new Function(add));
m_values.emplace("-", new Function(sub));
m_values.emplace("*", new Function(mul));
m_values.emplace("/", new Function(div));
m_values.emplace("+", makePtr<Function>(add));
m_values.emplace("-", makePtr<Function>(sub));
m_values.emplace("*", makePtr<Function>(mul));
m_values.emplace("/", makePtr<Function>(div));
}
virtual ~GlobalEnvironment() = default;
};

51
src/eval.cpp

@ -14,7 +14,7 @@
namespace blaze {
Eval::Eval(ASTNode* ast, Environment* env)
Eval::Eval(ASTNodePtr ast, Environment* env)
: m_ast(ast)
, m_env(env)
{
@ -25,46 +25,53 @@ void Eval::eval()
m_ast = evalImpl(m_ast, m_env);
}
ASTNode* Eval::evalImpl(ASTNode* ast, Environment* env)
ASTNodePtr Eval::evalImpl(ASTNodePtr ast, Environment* env)
{
if (!is<List>(ast)) {
if (!is<List>(ast.get())) {
return evalAst(ast, env);
}
if (static_cast<List*>(ast)->empty()) {
if (static_cast<List*>(ast.get())->empty()) {
return ast;
}
return apply(static_cast<List*>(evalAst(ast, env)));
return apply(static_pointer_cast<List>(evalAst(ast, env)));
}
ASTNode* Eval::evalAst(ASTNode* ast, Environment* env)
ASTNodePtr Eval::evalAst(ASTNodePtr ast, Environment* env)
{
if (is<Symbol>(ast)) {
auto result = env->lookup(static_cast<Symbol*>(ast)->symbol());
ASTNode* ast_raw_ptr = ast.get();
if (is<Symbol>(ast_raw_ptr)) {
auto result = env->lookup(static_pointer_cast<Symbol>(ast)->symbol());
if (!result) {
Error::the().addError(format("symbol's function definition is void: {}", ast));
// TODO: Maybe add backlink to parent nodes?
if (is<List>(m_ast)) {
Error::the().addError(format("symbol's function definition is void: {}", ast_raw_ptr));
}
else {
Error::the().addError(format("symbol's value as variable is void: {}", ast_raw_ptr));
}
}
return result;
}
else if (is<List>(ast)) {
auto result = new List();
auto nodes = static_cast<List*>(ast)->nodes();
else if (is<List>(ast_raw_ptr)) {
auto result = makePtr<List>();
auto nodes = static_pointer_cast<List>(ast)->nodes();
for (auto node : nodes) {
result->addNode(evalImpl(node, env));
}
return result;
}
else if (is<Vector>(ast)) {
auto result = new Vector();
auto nodes = static_cast<Vector*>(ast)->nodes();
else if (is<Vector>(ast_raw_ptr)) {
auto result = makePtr<Vector>();
auto nodes = static_pointer_cast<Vector>(ast)->nodes();
for (auto node : nodes) {
result->addNode(evalImpl(node, env));
}
return result;
}
else if (is<HashMap>(ast)) {
auto result = new HashMap();
auto elements = static_cast<HashMap*>(ast)->elements();
else if (is<HashMap>(ast_raw_ptr)) {
auto result = makePtr<HashMap>();
auto elements = static_pointer_cast<HashMap>(ast)->elements();
for (auto& element : elements) {
result->addElement(element.first, evalImpl(element.second, env));
}
@ -74,19 +81,19 @@ ASTNode* Eval::evalAst(ASTNode* ast, Environment* env)
return ast;
}
ASTNode* Eval::apply(List* evaluated_list)
ASTNodePtr Eval::apply(std::shared_ptr<List> evaluated_list)
{
auto nodes = evaluated_list->nodes();
if (!is<Function>(nodes[0])) {
if (!is<Function>(nodes[0].get())) {
Error::the().addError(format("invalid function: {}", nodes[0]));
return nullptr;
}
// car
auto lambda = static_cast<Function*>(nodes[0])->lambda();
auto lambda = static_pointer_cast<Function>(nodes[0])->lambda();
// cdr
std::span<ASTNode*> span { nodes.data() + 1, nodes.size() - 1 };
std::span<ASTNodePtr> span { nodes.data() + 1, nodes.size() - 1 };
return lambda(span);
}

12
src/eval.h

@ -13,19 +13,19 @@ namespace blaze {
class Eval {
public:
Eval(ASTNode* ast, Environment* env);
Eval(ASTNodePtr ast, Environment* env);
virtual ~Eval() = default;
void eval();
ASTNode* ast() const { return m_ast; }
ASTNodePtr ast() const { return m_ast; }
private:
ASTNode* evalImpl(ASTNode* ast, Environment* env);
ASTNode* evalAst(ASTNode* ast, Environment* env);
ASTNode* apply(List* evaluated_list);
ASTNodePtr evalImpl(ASTNodePtr ast, Environment* env);
ASTNodePtr evalAst(ASTNodePtr ast, Environment* env);
ASTNodePtr apply(std::shared_ptr<List> evaluated_list);
ASTNode* m_ast { nullptr };
ASTNodePtr m_ast { nullptr };
Environment* m_env { nullptr };
};

35
src/printer.cpp

@ -27,7 +27,7 @@ Printer::~Printer()
// -----------------------------------------
std::string Printer::print(ASTNode* node)
std::string Printer::print(ASTNodePtr node)
{
if (Error::the().hasAnyError()) {
init();
@ -38,7 +38,7 @@ std::string Printer::print(ASTNode* node)
return printNoErrorCheck(node);
}
std::string Printer::printNoErrorCheck(ASTNode* node)
std::string Printer::printNoErrorCheck(ASTNodePtr node)
{
init();
@ -60,7 +60,7 @@ void Printer::init()
m_print = "";
}
void Printer::printImpl(ASTNode* node)
void Printer::printImpl(ASTNodePtr node)
{
auto printSpacing = [this]() -> void {
if (!m_first_node && !m_previous_node_is_list) {
@ -68,36 +68,37 @@ void Printer::printImpl(ASTNode* node)
}
};
if (is<List>(node)) {
ASTNode* node_raw_ptr = node.get();
if (is<List>(node_raw_ptr)) {
printSpacing();
m_print += '(';
m_first_node = false;
m_previous_node_is_list = true;
auto nodes = static_cast<List*>(node)->nodes();
auto nodes = static_pointer_cast<List>(node)->nodes();
for (size_t i = 0; i < nodes.size(); ++i) {
printImpl(nodes[i]);
m_previous_node_is_list = false;
}
m_print += ')';
}
else if (is<Vector>(node)) {
else if (is<Vector>(node_raw_ptr)) {
printSpacing();
m_print += '[';
m_first_node = false;
m_previous_node_is_list = true;
auto nodes = static_cast<Vector*>(node)->nodes();
auto nodes = static_pointer_cast<Vector>(node)->nodes();
for (size_t i = 0; i < nodes.size(); ++i) {
printImpl(nodes[i]);
m_previous_node_is_list = false;
}
m_print += ']';
}
else if (is<HashMap>(node)) {
else if (is<HashMap>(node_raw_ptr)) {
printSpacing();
m_print += "{";
m_first_node = false;
m_previous_node_is_list = true;
auto elements = static_cast<HashMap*>(node)->elements();
auto elements = static_pointer_cast<HashMap>(node)->elements();
for (auto it = elements.begin(); it != elements.end(); ++it) {
m_print += format("{} ", it->first.front() == 0x7f ? ":" + it->first.substr(1) : it->first); // 127
printImpl(it->second);
@ -109,22 +110,22 @@ void Printer::printImpl(ASTNode* node)
m_previous_node_is_list = false;
m_print += '}';
}
else if (is<String>(node)) {
else if (is<String>(node_raw_ptr)) {
// TODO: Implement string readably printing
printSpacing();
m_print += format("{}", static_cast<String*>(node)->data());
m_print += format("{}", static_pointer_cast<String>(node)->data());
}
else if (is<Keyword>(node)) {
else if (is<Keyword>(node_raw_ptr)) {
printSpacing();
m_print += format(":{}", static_cast<Keyword*>(node)->keyword().substr(1));
m_print += format(":{}", static_pointer_cast<Keyword>(node)->keyword().substr(1));
}
else if (is<Number>(node)) {
else if (is<Number>(node_raw_ptr)) {
printSpacing();
m_print += format("{}", static_cast<Number*>(node)->number());
m_print += format("{}", static_pointer_cast<Number>(node)->number());
}
else if (is<Symbol>(node)) {
else if (is<Symbol>(node_raw_ptr)) {
printSpacing();
m_print += format("{}", static_cast<Symbol*>(node)->symbol());
m_print += format("{}", static_pointer_cast<Symbol>(node)->symbol());
}
}

6
src/printer.h

@ -17,12 +17,12 @@ public:
Printer();
virtual ~Printer();
std::string print(ASTNode* node);
std::string printNoErrorCheck(ASTNode* node);
std::string print(ASTNodePtr node);
std::string printNoErrorCheck(ASTNodePtr node);
private:
void init();
void printImpl(ASTNode* node);
void printImpl(ASTNodePtr node);
void printError();
bool m_first_node { true };

105
src/reader.cpp

@ -7,6 +7,7 @@
#include <cstddef> // size_t
#include <cstdint> // uint64_t
#include <cstdlib> // std::strtoll
#include <memory> // makePtr, std::shared_ptr
#include <utility> // std::move
#include "error.h"
@ -55,7 +56,7 @@ void Reader::read()
}
}
ASTNode* Reader::readImpl()
ASTNodePtr Reader::readImpl()
{
if (m_tokens.size() == 0) {
return nullptr;
@ -123,7 +124,7 @@ ASTNode* Reader::readImpl()
return nullptr;
}
ASTNode* Reader::readSpliceUnquote()
ASTNodePtr Reader::readSpliceUnquote()
{
ignore(); // ~@
@ -132,18 +133,18 @@ ASTNode* Reader::readSpliceUnquote()
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("splice-unquote"));
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("splice-unquote"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readList()
ASTNodePtr Reader::readList()
{
ignore(); // (
List* list = new List();
auto list = makePtr<List>();
while (!isEOF() && peek().type != Token::Type::ParenClose) {
list->addNode(readImpl());
}
@ -156,11 +157,11 @@ ASTNode* Reader::readList()
return list;
}
ASTNode* Reader::readVector()
ASTNodePtr Reader::readVector()
{
ignore(); // [
Vector* vector = new Vector();
auto vector = makePtr<Vector>();
while (!isEOF() && peek().type != Token::Type::BracketClose) {
vector->addNode(readImpl());
}
@ -172,30 +173,30 @@ ASTNode* Reader::readVector()
return vector;
}
ASTNode* Reader::readHashMap()
ASTNodePtr Reader::readHashMap()
{
ignore(); // {
HashMap* hash_map = new HashMap();
auto hash_map = makePtr<HashMap>();
while (!isEOF() && peek().type != Token::Type::BraceClose) {
ASTNode* key = readImpl();
ASTNode* value = readImpl();
auto key = readImpl();
auto value = readImpl();
if (!key && !value) {
if (key == nullptr && value == nullptr) {
break;
}
if (!key || !value) {
if (key == nullptr || value == nullptr) {
Error::the().addError("hash-map requires an even-sized list");
return nullptr;
}
if (!is<String>(key) && !is<Keyword>(key)) {
if (!is<String>(key.get()) && !is<Keyword>(key.get())) {
Error::the().addError(format("{} is not a string or keyword", key));
return nullptr;
}
std::string keyString = is<String>(key) ? static_cast<String*>(key)->data() : static_cast<Keyword*>(key)->keyword();
std::string keyString = is<String>(key.get()) ? static_pointer_cast<String>(key)->data() : static_pointer_cast<Keyword>(key)->keyword();
hash_map->addElement(keyString, value);
}
@ -206,7 +207,7 @@ ASTNode* Reader::readHashMap()
return hash_map;
}
ASTNode* Reader::readQuote()
ASTNodePtr Reader::readQuote()
{
ignore(); // '
@ -215,14 +216,14 @@ ASTNode* Reader::readQuote()
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("quote"));
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("quote"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readQuasiQuote()
ASTNodePtr Reader::readQuasiQuote()
{
ignore(); // `
@ -231,14 +232,14 @@ ASTNode* Reader::readQuasiQuote()
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("quasiquote"));
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("quasiquote"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readUnquote()
ASTNodePtr Reader::readUnquote()
{
ignore(); // ~
@ -247,14 +248,14 @@ ASTNode* Reader::readUnquote()
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("unquote"));
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("unquote"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readWithMeta()
ASTNodePtr Reader::readWithMeta()
{
ignore(); // ^
@ -265,17 +266,17 @@ ASTNode* Reader::readWithMeta()
}
retreat();
List* list = new List();
list->addNode(new Symbol("with-meta"));
ASTNode* first = readImpl();
ASTNode* second = readImpl();
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("with-meta"));
ASTNodePtr first = readImpl();
ASTNodePtr second = readImpl();
list->addNode(second);
list->addNode(first);
return list;
}
ASTNode* Reader::readDeref()
ASTNodePtr Reader::readDeref()
{
ignore(); // @
@ -284,14 +285,14 @@ ASTNode* Reader::readDeref()
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("deref"));
auto list = makePtr<List>();
list->addNode(makePtr<Symbol>("deref"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readString()
ASTNodePtr Reader::readString()
{
std::string symbol = consume().symbol;
@ -300,24 +301,24 @@ ASTNode* Reader::readString()
Error::the().addError("expected '\"', got EOF");
}
return new String(symbol);
return makePtr<String>(symbol);
}
ASTNode* Reader::readKeyword()
ASTNodePtr Reader::readKeyword()
{
return new Keyword(consume().symbol);
return makePtr<Keyword>(consume().symbol);
}
ASTNode* Reader::readValue()
ASTNodePtr Reader::readValue()
{
Token token = consume();
char* end_ptr = nullptr;
int64_t result = std::strtoll(token.symbol.c_str(), &end_ptr, 10);
if (end_ptr == token.symbol.c_str() + token.symbol.size()) {
return new Number(result);
return makePtr<Number>(result);
}
return new Symbol(token.symbol);
return makePtr<Symbol>(token.symbol);
}
// -----------------------------------------
@ -366,12 +367,13 @@ void Reader::dump()
dumpImpl(m_node);
}
void Reader::dumpImpl(ASTNode* node)
void Reader::dumpImpl(ASTNodePtr node)
{
std::string indentation = std::string(m_indentation * 2, ' ');
if (is<List>(node)) {
List* list = static_cast<List*>(node);
ASTNode* node_raw_ptr = node.get();
if (is<List>(node_raw_ptr)) {
List* list = static_cast<List*>(node_raw_ptr);
print("{}", indentation);
print(fg(ruc::format::TerminalColor::Blue), "ListContainer");
print(" <");
@ -384,20 +386,25 @@ void Reader::dumpImpl(ASTNode* node)
m_indentation--;
return;
}
else if (is<String>(node)) {
else if (is<String>(node_raw_ptr)) {
print("{}", indentation);
print(fg(ruc::format::TerminalColor::Yellow), "StringNode");
print(" <{}>", static_cast<String*>(node)->data());
print(" <{}>", static_cast<String*>(node_raw_ptr)->data());
}
else if (is<Number>(node)) {
else if (is<Keyword>(node_raw_ptr)) {
print("{}", indentation);
print(fg(ruc::format::TerminalColor::Yellow), "KeywordNode");
print(" <{}>", static_cast<Keyword*>(node_raw_ptr)->keyword());
}
else if (is<Number>(node_raw_ptr)) {
print("{}", indentation);
print(fg(ruc::format::TerminalColor::Yellow), "NumberNode");
print(" <{}>", static_cast<Number*>(node)->number());
print(" <{}>", static_cast<Number*>(node_raw_ptr)->number());
}
else if (is<Symbol>(node)) {
else if (is<Symbol>(node_raw_ptr)) {
print("{}", indentation);
print(fg(ruc::format::TerminalColor::Yellow), "SymbolNode");
print(" <{}>", static_cast<Symbol*>(node)->symbol());
print(" <{}>", static_cast<Symbol*>(node_raw_ptr)->symbol());
}
print("\n");
}

33
src/reader.h

@ -7,6 +7,7 @@
#pragma once
#include <cstddef> // size_t
#include <memory> // std::shared_ptr
#include <vector>
#include "ast.h"
@ -24,7 +25,7 @@ public:
void dump();
ASTNode* node() { return m_node; }
ASTNodePtr node() { return m_node; }
private:
bool isEOF() const;
@ -34,21 +35,21 @@ private:
void ignore();
void retreat();
ASTNode* readImpl();
ASTNode* readSpliceUnquote(); // ~@
ASTNode* readList(); // ()
ASTNode* readVector(); // []
ASTNode* readHashMap(); // {}
ASTNode* readQuote(); // '
ASTNode* readQuasiQuote(); // `
ASTNode* readUnquote(); // ~
ASTNode* readWithMeta(); // ^
ASTNode* readDeref(); // @
ASTNode* readString(); // "foobar"
ASTNode* readKeyword(); // :keyword
ASTNode* readValue(); // number, "true", "false", "nil", symbol
ASTNodePtr readImpl();
ASTNodePtr readSpliceUnquote(); // ~@
ASTNodePtr readList(); // ()
ASTNodePtr readVector(); // []
ASTNodePtr readHashMap(); // {}
ASTNodePtr readQuote(); // '
ASTNodePtr readQuasiQuote(); // `
ASTNodePtr readUnquote(); // ~
ASTNodePtr readWithMeta(); // ^
ASTNodePtr readDeref(); // @
ASTNodePtr readString(); // "foobar"
ASTNodePtr readKeyword(); // :keyword
ASTNodePtr readValue(); // number, "true", "false", "nil", symbol
void dumpImpl(ASTNode* node);
void dumpImpl(ASTNodePtr node);
size_t m_index { 0 };
size_t m_indentation { 0 };
@ -58,7 +59,7 @@ private:
bool m_invalid_syntax { false };
bool m_is_unbalanced { false };
ASTNode* m_node { nullptr };
ASTNodePtr m_node { nullptr };
};
} // namespace blaze

12
src/step1_read_print.cpp

@ -15,7 +15,7 @@
#include "settings.h"
#if 0
auto read(std::string_view input) -> blaze::ASTNode*
auto read(std::string_view input) -> blaze::ASTNodePtr
{
blaze::Lexer lexer(input);
lexer.tokenize();
@ -32,15 +32,15 @@ auto read(std::string_view input) -> blaze::ASTNode*
return reader.node();
}
auto eval(blaze::ASTNode* ast) -> blaze::ASTNode*
auto eval(blaze::ASTNodePtr ast) -> blaze::ASTNodePtr
{
return ast;
}
auto print(blaze::ASTNode* exp) -> void
auto print(blaze::ASTNodePtr exp) -> std::string
{
blaze::Printer printer(exp);
printer.dump();
blaze::Printer printer;
return printer.print(exp);
}
auto rep(std::string_view input) -> void
@ -48,7 +48,7 @@ auto rep(std::string_view input) -> void
blaze::Error::the().clearErrors();
blaze::Error::the().setInput(input);
print(eval(read(input)));
print("{}\n", print(eval(read(input))).c_str());
}
static auto cleanup(int signal) -> void

6
src/step2_eval.cpp

@ -16,7 +16,7 @@
#include "settings.h"
#if 1
auto read(std::string_view input) -> blaze::ASTNode*
auto read(std::string_view input) -> blaze::ASTNodePtr
{
blaze::Lexer lexer(input);
lexer.tokenize();
@ -33,7 +33,7 @@ auto read(std::string_view input) -> blaze::ASTNode*
return reader.node();
}
auto eval(blaze::ASTNode* ast) -> blaze::ASTNode*
auto eval(blaze::ASTNodePtr ast) -> blaze::ASTNodePtr
{
blaze::GlobalEnvironment env;
blaze::Eval eval(ast, &env);
@ -42,7 +42,7 @@ auto eval(blaze::ASTNode* ast) -> blaze::ASTNode*
return eval.ast();
}
auto print(blaze::ASTNode* exp) -> std::string
auto print(blaze::ASTNodePtr exp) -> std::string
{
blaze::Printer printer;

Loading…
Cancel
Save