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)
: m_data(data)
{

13
src/ast.h

@ -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;
};
// -----------------------------------------

9
src/eval.cpp

@ -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;

4
src/lexer.cpp

@ -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(); // ;

5
src/printer.cpp

@ -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("}}");

24
src/reader.cpp

@ -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()

Loading…
Cancel
Save