diff --git a/src/ast.cpp b/src/ast.cpp index 1ea8548..02edd6f 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -5,6 +5,7 @@ */ #include // int64_t +#include #include #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::format(Builder& builder, blaze::ASTNode* value) const +void Formatter::format(Builder& builder, blaze::ASTNodePtr value) const { blaze::Printer printer; return Formatter::format(builder, printer.printNoErrorCheck(value)); diff --git a/src/ast.h b/src/ast.h index f00e1a0..863cb15 100644 --- a/src/ast.h +++ b/src/ast.h @@ -8,6 +8,7 @@ #include // int64_t #include // std::function +#include // std::shared_ptr #include #include #include @@ -19,6 +20,9 @@ namespace blaze { +class ASTNode; +typedef std::shared_ptr 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& nodes() const { return m_nodes; } + const std::vector& 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 m_nodes; + std::vector 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& elements() const { return m_elements; } + const std::unordered_map& 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 m_elements; + std::unordered_map 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)>; +using Lambda = std::function)>; 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 +std::shared_ptr makePtr(Args&&... args) +{ + return std::make_shared(std::forward(args)...); +} + +// ----------------------------------------- + // clang-format off template<> inline bool ASTNode::fastIs() const { return isCollection(); } @@ -243,6 +255,6 @@ inline bool ASTNode::fastIs() const { return isFunction(); } // ----------------------------------------- template<> -struct ruc::format::Formatter : public Formatter { - void format(Builder& builder, blaze::ASTNode* value) const; +struct ruc::format::Formatter : public Formatter { + void format(Builder& builder, blaze::ASTNodePtr value) const; }; diff --git a/src/environment.h b/src/environment.h index 7674d6b..992f925 100644 --- a/src/environment.h +++ b/src/environment.h @@ -8,6 +8,7 @@ #include // int64_t #include +#include #include #include #include @@ -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 m_values; + std::unordered_map 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 nodes) -> ASTNode* { + auto add = [](std::span nodes) -> ASTNodePtr { int64_t result = 0; for (auto node : nodes) { - if (!is(node)) { + if (!is(node.get())) { Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node)); return nullptr; } - result += static_cast(node)->number(); + result += static_pointer_cast(node)->number(); } - return new Number(result); + return makePtr(result); }; - auto sub = [](std::span nodes) -> ASTNode* { + auto sub = [](std::span nodes) -> ASTNodePtr { int64_t result = 0; if (nodes.size() == 0) { - return new Number(0); + return makePtr(0); } for (auto node : nodes) { - if (!is(node)) { + if (!is(node.get())) { Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node)); return nullptr; } } // Start with the first number - result += static_cast(nodes[0])->number(); + result += static_pointer_cast(nodes[0])->number(); // Skip the first node for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) { - result -= static_cast(*it)->number(); + result -= static_pointer_cast(*it)->number(); } - return new Number(result); + return makePtr(result); }; - auto mul = [](std::span nodes) -> ASTNode* { + auto mul = [](std::span nodes) -> ASTNodePtr { int64_t result = 1; for (auto node : nodes) { - if (!is(node)) { + if (!is(node.get())) { Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node)); return nullptr; } - result *= static_cast(node)->number(); + result *= static_pointer_cast(node)->number(); } - return new Number(result); + return makePtr(result); }; - auto div = [this](std::span nodes) -> ASTNode* { + auto div = [this](std::span nodes) -> ASTNodePtr { double result = 0; if (nodes.size() == 0) { @@ -108,27 +109,27 @@ public: } for (auto node : nodes) { - if (!is(node)) { + if (!is(node.get())) { Error::the().addError(format("wrong type argument: number-or-marker-p, '{}'", node)); return nullptr; } } // Start with the first number - result += static_cast(nodes[0])->number(); + result += static_pointer_cast(nodes[0])->number(); // Skip the first node for (auto it = std::next(nodes.begin()); it != nodes.end(); ++it) { - result /= static_cast(*it)->number(); + result /= static_pointer_cast(*it)->number(); } - return new Number((int64_t)result); + return makePtr((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(add)); + m_values.emplace("-", makePtr(sub)); + m_values.emplace("*", makePtr(mul)); + m_values.emplace("/", makePtr(div)); } virtual ~GlobalEnvironment() = default; }; diff --git a/src/eval.cpp b/src/eval.cpp index ff7cd48..e56ac5e 100644 --- a/src/eval.cpp +++ b/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(ast)) { + if (!is(ast.get())) { return evalAst(ast, env); } - if (static_cast(ast)->empty()) { + if (static_cast(ast.get())->empty()) { return ast; } - return apply(static_cast(evalAst(ast, env))); + return apply(static_pointer_cast(evalAst(ast, env))); } -ASTNode* Eval::evalAst(ASTNode* ast, Environment* env) +ASTNodePtr Eval::evalAst(ASTNodePtr ast, Environment* env) { - if (is(ast)) { - auto result = env->lookup(static_cast(ast)->symbol()); + ASTNode* ast_raw_ptr = ast.get(); + if (is(ast_raw_ptr)) { + auto result = env->lookup(static_pointer_cast(ast)->symbol()); if (!result) { - Error::the().addError(format("symbol's function definition is void: {}", ast)); + // TODO: Maybe add backlink to parent nodes? + if (is(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(ast)) { - auto result = new List(); - auto nodes = static_cast(ast)->nodes(); + else if (is(ast_raw_ptr)) { + auto result = makePtr(); + auto nodes = static_pointer_cast(ast)->nodes(); for (auto node : nodes) { result->addNode(evalImpl(node, env)); } return result; } - else if (is(ast)) { - auto result = new Vector(); - auto nodes = static_cast(ast)->nodes(); + else if (is(ast_raw_ptr)) { + auto result = makePtr(); + auto nodes = static_pointer_cast(ast)->nodes(); for (auto node : nodes) { result->addNode(evalImpl(node, env)); } return result; } - else if (is(ast)) { - auto result = new HashMap(); - auto elements = static_cast(ast)->elements(); + else if (is(ast_raw_ptr)) { + auto result = makePtr(); + auto elements = static_pointer_cast(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 evaluated_list) { auto nodes = evaluated_list->nodes(); - if (!is(nodes[0])) { + if (!is(nodes[0].get())) { Error::the().addError(format("invalid function: {}", nodes[0])); return nullptr; } // car - auto lambda = static_cast(nodes[0])->lambda(); + auto lambda = static_pointer_cast(nodes[0])->lambda(); // cdr - std::span span { nodes.data() + 1, nodes.size() - 1 }; + std::span span { nodes.data() + 1, nodes.size() - 1 }; return lambda(span); } diff --git a/src/eval.h b/src/eval.h index dcc9ace..06dcd2d 100644 --- a/src/eval.h +++ b/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 evaluated_list); - ASTNode* m_ast { nullptr }; + ASTNodePtr m_ast { nullptr }; Environment* m_env { nullptr }; }; diff --git a/src/printer.cpp b/src/printer.cpp index aaa01b8..b10cfb7 100644 --- a/src/printer.cpp +++ b/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(node)) { + ASTNode* node_raw_ptr = node.get(); + if (is(node_raw_ptr)) { printSpacing(); m_print += '('; m_first_node = false; m_previous_node_is_list = true; - auto nodes = static_cast(node)->nodes(); + auto nodes = static_pointer_cast(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(node)) { + else if (is(node_raw_ptr)) { printSpacing(); m_print += '['; m_first_node = false; m_previous_node_is_list = true; - auto nodes = static_cast(node)->nodes(); + auto nodes = static_pointer_cast(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(node)) { + else if (is(node_raw_ptr)) { printSpacing(); m_print += "{"; m_first_node = false; m_previous_node_is_list = true; - auto elements = static_cast(node)->elements(); + auto elements = static_pointer_cast(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(node)) { + else if (is(node_raw_ptr)) { // TODO: Implement string readably printing printSpacing(); - m_print += format("{}", static_cast(node)->data()); + m_print += format("{}", static_pointer_cast(node)->data()); } - else if (is(node)) { + else if (is(node_raw_ptr)) { printSpacing(); - m_print += format(":{}", static_cast(node)->keyword().substr(1)); + m_print += format(":{}", static_pointer_cast(node)->keyword().substr(1)); } - else if (is(node)) { + else if (is(node_raw_ptr)) { printSpacing(); - m_print += format("{}", static_cast(node)->number()); + m_print += format("{}", static_pointer_cast(node)->number()); } - else if (is(node)) { + else if (is(node_raw_ptr)) { printSpacing(); - m_print += format("{}", static_cast(node)->symbol()); + m_print += format("{}", static_pointer_cast(node)->symbol()); } } diff --git a/src/printer.h b/src/printer.h index 388ed03..e8ae6eb 100644 --- a/src/printer.h +++ b/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 }; diff --git a/src/reader.cpp b/src/reader.cpp index d74fe19..cb8ea8a 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -7,6 +7,7 @@ #include // size_t #include // uint64_t #include // std::strtoll +#include // makePtr, std::shared_ptr #include // 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->addNode(makePtr("splice-unquote")); list->addNode(readImpl()); return list; } -ASTNode* Reader::readList() +ASTNodePtr Reader::readList() { ignore(); // ( - List* list = new List(); + auto list = makePtr(); 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(); 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(); 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(key) && !is(key)) { + if (!is(key.get()) && !is(key.get())) { Error::the().addError(format("{} is not a string or keyword", key)); return nullptr; } - std::string keyString = is(key) ? static_cast(key)->data() : static_cast(key)->keyword(); + std::string keyString = is(key.get()) ? static_pointer_cast(key)->data() : static_pointer_cast(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->addNode(makePtr("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->addNode(makePtr("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->addNode(makePtr("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->addNode(makePtr("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->addNode(makePtr("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(symbol); } -ASTNode* Reader::readKeyword() +ASTNodePtr Reader::readKeyword() { - return new Keyword(consume().symbol); + return makePtr(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(result); } - return new Symbol(token.symbol); + return makePtr(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(node)) { - List* list = static_cast(node); + ASTNode* node_raw_ptr = node.get(); + if (is(node_raw_ptr)) { + List* list = static_cast(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(node)) { + else if (is(node_raw_ptr)) { print("{}", indentation); print(fg(ruc::format::TerminalColor::Yellow), "StringNode"); - print(" <{}>", static_cast(node)->data()); + print(" <{}>", static_cast(node_raw_ptr)->data()); } - else if (is(node)) { + else if (is(node_raw_ptr)) { + print("{}", indentation); + print(fg(ruc::format::TerminalColor::Yellow), "KeywordNode"); + print(" <{}>", static_cast(node_raw_ptr)->keyword()); + } + else if (is(node_raw_ptr)) { print("{}", indentation); print(fg(ruc::format::TerminalColor::Yellow), "NumberNode"); - print(" <{}>", static_cast(node)->number()); + print(" <{}>", static_cast(node_raw_ptr)->number()); } - else if (is(node)) { + else if (is(node_raw_ptr)) { print("{}", indentation); print(fg(ruc::format::TerminalColor::Yellow), "SymbolNode"); - print(" <{}>", static_cast(node)->symbol()); + print(" <{}>", static_cast(node_raw_ptr)->symbol()); } print("\n"); } diff --git a/src/reader.h b/src/reader.h index 91dfb44..981fcd5 100644 --- a/src/reader.h +++ b/src/reader.h @@ -7,6 +7,7 @@ #pragma once #include // size_t +#include // std::shared_ptr #include #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 diff --git a/src/step1_read_print.cpp b/src/step1_read_print.cpp index d28840d..479607d 100644 --- a/src/step1_read_print.cpp +++ b/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 diff --git a/src/step2_eval.cpp b/src/step2_eval.cpp index b6657eb..4efffa1 100644 --- a/src/step2_eval.cpp +++ b/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;