Everywhere: Pass step2 tests by supporting hash-maps

This commit is contained in:
Riyyi
2023-03-24 22:28:31 +01:00
parent 5c5a766b7e
commit c6ea42bc5d
6 changed files with 50 additions and 12 deletions
+7
View File
@@ -26,6 +26,13 @@ void Collection::addNode(ASTNode* node)
// -----------------------------------------
void HashMap::addElement(const std::string& key, ASTNode* value)
{
m_elements.emplace(key, value);
}
// -----------------------------------------
String::String(const std::string& data)
: m_data(data)
{
+11 -2
View File
@@ -12,6 +12,7 @@
#include <string>
#include <string_view>
#include <typeinfo> // typeid
#include <unordered_map>
#include <vector>
#include "ruc/format/formatter.h"
@@ -90,13 +91,21 @@ public:
// -----------------------------------------
// {}
class HashMap final : public Collection {
class HashMap final : public ASTNode {
public:
HashMap() = default;
virtual ~HashMap() = default;
virtual bool isCollection() const override { return false; }
virtual bool isHashMap() const override { return true; }
void addElement(const std::string& key, ASTNode* value);
const std::unordered_map<std::string, ASTNode*>& 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;
};
// -----------------------------------------
+6 -3
View File
@@ -63,9 +63,12 @@ ASTNode* Eval::evalAst(ASTNode* ast, Environment* env)
return result;
}
else if (is<HashMap>(ast)) {
// TODO
VERIFY_NOT_REACHED();
return nullptr;
auto result = new HashMap();
auto elements = static_cast<HashMap*>(ast)->elements();
for (auto& element : elements) {
result->addElement(element.first, evalImpl(element.second, env));
}
return result;
}
return ast;
+2 -2
View File
@@ -216,7 +216,7 @@ bool Lexer::consumeKeyword()
bool Lexer::consumeValue()
{
size_t column = m_column;
std::string value = "";
std::string value;
static std::unordered_set<char> exit = {
'[',
@@ -259,7 +259,7 @@ bool Lexer::consumeValue()
bool Lexer::consumeComment()
{
size_t column = m_column;
std::string comment = "";
std::string comment;
ignore(); // ;
+3 -2
View File
@@ -78,8 +78,9 @@ void Printer::dumpImpl(ASTNode* node)
m_firstNode = false;
m_previousNodeIsList = true;
HashMap* hash_map = static_cast<HashMap*>(node);
for (size_t i = 0; i < hash_map->nodes().size(); ++i) {
dumpImpl(hash_map->nodes()[i]);
for (auto element : hash_map->elements()) {
print("{} ", element.first.front() == 0x7f ? ":" + element.first.substr(1) : element.first); // 127
dumpImpl(element.second);
m_previousNodeIsList = false;
}
print("}}");
+21 -3
View File
@@ -193,9 +193,27 @@ ASTNode* Reader::readHashMap()
{
ignore(); // {
HashMap* vector = new HashMap();
HashMap* hash_map = new HashMap();
while (!isEOF() && peek().type != Token::Type::BraceClose) {
vector->addNode(readImpl());
ASTNode* key = readImpl();
ASTNode* value = readImpl();
if (!key && !value) {
break;
}
if (!key || !value) {
Error::the().addError("hash-map requires an even-sized list");
return nullptr;
}
if (!is<String>(key) && !is<Keyword>(key)) {
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();
hash_map->addElement(keyString, value);
}
if (!consumeSpecific(Token { .type = Token::Type::BraceClose })) { // }
@@ -203,7 +221,7 @@ ASTNode* Reader::readHashMap()
m_is_unbalanced = true;
}
return vector;
return hash_map;
}
ASTNode* Reader::readQuote()