Browse Source

Everywhere: Pass step2 tests by supporting hash-maps

master
Riyyi 2 years ago
parent
commit
c6ea42bc5d
  1. 7
      src/ast.cpp
  2. 13
      src/ast.h
  3. 9
      src/eval.cpp
  4. 4
      src/lexer.cpp
  5. 5
      src/printer.cpp
  6. 24
      src/reader.cpp

7
src/ast.cpp

@ -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) String::String(const std::string& data)
: m_data(data) : m_data(data)
{ {

13
src/ast.h

@ -12,6 +12,7 @@
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <typeinfo> // typeid #include <typeinfo> // typeid
#include <unordered_map>
#include <vector> #include <vector>
#include "ruc/format/formatter.h" #include "ruc/format/formatter.h"
@ -90,13 +91,21 @@ public:
// ----------------------------------------- // -----------------------------------------
// {} // {}
class HashMap final : public Collection { class HashMap final : public ASTNode {
public: public:
HashMap() = default; HashMap() = default;
virtual ~HashMap() = default; virtual ~HashMap() = default;
virtual bool isCollection() const override { return false; }
virtual bool isHashMap() const override { return true; } 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;
}; };
// ----------------------------------------- // -----------------------------------------

9
src/eval.cpp

@ -63,9 +63,12 @@ ASTNode* Eval::evalAst(ASTNode* ast, Environment* env)
return result; return result;
} }
else if (is<HashMap>(ast)) { else if (is<HashMap>(ast)) {
// TODO auto result = new HashMap();
VERIFY_NOT_REACHED(); auto elements = static_cast<HashMap*>(ast)->elements();
return nullptr; for (auto& element : elements) {
result->addElement(element.first, evalImpl(element.second, env));
}
return result;
} }
return ast; return ast;

4
src/lexer.cpp

@ -216,7 +216,7 @@ bool Lexer::consumeKeyword()
bool Lexer::consumeValue() bool Lexer::consumeValue()
{ {
size_t column = m_column; size_t column = m_column;
std::string value = ""; std::string value;
static std::unordered_set<char> exit = { static std::unordered_set<char> exit = {
'[', '[',
@ -259,7 +259,7 @@ bool Lexer::consumeValue()
bool Lexer::consumeComment() bool Lexer::consumeComment()
{ {
size_t column = m_column; size_t column = m_column;
std::string comment = ""; std::string comment;
ignore(); // ; ignore(); // ;

5
src/printer.cpp

@ -78,8 +78,9 @@ void Printer::dumpImpl(ASTNode* node)
m_firstNode = false; m_firstNode = false;
m_previousNodeIsList = true; m_previousNodeIsList = true;
HashMap* hash_map = static_cast<HashMap*>(node); HashMap* hash_map = static_cast<HashMap*>(node);
for (size_t i = 0; i < hash_map->nodes().size(); ++i) { for (auto element : hash_map->elements()) {
dumpImpl(hash_map->nodes()[i]); print("{} ", element.first.front() == 0x7f ? ":" + element.first.substr(1) : element.first); // 127
dumpImpl(element.second);
m_previousNodeIsList = false; m_previousNodeIsList = false;
} }
print("}}"); print("}}");

24
src/reader.cpp

@ -193,9 +193,27 @@ ASTNode* Reader::readHashMap()
{ {
ignore(); // { ignore(); // {
HashMap* vector = new HashMap(); HashMap* hash_map = new HashMap();
while (!isEOF() && peek().type != Token::Type::BraceClose) { 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 })) { // } if (!consumeSpecific(Token { .type = Token::Type::BraceClose })) { // }
@ -203,7 +221,7 @@ ASTNode* Reader::readHashMap()
m_is_unbalanced = true; m_is_unbalanced = true;
} }
return vector; return hash_map;
} }
ASTNode* Reader::readQuote() ASTNode* Reader::readQuote()

Loading…
Cancel
Save