From 30b120befcf6ee7c7dca41a0c00cd03b8e546c56 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 2 Apr 2023 11:29:18 +0200 Subject: [PATCH] Eval+Env: Improve logic sharing between List and Vector --- src/ast.h | 2 -- src/eval.cpp | 20 +++++++------------- src/functions.cpp | 27 +++++++++++++-------------- src/printer.cpp | 20 ++++---------------- src/reader.cpp | 6 +++--- 5 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/ast.h b/src/ast.h index bfe85c8..aa2060b 100644 --- a/src/ast.h +++ b/src/ast.h @@ -77,7 +77,6 @@ public: List() = default; virtual ~List() = default; - virtual bool isCollection() const override { return false; } virtual bool isList() const override { return true; } }; @@ -89,7 +88,6 @@ public: Vector() = default; virtual ~Vector() = default; - virtual bool isCollection() const override { return false; } virtual bool isVector() const override { return true; } }; diff --git a/src/eval.cpp b/src/eval.cpp index d07b1b2..ab324db 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -166,21 +166,15 @@ ASTNodePtr Eval::evalLet(const std::list& nodes, EnvironmentPtr env) auto second_argument = *std::next(nodes.begin()); // First argument needs to be a List or Vector - if (!is(first_argument.get()) && !is(first_argument.get())) { - Error::the().addError(format("wrong argument type: list, '{}'", first_argument)); + if (!is(first_argument.get())) { + Error::the().addError(format("wrong argument type: collection, '{}'", first_argument)); return nullptr; } // Get the nodes out of the List or Vector std::list binding_nodes; - if (is(first_argument.get())) { - auto bindings = std::static_pointer_cast(first_argument); - binding_nodes = bindings->nodes(); - } - else { - auto bindings = std::static_pointer_cast(first_argument); - binding_nodes = bindings->nodes(); - } + auto bindings = std::static_pointer_cast(first_argument); + binding_nodes = bindings->nodes(); // List or Vector needs to have an even number of elements size_t count = binding_nodes.size(); @@ -269,11 +263,11 @@ ASTNodePtr Eval::evalFn(const std::list& nodes, EnvironmentPtr env) auto first_argument = *nodes.begin(); auto second_argument = *std::next(nodes.begin()); - // First element needs to be a List - AST_CAST(List, first_argument, list); + // First element needs to be a List or Vector + AST_CAST(Collection, first_argument, collection); std::vector bindings; - for (auto node : list->nodes()) { + for (auto node : collection->nodes()) { // All nodes need to be a Symbol AST_CAST(Symbol, node, symbol); bindings.push_back(symbol->symbol()); diff --git a/src/functions.cpp b/src/functions.cpp index 52364c9..6c30982 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -214,12 +214,12 @@ void GlobalEnvironment::isEmpty() bool result = true; for (auto node : nodes) { - if (!is(node.get())) { - Error::the().addError(format("wrong argument type: list, '{}'", node)); + if (!is(node.get())) { + Error::the().addError(format("wrong argument type: collection, '{}'", node)); return nullptr; } - if (!std::static_pointer_cast(node)->empty()) { + if (!std::static_pointer_cast(node)->empty()) { result = false; break; } @@ -239,18 +239,17 @@ void GlobalEnvironment::count() return nullptr; } + auto first_argument = nodes.front(); + size_t result = 0; - if (is(nodes.front().get()) && std::static_pointer_cast(nodes.front())->state() == Value::Nil) { + if (is(first_argument.get()) && std::static_pointer_cast(nodes.front())->state() == Value::Nil) { // result = 0 } - else if (!is(nodes.front().get())) { - result = std::static_pointer_cast(nodes.front())->size(); - } - else if (!is(nodes.front().get())) { - result = std::static_pointer_cast(nodes.front())->size(); + else if (is(first_argument.get())) { + result = std::static_pointer_cast(first_argument)->size(); } else { - Error::the().addError(format("wrong argument type: list, '{}'", nodes)); + Error::the().addError(format("wrong argument type: collection, '{}'", first_argument)); return nullptr; } @@ -330,10 +329,10 @@ void GlobalEnvironment::equal() std::function equal = [&equal](ASTNodePtr lhs, ASTNodePtr rhs) -> bool { - if ((is(lhs.get()) && is(rhs.get())) - || (is(lhs.get()) && is(rhs.get()))) { - auto lhs_nodes = std::static_pointer_cast(lhs)->nodes(); - auto rhs_nodes = std::static_pointer_cast(rhs)->nodes(); + if ((is(lhs.get()) || is(lhs.get())) + && (is(rhs.get()) || is(rhs.get()))) { + auto lhs_nodes = std::static_pointer_cast(lhs)->nodes(); + auto rhs_nodes = std::static_pointer_cast(rhs)->nodes(); if (lhs_nodes.size() != rhs_nodes.size()) { return false; diff --git a/src/printer.cpp b/src/printer.cpp index 83ed249..7ec7dae 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -71,29 +71,17 @@ void Printer::printImpl(ASTNodePtr node, bool print_readably) }; ASTNode* node_raw_ptr = node.get(); - if (is(node_raw_ptr)) { + if (is(node_raw_ptr)) { printSpacing(); - m_print += '('; + m_print += (is(node_raw_ptr)) ? '(' : '['; m_first_node = false; m_previous_node_is_list = true; - auto nodes = std::static_pointer_cast(node)->nodes(); + auto nodes = std::static_pointer_cast(node)->nodes(); for (auto node : nodes) { printImpl(node, print_readably); m_previous_node_is_list = false; } - m_print += ')'; - } - else if (is(node_raw_ptr)) { - printSpacing(); - m_print += '['; - m_first_node = false; - m_previous_node_is_list = true; - auto nodes = std::static_pointer_cast(node)->nodes(); - for (auto node : nodes) { - printImpl(node, print_readably); - m_previous_node_is_list = false; - } - m_print += ']'; + m_print += (is(node_raw_ptr)) ? ')' : ']'; } else if (is(node_raw_ptr)) { printSpacing(); diff --git a/src/reader.cpp b/src/reader.cpp index d62048c..1549a6b 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -377,12 +377,12 @@ void Reader::dumpImpl(ASTNodePtr node) std::string indentation = std::string(m_indentation * 2, ' '); ASTNode* node_raw_ptr = node.get(); - if (is(node_raw_ptr)) { + if (is(node_raw_ptr)) { auto nodes = std::static_pointer_cast(node)->nodes(); print("{}", indentation); - print(fg(ruc::format::TerminalColor::Blue), "ListContainer"); + print(fg(ruc::format::TerminalColor::Blue), "{}Container", (is(node_raw_ptr)) ? "List" : "Vector"); print(" <"); - print(fg(ruc::format::TerminalColor::Blue), "()"); + print(fg(ruc::format::TerminalColor::Blue), "{}", (is(node_raw_ptr)) ? "()" : "{}"); print(">\n"); m_indentation++; for (auto node : nodes) {