Compare commits
2
Commits
099cda8b86
...
453ca1f796
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
453ca1f796 | ||
|
|
534d80c35d |
+1
-3
@@ -3,12 +3,10 @@
|
|||||||
#+LANGUAGE: en
|
#+LANGUAGE: en
|
||||||
#+OPTIONS: toc:nil
|
#+OPTIONS: toc:nil
|
||||||
|
|
||||||
This is my implementation of the [[https://github.com/kanaka/mal][Make A Lisp]] project, done in C++20.
|
This is an implementation of the [[https://github.com/kanaka/mal][Make A Lisp]] project, done in C++20.
|
||||||
|
|
||||||
** Usage
|
** Usage
|
||||||
|
|
||||||
Change the ~#if 0~ macro at the top of the ~stepX.cpp~ to ~#if 1~.
|
|
||||||
|
|
||||||
*** Run the REPL
|
*** Run the REPL
|
||||||
|
|
||||||
#+BEGIN_SRC shell-script
|
#+BEGIN_SRC shell-script
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ ADD_FUNCTION(
|
|||||||
return makePtr<Constant>((result) ? Constant::True : Constant::False);
|
return makePtr<Constant>((result) ? Constant::True : Constant::False);
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: (count {1}) infinite loop
|
|
||||||
ADD_FUNCTION(
|
ADD_FUNCTION(
|
||||||
"count",
|
"count",
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -256,9 +256,6 @@ bool Lexer::consumeValue()
|
|||||||
|
|
||||||
bool Lexer::consumeComment()
|
bool Lexer::consumeComment()
|
||||||
{
|
{
|
||||||
size_t column = m_column;
|
|
||||||
std::string comment;
|
|
||||||
|
|
||||||
ignore(); // ;
|
ignore(); // ;
|
||||||
|
|
||||||
static std::unordered_set<char> exit = {
|
static std::unordered_set<char> exit = {
|
||||||
@@ -275,18 +272,9 @@ bool Lexer::consumeComment()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
comment += character;
|
|
||||||
ignore();
|
ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim comment
|
|
||||||
comment.erase(comment.begin(),
|
|
||||||
std::find_if(comment.begin(), comment.end(), [](char c) { return !std::isspace(c); }));
|
|
||||||
comment.erase(std::find_if(comment.rbegin(), comment.rend(), [](char c) { return !std::isspace(c); }).base(),
|
|
||||||
comment.end());
|
|
||||||
|
|
||||||
m_tokens.push_back({ Token::Type::Comment, m_line, column, comment });
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ struct Token {
|
|||||||
String, // "foobar"
|
String, // "foobar"
|
||||||
Keyword, // :keyword
|
Keyword, // :keyword
|
||||||
Value, // number, "nil", "true", "false", symbol
|
Value, // number, "nil", "true", "false", symbol
|
||||||
Comment, // ;
|
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+11
-14
@@ -45,14 +45,7 @@ void Reader::read()
|
|||||||
|
|
||||||
// Check for multiple expressions
|
// Check for multiple expressions
|
||||||
if (!isEOF()) {
|
if (!isEOF()) {
|
||||||
Token::Type type = peek().type;
|
Error::the().add("more than one sexp in input");
|
||||||
switch (type) {
|
|
||||||
case Token::Type::Comment:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Error::the().add("more than one sexp in input");
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,10 +101,6 @@ ValuePtr Reader::readImpl()
|
|||||||
case Token::Type::Keyword: // :keyword
|
case Token::Type::Keyword: // :keyword
|
||||||
return readKeyword();
|
return readKeyword();
|
||||||
break;
|
break;
|
||||||
case Token::Type::Comment: // ;
|
|
||||||
ignore();
|
|
||||||
return nullptr;
|
|
||||||
break;
|
|
||||||
case Token::Type::Value: // true, false, nil
|
case Token::Type::Value: // true, false, nil
|
||||||
return readValue();
|
return readValue();
|
||||||
break;
|
break;
|
||||||
@@ -146,7 +135,11 @@ ValuePtr Reader::readList()
|
|||||||
|
|
||||||
auto list = makePtr<List>();
|
auto list = makePtr<List>();
|
||||||
while (!isEOF() && peek().type != Token::Type::ParenClose) {
|
while (!isEOF() && peek().type != Token::Type::ParenClose) {
|
||||||
list->add(readImpl());
|
auto node = readImpl();
|
||||||
|
if (node == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
list->add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // )
|
if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // )
|
||||||
@@ -163,7 +156,11 @@ ValuePtr Reader::readVector()
|
|||||||
|
|
||||||
auto vector = makePtr<Vector>();
|
auto vector = makePtr<Vector>();
|
||||||
while (!isEOF() && peek().type != Token::Type::BracketClose) {
|
while (!isEOF() && peek().type != Token::Type::BracketClose) {
|
||||||
vector->add(readImpl());
|
auto node = readImpl();
|
||||||
|
if (node == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
vector->add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ]
|
if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ]
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "readline.h"
|
#include "readline.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
#if 1
|
|
||||||
namespace blaze {
|
namespace blaze {
|
||||||
|
|
||||||
static blaze::Readline s_readline;
|
static blaze::Readline s_readline;
|
||||||
@@ -178,4 +177,3 @@ auto main(int argc, char* argv[]) -> int
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
Reference in New Issue
Block a user