AST+Eval: Provide convenient constructor for Collection
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <concepts> // std::derived_from, std::same_as
|
||||
#include <cstdint> // int64_t, uint8_t
|
||||
#include <functional> // std::function
|
||||
#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 {
|
||||
public:
|
||||
virtual ~Collection() = default;
|
||||
|
||||
void add(ValuePtr node);
|
||||
|
||||
const std::list<ValuePtr>& nodes() const { return m_nodes; }
|
||||
size_t size() const { return m_nodes.size(); }
|
||||
bool empty() const { return m_nodes.size() == 0; }
|
||||
|
||||
const std::list<ValuePtr>& nodes() const { return m_nodes; }
|
||||
|
||||
protected:
|
||||
Collection() = default;
|
||||
Collection(const std::list<ValuePtr>& nodes);
|
||||
|
||||
template<IsValue... Ts>
|
||||
Collection(std::shared_ptr<Ts>... nodes)
|
||||
{
|
||||
m_nodes = { nodes... };
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool isCollection() const override { return true; }
|
||||
|
||||
@@ -79,6 +90,13 @@ class List final : public Collection {
|
||||
public:
|
||||
List() = default;
|
||||
List(const std::list<ValuePtr>& nodes);
|
||||
|
||||
template<IsValue... Ts>
|
||||
List(std::shared_ptr<Ts>... nodes)
|
||||
: Collection(nodes...)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~List() = default;
|
||||
|
||||
private:
|
||||
@@ -92,6 +110,13 @@ class Vector final : public Collection {
|
||||
public:
|
||||
Vector() = default;
|
||||
Vector(const std::list<ValuePtr>& nodes);
|
||||
|
||||
template<IsValue... Ts>
|
||||
Vector(std::shared_ptr<Ts>... nodes)
|
||||
: Collection(nodes...)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Vector() = default;
|
||||
|
||||
private:
|
||||
|
||||
+7
-19
@@ -253,10 +253,7 @@ static ValuePtr startsWith(ValuePtr ast, const std::string& symbol)
|
||||
static ValuePtr evalQuasiQuoteImpl(ValuePtr ast)
|
||||
{
|
||||
if (is<HashMap>(ast.get()) || is<Symbol>(ast.get())) {
|
||||
auto quoted_list = makePtr<List>();
|
||||
quoted_list->add(makePtr<Symbol>("quote"));
|
||||
quoted_list->add(ast);
|
||||
return quoted_list;
|
||||
return makePtr<List>(makePtr<Symbol>("quote"), ast);
|
||||
}
|
||||
|
||||
if (!is<Collection>(ast.get())) {
|
||||
@@ -283,32 +280,23 @@ static ValuePtr evalQuasiQuoteImpl(ValuePtr ast)
|
||||
for (auto it = nodes.rbegin(); it != nodes.rend(); ++it) {
|
||||
const auto elt = *it;
|
||||
|
||||
auto list = makePtr<List>();
|
||||
|
||||
const auto splice_unquote = startsWith(elt, "splice-unquote"); // (list 2 2 2)
|
||||
if (splice_unquote) {
|
||||
list->add(makePtr<Symbol>("concat"));
|
||||
list->add(splice_unquote);
|
||||
list->add(result);
|
||||
result = list; // (cons 1 (concat (list 2 2 2) (cons 3 ())))
|
||||
// (cons 1 (concat (list 2 2 2) (cons 3 ())))
|
||||
result = makePtr<List>(makePtr<Symbol>("concat"), splice_unquote, result);
|
||||
continue;
|
||||
}
|
||||
|
||||
list->add(makePtr<Symbol>("cons"));
|
||||
list->add(evalQuasiQuoteImpl(elt));
|
||||
list->add(result);
|
||||
result = list; // (cons 1 (cons 2 (cons 3 ())))
|
||||
// (cons 1 (cons 2 (cons 3 ())))
|
||||
result = makePtr<List>(makePtr<Symbol>("cons"), evalQuasiQuoteImpl(elt), result);
|
||||
}
|
||||
|
||||
if (is<List>(ast.get())) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Wrap Vector in (vec)
|
||||
auto vector = makePtr<List>();
|
||||
vector->add(makePtr<Symbol>("vec"));
|
||||
vector->add(result);
|
||||
return vector;
|
||||
// Wrap result in (vec) for Vector types
|
||||
return makePtr<List>(makePtr<Symbol>("vec"), result);
|
||||
}
|
||||
|
||||
void Eval::evalQuasiQuote(const std::list<ValuePtr>& nodes, EnvironmentPtr env)
|
||||
|
||||
+1
-7
@@ -172,13 +172,7 @@ ADD_FUNCTION(">=", NUMBER_COMPARE(>=));
|
||||
ADD_FUNCTION(
|
||||
"list",
|
||||
{
|
||||
auto list = makePtr<List>();
|
||||
|
||||
for (auto node : nodes) {
|
||||
list->add(node);
|
||||
}
|
||||
|
||||
return list;
|
||||
return makePtr<List>(nodes);
|
||||
});
|
||||
|
||||
ADD_FUNCTION(
|
||||
|
||||
Reference in New Issue
Block a user