Browse Source

AST+Eval: Provide convenient constructor for Collection

master
Riyyi 2 years ago
parent
commit
082a029957
  1. 1
      .clang-format
  2. 27
      src/ast.h
  3. 26
      src/eval.cpp
  4. 8
      src/functions.cpp

1
.clang-format

@ -19,6 +19,7 @@ AllowShortLambdasOnASingleLine: All
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
IndentPPDirectives: BeforeHash IndentPPDirectives: BeforeHash
RequiresClausePosition: SingleLine
BraceWrapping: BraceWrapping:
AfterEnum: false AfterEnum: false

27
src/ast.h

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <concepts> // std::derived_from, std::same_as
#include <cstdint> // int64_t, uint8_t #include <cstdint> // int64_t, uint8_t
#include <functional> // std::function #include <functional> // std::function
#include <list> #include <list>
@ -52,20 +53,30 @@ protected:
// ----------------------------------------- // -----------------------------------------
template<typename T>
concept IsValue = std::same_as<Value, T> || std::derived_from<T, Value>;
class Collection : public Value { class Collection : public Value {
public: public:
virtual ~Collection() = default; virtual ~Collection() = default;
void add(ValuePtr node); void add(ValuePtr node);
const std::list<ValuePtr>& nodes() const { return m_nodes; }
size_t size() const { return m_nodes.size(); } size_t size() const { return m_nodes.size(); }
bool empty() const { return m_nodes.size() == 0; } bool empty() const { return m_nodes.size() == 0; }
const std::list<ValuePtr>& nodes() const { return m_nodes; }
protected: protected:
Collection() = default; Collection() = default;
Collection(const std::list<ValuePtr>& nodes); Collection(const std::list<ValuePtr>& nodes);
template<IsValue... Ts>
Collection(std::shared_ptr<Ts>... nodes)
{
m_nodes = { nodes... };
}
private: private:
virtual bool isCollection() const override { return true; } virtual bool isCollection() const override { return true; }
@ -79,6 +90,13 @@ class List final : public Collection {
public: public:
List() = default; List() = default;
List(const std::list<ValuePtr>& nodes); List(const std::list<ValuePtr>& nodes);
template<IsValue... Ts>
List(std::shared_ptr<Ts>... nodes)
: Collection(nodes...)
{
}
virtual ~List() = default; virtual ~List() = default;
private: private:
@ -92,6 +110,13 @@ class Vector final : public Collection {
public: public:
Vector() = default; Vector() = default;
Vector(const std::list<ValuePtr>& nodes); Vector(const std::list<ValuePtr>& nodes);
template<IsValue... Ts>
Vector(std::shared_ptr<Ts>... nodes)
: Collection(nodes...)
{
}
virtual ~Vector() = default; virtual ~Vector() = default;
private: private:

26
src/eval.cpp

@ -253,10 +253,7 @@ static ValuePtr startsWith(ValuePtr ast, const std::string& symbol)
static ValuePtr evalQuasiQuoteImpl(ValuePtr ast) static ValuePtr evalQuasiQuoteImpl(ValuePtr ast)
{ {
if (is<HashMap>(ast.get()) || is<Symbol>(ast.get())) { if (is<HashMap>(ast.get()) || is<Symbol>(ast.get())) {
auto quoted_list = makePtr<List>(); return makePtr<List>(makePtr<Symbol>("quote"), ast);
quoted_list->add(makePtr<Symbol>("quote"));
quoted_list->add(ast);
return quoted_list;
} }
if (!is<Collection>(ast.get())) { if (!is<Collection>(ast.get())) {
@ -283,32 +280,23 @@ static ValuePtr evalQuasiQuoteImpl(ValuePtr ast)
for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) { for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {
const auto elt = *it; const auto elt = *it;
auto list = makePtr<List>();
const auto splice_unquote = startsWith(elt, "splice-unquote"); // (list 2 2 2) const auto splice_unquote = startsWith(elt, "splice-unquote"); // (list 2 2 2)
if (splice_unquote) { if (splice_unquote) {
list->add(makePtr<Symbol>("concat")); // (cons 1 (concat (list 2 2 2) (cons 3 ())))
list->add(splice_unquote); result = makePtr<List>(makePtr<Symbol>("concat"), splice_unquote, result);
list->add(result);
result = list; // (cons 1 (concat (list 2 2 2) (cons 3 ())))
continue; continue;
} }
list->add(makePtr<Symbol>("cons")); // (cons 1 (cons 2 (cons 3 ())))
list->add(evalQuasiQuoteImpl(elt)); result = makePtr<List>(makePtr<Symbol>("cons"), evalQuasiQuoteImpl(elt), result);
list->add(result);
result = list; // (cons 1 (cons 2 (cons 3 ())))
} }
if (is<List>(ast.get())) { if (is<List>(ast.get())) {
return result; return result;
} }
// Wrap Vector in (vec) // Wrap result in (vec) for Vector types
auto vector = makePtr<List>(); return makePtr<List>(makePtr<Symbol>("vec"), result);
vector->add(makePtr<Symbol>("vec"));
vector->add(result);
return vector;
} }
void Eval::evalQuasiQuote(const std::list<ValuePtr>& nodes, EnvironmentPtr env) void Eval::evalQuasiQuote(const std::list<ValuePtr>& nodes, EnvironmentPtr env)

8
src/functions.cpp

@ -172,13 +172,7 @@ ADD_FUNCTION(">=", NUMBER_COMPARE(>=));
ADD_FUNCTION( ADD_FUNCTION(
"list", "list",
{ {
auto list = makePtr<List>(); return makePtr<List>(nodes);
for (auto node : nodes) {
list->add(node);
}
return list;
}); });
ADD_FUNCTION( ADD_FUNCTION(

Loading…
Cancel
Save