AST+Eval: Provide convenient constructor for Collection
This commit is contained in:
@@ -19,6 +19,7 @@ AllowShortLambdasOnASingleLine: All
|
|||||||
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
IndentPPDirectives: BeforeHash
|
IndentPPDirectives: BeforeHash
|
||||||
|
RequiresClausePosition: SingleLine
|
||||||
|
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterEnum: false
|
AfterEnum: false
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
+7
-19
@@ -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)
|
||||||
|
|||||||
+1
-7
@@ -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(
|
||||||
|
|||||||
Reference in New Issue
Block a user