Browse Source

AST+Eval: Prevent list copy during core function 'rest'

master
Riyyi 2 years ago
parent
commit
86e1a630b8
  1. 21
      src/ast.cpp
  2. 11
      src/ast.h
  3. 25
      src/eval.cpp
  4. 4
      src/forward.h
  5. 6
      src/functions.cpp

21
src/ast.cpp

@ -22,6 +22,11 @@ Collection::Collection(const std::list<ValuePtr>& nodes)
{ {
} }
Collection::Collection(ValueListConstIt begin, ValueListConstIt end)
: m_nodes(ValueList(begin, end))
{
}
void Collection::add(ValuePtr node) void Collection::add(ValuePtr node)
{ {
if (node == nullptr) { if (node == nullptr) {
@ -40,6 +45,12 @@ void Collection::addFront(ValuePtr node)
m_nodes.push_front(node); m_nodes.push_front(node);
} }
ValueList Collection::rest() const
{
auto start = (m_nodes.size() > 0) ? std::next(m_nodes.begin()) : m_nodes.end();
return ValueList(start, m_nodes.end());
}
// ----------------------------------------- // -----------------------------------------
List::List(const std::list<ValuePtr>& nodes) List::List(const std::list<ValuePtr>& nodes)
@ -47,6 +58,11 @@ List::List(const std::list<ValuePtr>& nodes)
{ {
} }
List::List(ValueListConstIt begin, ValueListConstIt end)
: Collection(begin, end)
{
}
// ----------------------------------------- // -----------------------------------------
Vector::Vector(const std::list<ValuePtr>& nodes) Vector::Vector(const std::list<ValuePtr>& nodes)
@ -54,6 +70,11 @@ Vector::Vector(const std::list<ValuePtr>& nodes)
{ {
} }
Vector::Vector(ValueListConstIt begin, ValueListConstIt end)
: Collection(begin, end)
{
}
// ----------------------------------------- // -----------------------------------------
HashMap::HashMap(const Elements& elements) HashMap::HashMap(const Elements& elements)

11
src/ast.h

@ -67,11 +67,14 @@ public:
bool empty() const { return m_nodes.size() == 0; } bool empty() const { return m_nodes.size() == 0; }
ValuePtr front() const { return m_nodes.front(); } ValuePtr front() const { return m_nodes.front(); }
const std::list<ValuePtr>& nodes() const { return m_nodes; } ValueList rest() const;
const ValueList& nodes() const { return m_nodes; }
protected: protected:
Collection() = default; Collection() = default;
Collection(const std::list<ValuePtr>& nodes); Collection(const ValueList& nodes);
Collection(ValueListConstIt begin, ValueListConstIt end);
template<IsValue... Ts> template<IsValue... Ts>
Collection(std::shared_ptr<Ts>... nodes) Collection(std::shared_ptr<Ts>... nodes)
@ -82,7 +85,7 @@ protected:
private: private:
virtual bool isCollection() const override { return true; } virtual bool isCollection() const override { return true; }
std::list<ValuePtr> m_nodes; ValueList m_nodes;
}; };
// ----------------------------------------- // -----------------------------------------
@ -92,6 +95,7 @@ class List final : public Collection {
public: public:
List() = default; List() = default;
List(const std::list<ValuePtr>& nodes); List(const std::list<ValuePtr>& nodes);
List(ValueListConstIt begin, ValueListConstIt end);
template<IsValue... Ts> template<IsValue... Ts>
List(std::shared_ptr<Ts>... nodes) List(std::shared_ptr<Ts>... nodes)
@ -112,6 +116,7 @@ class Vector final : public Collection {
public: public:
Vector() = default; Vector() = default;
Vector(const std::list<ValuePtr>& nodes); Vector(const std::list<ValuePtr>& nodes);
Vector(ValueListConstIt begin, ValueListConstIt end);
template<IsValue... Ts> template<IsValue... Ts>
Vector(std::shared_ptr<Ts>... nodes) Vector(std::shared_ptr<Ts>... nodes)

25
src/eval.cpp

@ -79,10 +79,9 @@ ValuePtr Eval::evalImpl()
} }
// Special forms // Special forms
auto nodes = list->nodes(); if (is<Symbol>(list->front().get())) {
if (is<Symbol>(nodes.front().get())) { auto symbol = std::static_pointer_cast<Symbol>(list->front())->symbol();
auto symbol = std::static_pointer_cast<Symbol>(nodes.front())->symbol(); const auto& nodes = list->rest();
nodes.pop_front();
if (symbol == "def!") { if (symbol == "def!") {
return evalDef(nodes, env); return evalDef(nodes, env);
} }
@ -131,16 +130,11 @@ ValuePtr Eval::evalImpl()
} }
// Regular list // Regular list
if (is<Lambda>(evaluated_list->nodes().front().get())) { if (is<Lambda>(evaluated_list->front().get())) {
auto evaluated_nodes = evaluated_list->nodes(); auto lambda = std::static_pointer_cast<Lambda>(evaluated_list->front());
// car
auto lambda = std::static_pointer_cast<Lambda>(evaluated_nodes.front());
// cdr
evaluated_nodes.pop_front();
m_ast_stack.push(lambda->body()); m_ast_stack.push(lambda->body());
m_env_stack.push(Environment::create(lambda, evaluated_nodes)); m_env_stack.push(Environment::create(lambda, evaluated_list->rest()));
continue; // TCO continue; // TCO
} }
@ -229,13 +223,12 @@ bool Eval::isMacroCall(ValuePtr ast, EnvironmentPtr env)
ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env) ValuePtr Eval::macroExpand(ValuePtr ast, EnvironmentPtr env)
{ {
while (isMacroCall(ast, env)) { while (isMacroCall(ast, env)) {
auto nodes = std::static_pointer_cast<List>(ast)->nodes(); auto list = std::static_pointer_cast<List>(ast);
auto value = env->get(std::static_pointer_cast<Symbol>(nodes.front())->symbol()); auto value = env->get(std::static_pointer_cast<Symbol>(list->front())->symbol());
auto lambda = std::static_pointer_cast<Lambda>(value); auto lambda = std::static_pointer_cast<Lambda>(value);
nodes.pop_front();
m_ast_stack.push(lambda->body()); m_ast_stack.push(lambda->body());
m_env_stack.push(Environment::create(lambda, nodes)); m_env_stack.push(Environment::create(lambda, list->rest()));
ast = evalImpl(); ast = evalImpl();
} }

4
src/forward.h

@ -6,6 +6,7 @@
#pragma once #pragma once
#include <list>
#include <memory> // std::shared_ptr #include <memory> // std::shared_ptr
namespace blaze { namespace blaze {
@ -15,6 +16,9 @@ namespace blaze {
class Value; class Value;
typedef std::shared_ptr<Value> ValuePtr; typedef std::shared_ptr<Value> ValuePtr;
typedef std::list<ValuePtr> ValueList;
typedef ValueList::iterator ValueListIt;
typedef ValueList::const_iterator ValueListConstIt;
class Environment; class Environment;
typedef std::shared_ptr<Environment> EnvironmentPtr; typedef std::shared_ptr<Environment> EnvironmentPtr;

6
src/functions.cpp

@ -500,12 +500,8 @@ ADD_FUNCTION(
} }
VALUE_CAST(collection, Collection, nodes.front()); VALUE_CAST(collection, Collection, nodes.front());
auto collection_nodes = collection->nodes();
if (collection_nodes.size() > 0) {
collection_nodes.pop_front();
}
return makePtr<List>(collection_nodes); return makePtr<List>(collection->rest());
}); });
// (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4) // (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4)

Loading…
Cancel
Save