Eval+Env: Improve logic sharing between List and Vector
This commit is contained in:
@@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+7
-13
@@ -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());
|
||||||
|
|||||||
+13
-14
@@ -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;
|
||||||
|
|||||||
+4
-16
@@ -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();
|
||||||
|
|||||||
+3
-3
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user