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)
{
if (node == nullptr) {
@ -40,6 +45,12 @@ void Collection::addFront(ValuePtr 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)
@ -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)
@ -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)

11
src/ast.h

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

25
src/eval.cpp

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

4
src/forward.h

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

6
src/functions.cpp

@ -500,12 +500,8 @@ ADD_FUNCTION(
}
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)

Loading…
Cancel
Save