Browse Source

AST+Eval: Provide convenient constructor for Collection

master
Riyyi 1 year 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
IndentPPDirectives: BeforeHash
RequiresClausePosition: SingleLine
BraceWrapping:
AfterEnum: false

27
src/ast.h

@ -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:

26
src/eval.cpp

@ -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)

8
src/functions.cpp

@ -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(

Loading…
Cancel
Save