Browse Source

Eval+Env: Improve logic sharing between List and Vector

master
Riyyi 2 years ago
parent
commit
30b120befc
  1. 2
      src/ast.h
  2. 20
      src/eval.cpp
  3. 27
      src/functions.cpp
  4. 20
      src/printer.cpp
  5. 6
      src/reader.cpp

2
src/ast.h

@ -77,7 +77,6 @@ public:
List() = default; List() = default;
virtual ~List() = default; virtual ~List() = default;
virtual bool isCollection() const override { return false; }
virtual bool isList() const override { return true; } virtual bool isList() const override { return true; }
}; };
@ -89,7 +88,6 @@ public:
Vector() = default; Vector() = default;
virtual ~Vector() = default; virtual ~Vector() = default;
virtual bool isCollection() const override { return false; }
virtual bool isVector() const override { return true; } virtual bool isVector() const override { return true; }
}; };

20
src/eval.cpp

@ -166,21 +166,15 @@ ASTNodePtr Eval::evalLet(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env)
auto second_argument = *std::next(nodes.begin()); auto second_argument = *std::next(nodes.begin());
// First argument needs to be a List or Vector // First argument needs to be a List or Vector
if (!is<List>(first_argument.get()) && !is<Vector>(first_argument.get())) { if (!is<Collection>(first_argument.get())) {
Error::the().addError(format("wrong argument type: list, '{}'", first_argument)); Error::the().addError(format("wrong argument type: collection, '{}'", first_argument));
return nullptr; return nullptr;
} }
// Get the nodes out of the List or Vector // Get the nodes out of the List or Vector
std::list<ASTNodePtr> binding_nodes; std::list<ASTNodePtr> binding_nodes;
if (is<List>(first_argument.get())) { auto bindings = std::static_pointer_cast<Collection>(first_argument);
auto bindings = std::static_pointer_cast<List>(first_argument); binding_nodes = bindings->nodes();
binding_nodes = bindings->nodes();
}
else {
auto bindings = std::static_pointer_cast<Vector>(first_argument);
binding_nodes = bindings->nodes();
}
// List or Vector needs to have an even number of elements // List or Vector needs to have an even number of elements
size_t count = binding_nodes.size(); size_t count = binding_nodes.size();
@ -269,11 +263,11 @@ ASTNodePtr Eval::evalFn(const std::list<ASTNodePtr>& nodes, EnvironmentPtr env)
auto first_argument = *nodes.begin(); auto first_argument = *nodes.begin();
auto second_argument = *std::next(nodes.begin()); auto second_argument = *std::next(nodes.begin());
// First element needs to be a List // First element needs to be a List or Vector
AST_CAST(List, first_argument, list); AST_CAST(Collection, first_argument, collection);
std::vector<std::string> bindings; std::vector<std::string> bindings;
for (auto node : list->nodes()) { for (auto node : collection->nodes()) {
// All nodes need to be a Symbol // All nodes need to be a Symbol
AST_CAST(Symbol, node, symbol); AST_CAST(Symbol, node, symbol);
bindings.push_back(symbol->symbol()); bindings.push_back(symbol->symbol());

27
src/functions.cpp

@ -214,12 +214,12 @@ void GlobalEnvironment::isEmpty()
bool result = true; bool result = true;
for (auto node : nodes) { for (auto node : nodes) {
if (!is<List>(node.get())) { if (!is<Collection>(node.get())) {
Error::the().addError(format("wrong argument type: list, '{}'", node)); Error::the().addError(format("wrong argument type: collection, '{}'", node));
return nullptr; return nullptr;
} }
if (!std::static_pointer_cast<List>(node)->empty()) { if (!std::static_pointer_cast<Collection>(node)->empty()) {
result = false; result = false;
break; break;
} }
@ -239,18 +239,17 @@ void GlobalEnvironment::count()
return nullptr; return nullptr;
} }
auto first_argument = nodes.front();
size_t result = 0; size_t result = 0;
if (is<Value>(nodes.front().get()) && std::static_pointer_cast<Value>(nodes.front())->state() == Value::Nil) { if (is<Value>(first_argument.get()) && std::static_pointer_cast<Value>(nodes.front())->state() == Value::Nil) {
// result = 0 // result = 0
} }
else if (!is<List>(nodes.front().get())) { else if (is<Collection>(first_argument.get())) {
result = std::static_pointer_cast<List>(nodes.front())->size(); result = std::static_pointer_cast<Collection>(first_argument)->size();
}
else if (!is<Vector>(nodes.front().get())) {
result = std::static_pointer_cast<Vector>(nodes.front())->size();
} }
else { else {
Error::the().addError(format("wrong argument type: list, '{}'", nodes)); Error::the().addError(format("wrong argument type: collection, '{}'", first_argument));
return nullptr; return nullptr;
} }
@ -330,10 +329,10 @@ void GlobalEnvironment::equal()
std::function<bool(ASTNodePtr, ASTNodePtr)> equal = std::function<bool(ASTNodePtr, ASTNodePtr)> equal =
[&equal](ASTNodePtr lhs, ASTNodePtr rhs) -> bool { [&equal](ASTNodePtr lhs, ASTNodePtr rhs) -> bool {
if ((is<List>(lhs.get()) && is<List>(rhs.get())) if ((is<List>(lhs.get()) || is<Vector>(lhs.get()))
|| (is<Vector>(lhs.get()) && is<Vector>(rhs.get()))) { && (is<List>(rhs.get()) || is<Vector>(rhs.get()))) {
auto lhs_nodes = std::static_pointer_cast<List>(lhs)->nodes(); auto lhs_nodes = std::static_pointer_cast<Collection>(lhs)->nodes();
auto rhs_nodes = std::static_pointer_cast<List>(rhs)->nodes(); auto rhs_nodes = std::static_pointer_cast<Collection>(rhs)->nodes();
if (lhs_nodes.size() != rhs_nodes.size()) { if (lhs_nodes.size() != rhs_nodes.size()) {
return false; return false;

20
src/printer.cpp

@ -71,29 +71,17 @@ void Printer::printImpl(ASTNodePtr node, bool print_readably)
}; };
ASTNode* node_raw_ptr = node.get(); ASTNode* node_raw_ptr = node.get();
if (is<List>(node_raw_ptr)) { if (is<Collection>(node_raw_ptr)) {
printSpacing(); printSpacing();
m_print += '('; m_print += (is<List>(node_raw_ptr)) ? '(' : '[';
m_first_node = false; m_first_node = false;
m_previous_node_is_list = true; m_previous_node_is_list = true;
auto nodes = std::static_pointer_cast<List>(node)->nodes(); auto nodes = std::static_pointer_cast<Collection>(node)->nodes();
for (auto node : nodes) { for (auto node : nodes) {
printImpl(node, print_readably); printImpl(node, print_readably);
m_previous_node_is_list = false; m_previous_node_is_list = false;
} }
m_print += ')'; m_print += (is<List>(node_raw_ptr)) ? ')' : ']';
}
else if (is<Vector>(node_raw_ptr)) {
printSpacing();
m_print += '[';
m_first_node = false;
m_previous_node_is_list = true;
auto nodes = std::static_pointer_cast<Vector>(node)->nodes();
for (auto node : nodes) {
printImpl(node, print_readably);
m_previous_node_is_list = false;
}
m_print += ']';
} }
else if (is<HashMap>(node_raw_ptr)) { else if (is<HashMap>(node_raw_ptr)) {
printSpacing(); printSpacing();

6
src/reader.cpp

@ -377,12 +377,12 @@ void Reader::dumpImpl(ASTNodePtr node)
std::string indentation = std::string(m_indentation * 2, ' '); std::string indentation = std::string(m_indentation * 2, ' ');
ASTNode* node_raw_ptr = node.get(); ASTNode* node_raw_ptr = node.get();
if (is<List>(node_raw_ptr)) { if (is<Collection>(node_raw_ptr)) {
auto nodes = std::static_pointer_cast<List>(node)->nodes(); auto nodes = std::static_pointer_cast<List>(node)->nodes();
print("{}", indentation); print("{}", indentation);
print(fg(ruc::format::TerminalColor::Blue), "ListContainer"); print(fg(ruc::format::TerminalColor::Blue), "{}Container", (is<List>(node_raw_ptr)) ? "List" : "Vector");
print(" <"); print(" <");
print(fg(ruc::format::TerminalColor::Blue), "()"); print(fg(ruc::format::TerminalColor::Blue), "{}", (is<List>(node_raw_ptr)) ? "()" : "{}");
print(">\n"); print(">\n");
m_indentation++; m_indentation++;
for (auto node : nodes) { for (auto node : nodes) {

Loading…
Cancel
Save