From 68303dfe7b372caca3f96ac4cb9691ac80949739 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 19 Mar 2023 16:13:47 +0100 Subject: [PATCH] Reader: Add support for more Tokens --- src/lexer.cpp | 4 +-- src/reader.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/reader.h | 4 +++ 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/src/lexer.cpp b/src/lexer.cpp index f423764..4f4ffe8 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -105,8 +105,8 @@ bool Lexer::consumeSpliceUnquoteOrUnquote() { size_t column = m_column; - ignore(); // ~ - if (peek() == '@') { + if (peek(1) == '@') { + ignore(); // ~ m_tokens.push_back({ Token::Type::Special, m_line, column, "~@" }); } else { diff --git a/src/reader.cpp b/src/reader.cpp index 0ba5f9c..fe34d31 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -73,6 +73,9 @@ ASTNode* Reader::readImpl() } switch (peek().type) { + case Token::Type::Special: // ~@ + return readSpliceUnquote(); + break; case Token::Type::ParenOpen: // ( return readList(); break; @@ -81,6 +84,15 @@ ASTNode* Reader::readImpl() m_error_character = ')'; return nullptr; break; + case Token::Type::Quote: // ' + return readQuote(); + break; + case Token::Type::Backtick: // ` + return readQuasiQuote(); + break; + case Token::Type::Tilde: // ~ + return readUnquote(); + break; case Token::Type::String: return readString(); break; @@ -88,10 +100,28 @@ ASTNode* Reader::readImpl() return readValue(); break; default: - // Unimplemented token - VERIFY_NOT_REACHED(); - return nullptr; + break; }; + + // Unimplemented token + VERIFY_NOT_REACHED(); + return nullptr; +} + +ASTNode* Reader::readSpliceUnquote() +{ + ignore(); // ~@ + + if (isEOF()) { + Error::the().addError("expected form, got EOF"); + return nullptr; + } + + List* list = new List(); + list->addNode(new Symbol("splice-unquote")); + list->addNode(readImpl()); + + return list; } ASTNode* Reader::readList() @@ -111,6 +141,54 @@ ASTNode* Reader::readList() return list; } +ASTNode* Reader::readQuote() +{ + ignore(); // ' + + if (isEOF()) { + Error::the().addError("expected form, got EOF"); + return nullptr; + } + + List* list = new List(); + list->addNode(new Symbol("quote")); + list->addNode(readImpl()); + + return list; +} + +ASTNode* Reader::readQuasiQuote() +{ + ignore(); // ` + + if (isEOF()) { + Error::the().addError("expected form, got EOF"); + return nullptr; + } + + List* list = new List(); + list->addNode(new Symbol("quasiquote")); + list->addNode(readImpl()); + + return list; +} + +ASTNode* Reader::readUnquote() +{ + ignore(); // ~ + + if (isEOF()) { + Error::the().addError("expected form, got EOF"); + return nullptr; + } + + List* list = new List(); + list->addNode(new Symbol("unquote")); + list->addNode(readImpl()); + + return list; +} + ASTNode* Reader::readString() { std::string symbol = consume().symbol; diff --git a/src/reader.h b/src/reader.h index fbd9720..99d93e7 100644 --- a/src/reader.h +++ b/src/reader.h @@ -34,7 +34,11 @@ private: void ignore(); ASTNode* readImpl(); + ASTNode* readSpliceUnquote(); ASTNode* readList(); + ASTNode* readQuote(); + ASTNode* readQuasiQuote(); + ASTNode* readUnquote(); ASTNode* readString(); ASTNode* readValue();