From 86e1a630b82693af691fbf6357b59fcbc5da6932 Mon Sep 17 00:00:00 2001 From: Riyyi Date: Sun, 23 Apr 2023 15:23:14 +0200 Subject: [PATCH] AST+Eval: Prevent list copy during core function 'rest' --- src/ast.cpp | 21 +++++++++++++++++++++ src/ast.h | 11 ++++++++--- src/eval.cpp | 25 +++++++++---------------- src/forward.h | 4 ++++ src/functions.cpp | 6 +----- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/ast.cpp b/src/ast.cpp index c365374..8464be3 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -22,6 +22,11 @@ Collection::Collection(const std::list& 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& nodes) @@ -47,6 +58,11 @@ List::List(const std::list& nodes) { } +List::List(ValueListConstIt begin, ValueListConstIt end) + : Collection(begin, end) +{ +} + // ----------------------------------------- Vector::Vector(const std::list& nodes) @@ -54,6 +70,11 @@ Vector::Vector(const std::list& nodes) { } +Vector::Vector(ValueListConstIt begin, ValueListConstIt end) + : Collection(begin, end) +{ +} + // ----------------------------------------- HashMap::HashMap(const Elements& elements) diff --git a/src/ast.h b/src/ast.h index 26d6222..c51ea52 100644 --- a/src/ast.h +++ b/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& nodes() const { return m_nodes; } + ValueList rest() const; + + const ValueList& nodes() const { return m_nodes; } protected: Collection() = default; - Collection(const std::list& nodes); + Collection(const ValueList& nodes); + Collection(ValueListConstIt begin, ValueListConstIt end); template Collection(std::shared_ptr... nodes) @@ -82,7 +85,7 @@ protected: private: virtual bool isCollection() const override { return true; } - std::list m_nodes; + ValueList m_nodes; }; // ----------------------------------------- @@ -92,6 +95,7 @@ class List final : public Collection { public: List() = default; List(const std::list& nodes); + List(ValueListConstIt begin, ValueListConstIt end); template List(std::shared_ptr... nodes) @@ -112,6 +116,7 @@ class Vector final : public Collection { public: Vector() = default; Vector(const std::list& nodes); + Vector(ValueListConstIt begin, ValueListConstIt end); template Vector(std::shared_ptr... nodes) diff --git a/src/eval.cpp b/src/eval.cpp index c8002c3..2c717f0 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -79,10 +79,9 @@ ValuePtr Eval::evalImpl() } // Special forms - auto nodes = list->nodes(); - if (is(nodes.front().get())) { - auto symbol = std::static_pointer_cast(nodes.front())->symbol(); - nodes.pop_front(); + if (is(list->front().get())) { + auto symbol = std::static_pointer_cast(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(evaluated_list->nodes().front().get())) { - auto evaluated_nodes = evaluated_list->nodes(); - - // car - auto lambda = std::static_pointer_cast(evaluated_nodes.front()); - // cdr - evaluated_nodes.pop_front(); + if (is(evaluated_list->front().get())) { + auto lambda = std::static_pointer_cast(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(ast)->nodes(); - auto value = env->get(std::static_pointer_cast(nodes.front())->symbol()); + auto list = std::static_pointer_cast(ast); + auto value = env->get(std::static_pointer_cast(list->front())->symbol()); auto lambda = std::static_pointer_cast(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(); } diff --git a/src/forward.h b/src/forward.h index 3eb3175..9c40a57 100644 --- a/src/forward.h +++ b/src/forward.h @@ -6,6 +6,7 @@ #pragma once +#include #include // std::shared_ptr namespace blaze { @@ -15,6 +16,9 @@ namespace blaze { class Value; typedef std::shared_ptr ValuePtr; +typedef std::list ValueList; +typedef ValueList::iterator ValueListIt; +typedef ValueList::const_iterator ValueListConstIt; class Environment; typedef std::shared_ptr EnvironmentPtr; diff --git a/src/functions.cpp b/src/functions.cpp index 4b6a221..deb1254 100644 --- a/src/functions.cpp +++ b/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(collection_nodes); + return makePtr(collection->rest()); }); // (apply + 1 2 (list 3 4)) -> (+ 1 2 3 4)