Browse Source

Everywhere: Pass step1 tests by supporting more Tokens in the Reader

master
Riyyi 2 years ago
parent
commit
94dcd4c50e
  1. 6
      src/ast.cpp
  2. 56
      src/ast.h
  3. 4
      src/lexer.cpp
  4. 26
      src/printer.cpp
  5. 104
      src/reader.cpp
  6. 17
      src/reader.h

6
src/ast.cpp

@ -10,16 +10,14 @@
namespace blaze { namespace blaze {
List::~List() Collection::~Collection()
{ {
for (auto node : m_nodes) { for (auto node : m_nodes) {
delete node; delete node;
} }
} }
// ----------------------------------------- void Collection::addNode(ASTNode* node)
void List::addNode(ASTNode* node)
{ {
m_nodes.push_back(node); m_nodes.push_back(node);
} }

56
src/ast.h

@ -23,6 +23,7 @@ public:
template<typename T> template<typename T>
bool fastIs() const = delete; bool fastIs() const = delete;
virtual bool isCollection() const { return false; }
virtual bool isVector() const { return false; } virtual bool isVector() const { return false; }
virtual bool isHashMap() const { return false; } virtual bool isHashMap() const { return false; }
virtual bool isList() const { return false; } virtual bool isList() const { return false; }
@ -30,17 +31,25 @@ public:
virtual bool isNumber() const { return false; } virtual bool isNumber() const { return false; }
virtual bool isSpecialSymbol() const { return false; } virtual bool isSpecialSymbol() const { return false; }
virtual bool isSymbol() const { return false; } virtual bool isSymbol() const { return false; }
protected:
ASTNode() {}
}; };
// ----------------------------------------- // -----------------------------------------
// [] class Collection : public ASTNode {
class Vector final : public ASTNode {
public: public:
Vector(); virtual ~Collection() override;
virtual ~Vector();
virtual bool isVector() const override { return true; } virtual bool isCollection() const override { return true; }
void addNode(ASTNode* node);
const std::vector<ASTNode*>& nodes() const { return m_nodes; }
protected:
Collection() {}
private: private:
std::vector<ASTNode*> m_nodes; std::vector<ASTNode*> m_nodes;
@ -48,34 +57,38 @@ private:
// ----------------------------------------- // -----------------------------------------
// []
class Vector final : public Collection {
public:
Vector() = default;
virtual ~Vector() = default;
virtual bool isCollection() const override { return false; }
virtual bool isVector() const override { return true; }
};
// -----------------------------------------
// {} // {}
class HashMap final : public ASTNode { class HashMap final : public Collection {
public: public:
HashMap(); HashMap() = default;
virtual ~HashMap(); virtual ~HashMap() = default;
virtual bool isCollection() const override { return false; }
virtual bool isHashMap() const override { return true; } virtual bool isHashMap() const override { return true; }
private:
std::vector<ASTNode*> m_nodes;
}; };
// ----------------------------------------- // -----------------------------------------
// () // ()
class List final : public ASTNode { class List final : public Collection {
public: public:
List() = default; List() = default;
virtual ~List() override; virtual ~List() = default;
virtual bool isCollection() const override { return false; }
virtual bool isList() const override { return true; } virtual bool isList() const override { return true; }
void addNode(ASTNode* node);
const std::vector<ASTNode*>& nodes() const { return m_nodes; }
private:
std::vector<ASTNode*> m_nodes;
}; };
// ----------------------------------------- // -----------------------------------------
@ -143,6 +156,9 @@ private:
// ----------------------------------------- // -----------------------------------------
// clang-format off // clang-format off
template<>
inline bool ASTNode::fastIs<Collection>() const { return isCollection(); }
template<> template<>
inline bool ASTNode::fastIs<Vector>() const { return isVector(); } inline bool ASTNode::fastIs<Vector>() const { return isVector(); }

4
src/lexer.cpp

@ -39,10 +39,10 @@ void Lexer::tokenize()
consumeSpliceUnquoteOrUnquote(); consumeSpliceUnquoteOrUnquote();
break; break;
case '[': case '[':
m_tokens.push_back({ Token::Type::ParenOpen, m_line, m_column, "[" }); m_tokens.push_back({ Token::Type::BracketOpen, m_line, m_column, "[" });
break; break;
case ']': case ']':
m_tokens.push_back({ Token::Type::ParenClose, m_line, m_column, "]" }); m_tokens.push_back({ Token::Type::BracketClose, m_line, m_column, "]" });
break; break;
case '{': case '{':
m_tokens.push_back({ Token::Type::BraceOpen, m_line, m_column, "{" }); m_tokens.push_back({ Token::Type::BraceOpen, m_line, m_column, "{" });

26
src/printer.cpp

@ -48,7 +48,31 @@ void Printer::dumpImpl(ASTNode* node)
} }
}; };
if (is<List>(node)) { if (is<Vector>(node)) {
printSpacing();
print("[");
m_firstNode = false;
m_previousNodeIsList = true;
Vector* vector = static_cast<Vector*>(node);
for (size_t i = 0; i < vector->nodes().size(); ++i) {
dumpImpl(vector->nodes()[i]);
m_previousNodeIsList = false;
}
print("]");
}
else if (is<HashMap>(node)) {
printSpacing();
print("{{");
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]);
m_previousNodeIsList = false;
}
print("}}");
}
else if (is<List>(node)) {
printSpacing(); printSpacing();
print("("); print("(");
m_firstNode = false; m_firstNode = false;

104
src/reader.cpp

@ -59,6 +59,8 @@ void Reader::read()
case Token::Type::Value: case Token::Type::Value:
Error::the().addError("more than one sexp in input"); Error::the().addError("more than one sexp in input");
break; break;
case Token::Type::Comment:
break;
default: default:
Error::the().addError("unknown error"); Error::the().addError("unknown error");
break; break;
@ -76,6 +78,22 @@ ASTNode* Reader::readImpl()
case Token::Type::Special: // ~@ case Token::Type::Special: // ~@
return readSpliceUnquote(); return readSpliceUnquote();
break; break;
case Token::Type::BracketOpen: // [
return readVector();
break;
case Token::Type::BracketClose: // ]
m_invalid_syntax = true;
m_error_character = ']';
return nullptr;
break;
case Token::Type::BraceOpen: // {
return readHashMap();
break;
case Token::Type::BraceClose: // }
m_invalid_syntax = true;
m_error_character = '}';
return nullptr;
break;
case Token::Type::ParenOpen: // ( case Token::Type::ParenOpen: // (
return readList(); return readList();
break; break;
@ -93,9 +111,19 @@ ASTNode* Reader::readImpl()
case Token::Type::Tilde: // ~ case Token::Type::Tilde: // ~
return readUnquote(); return readUnquote();
break; break;
case Token::Type::Caret: // ^
return readWithMeta();
break;
case Token::Type::At: // @
return readDeref();
break;
case Token::Type::String: case Token::Type::String:
return readString(); return readString();
break; break;
case Token::Type::Comment: // ;
ignore();
return nullptr;
break;
case Token::Type::Value: case Token::Type::Value:
return readValue(); return readValue();
break; break;
@ -124,6 +152,40 @@ ASTNode* Reader::readSpliceUnquote()
return list; return list;
} }
ASTNode* Reader::readVector()
{
ignore(); // [
Vector* vector = new Vector();
while (!isEOF() && peek().type != Token::Type::BracketClose) {
vector->addNode(readImpl());
}
if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ]
m_error_character = ']';
m_is_unbalanced = true;
}
return vector;
}
ASTNode* Reader::readHashMap()
{
ignore(); // {
HashMap* vector = new HashMap();
while (!isEOF() && peek().type != Token::Type::BraceClose) {
vector->addNode(readImpl());
}
if (!consumeSpecific(Token { .type = Token::Type::BraceClose })) { // }
m_error_character = '}';
m_is_unbalanced = true;
}
return vector;
}
ASTNode* Reader::readList() ASTNode* Reader::readList()
{ {
ignore(); // ( ignore(); // (
@ -189,6 +251,43 @@ ASTNode* Reader::readUnquote()
return list; return list;
} }
ASTNode* Reader::readWithMeta()
{
ignore(); // ^
ignore(); // first token
if (isEOF()) { // second token
Error::the().addError("expected form, got EOF");
return nullptr;
}
retreat();
List* list = new List();
list->addNode(new Symbol("with-meta"));
ASTNode* first = readImpl();
ASTNode* second = readImpl();
list->addNode(second);
list->addNode(first);
return list;
}
ASTNode* Reader::readDeref()
{
ignore(); // @
if (isEOF()) {
Error::the().addError("expected form, got EOF");
return nullptr;
}
List* list = new List();
list->addNode(new Symbol("deref"));
list->addNode(readImpl());
return list;
}
ASTNode* Reader::readString() ASTNode* Reader::readString()
{ {
std::string symbol = consume().symbol; std::string symbol = consume().symbol;
@ -248,6 +347,11 @@ void Reader::ignore()
m_index++; m_index++;
} }
void Reader::retreat()
{
m_index--;
}
// ----------------------------------------- // -----------------------------------------
void Reader::dump() void Reader::dump()

17
src/reader.h

@ -32,14 +32,19 @@ private:
Token consume(); Token consume();
bool consumeSpecific(Token token); bool consumeSpecific(Token token);
void ignore(); void ignore();
void retreat();
ASTNode* readImpl(); ASTNode* readImpl();
ASTNode* readSpliceUnquote(); ASTNode* readSpliceUnquote(); // ~@
ASTNode* readList(); ASTNode* readVector(); // []
ASTNode* readQuote(); ASTNode* readHashMap(); // {}
ASTNode* readQuasiQuote(); ASTNode* readList(); // ()
ASTNode* readUnquote(); ASTNode* readQuote(); // '
ASTNode* readString(); ASTNode* readQuasiQuote(); // `
ASTNode* readUnquote(); // ~
ASTNode* readWithMeta(); // ^
ASTNode* readDeref(); // @
ASTNode* readString(); // "foobar"
ASTNode* readValue(); ASTNode* readValue();
void dumpImpl(ASTNode* node); void dumpImpl(ASTNode* node);

Loading…
Cancel
Save