diff --git a/.clang-format b/.clang-format index c171fd6..300ddea 100644 --- a/.clang-format +++ b/.clang-format @@ -19,6 +19,7 @@ AllowShortLambdasOnASingleLine: All AlwaysBreakTemplateDeclarations: Yes IndentPPDirectives: BeforeHash +RequiresClausePosition: SingleLine BraceWrapping: AfterEnum: false diff --git a/src/ast.h b/src/ast.h index b4af981..623ebcd 100644 --- a/src/ast.h +++ b/src/ast.h @@ -6,6 +6,7 @@ #pragma once +#include // std::derived_from, std::same_as #include // int64_t, uint8_t #include // std::function #include @@ -52,20 +53,30 @@ protected: // ----------------------------------------- +template +concept IsValue = std::same_as || std::derived_from; + class Collection : public Value { public: virtual ~Collection() = default; void add(ValuePtr node); - const std::list& nodes() const { return m_nodes; } size_t size() const { return m_nodes.size(); } bool empty() const { return m_nodes.size() == 0; } + const std::list& nodes() const { return m_nodes; } + protected: Collection() = default; Collection(const std::list& nodes); + template + Collection(std::shared_ptr... 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& nodes); + + template + List(std::shared_ptr... nodes) + : Collection(nodes...) + { + } + virtual ~List() = default; private: @@ -92,6 +110,13 @@ class Vector final : public Collection { public: Vector() = default; Vector(const std::list& nodes); + + template + Vector(std::shared_ptr... nodes) + : Collection(nodes...) + { + } + virtual ~Vector() = default; private: diff --git a/src/eval.cpp b/src/eval.cpp index 56a3f9e..8ea634a 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -253,10 +253,7 @@ static ValuePtr startsWith(ValuePtr ast, const std::string& symbol) static ValuePtr evalQuasiQuoteImpl(ValuePtr ast) { if (is(ast.get()) || is(ast.get())) { - auto quoted_list = makePtr(); - quoted_list->add(makePtr("quote")); - quoted_list->add(ast); - return quoted_list; + return makePtr(makePtr("quote"), ast); } if (!is(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(); - const auto splice_unquote = startsWith(elt, "splice-unquote"); // (list 2 2 2) if (splice_unquote) { - list->add(makePtr("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(makePtr("concat"), splice_unquote, result); continue; } - list->add(makePtr("cons")); - list->add(evalQuasiQuoteImpl(elt)); - list->add(result); - result = list; // (cons 1 (cons 2 (cons 3 ()))) + // (cons 1 (cons 2 (cons 3 ()))) + result = makePtr(makePtr("cons"), evalQuasiQuoteImpl(elt), result); } if (is(ast.get())) { return result; } - // Wrap Vector in (vec) - auto vector = makePtr(); - vector->add(makePtr("vec")); - vector->add(result); - return vector; + // Wrap result in (vec) for Vector types + return makePtr(makePtr("vec"), result); } void Eval::evalQuasiQuote(const std::list& nodes, EnvironmentPtr env) diff --git a/src/functions.cpp b/src/functions.cpp index 5818910..76b8da2 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -172,13 +172,7 @@ ADD_FUNCTION(">=", NUMBER_COMPARE(>=)); ADD_FUNCTION( "list", { - auto list = makePtr(); - - for (auto node : nodes) { - list->add(node); - } - - return list; + return makePtr(nodes); }); ADD_FUNCTION(