diff --git a/src/ast.cpp b/src/ast.cpp index fac190c..bbfc50e 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -51,15 +51,6 @@ Collection::Collection(const Collection& that, ValuePtr meta) { } -void Collection::add(ValuePtr node) -{ - if (node == nullptr) { - return; - } - - m_nodes.push_back(node); -} - ValueVector Collection::rest() const { auto start = (m_nodes.size() > 0) ? m_nodes.begin() + 1 : m_nodes.end(); diff --git a/src/ast.h b/src/ast.h index 1a61084..f3a86f9 100644 --- a/src/ast.h +++ b/src/ast.h @@ -94,8 +94,6 @@ class Collection : public Value { public: virtual ~Collection() = default; - void add(ValuePtr node); - // TODO: rename size -> count size_t size() const { return m_nodes.size(); } bool empty() const { return m_nodes.size() == 0; } @@ -219,6 +217,7 @@ public: virtual ~String() = default; const std::string& data() const { return m_data; } + size_t size() const { return m_data.size(); } bool empty() const { return m_data.empty(); } WITH_NO_META(); @@ -324,7 +323,7 @@ private: // ----------------------------------------- -using FunctionType = std::function; +using FunctionType = std::function; class Function final : public Callable { public: diff --git a/src/environment.cpp b/src/environment.cpp index a4f2152..39ba951 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -43,11 +43,11 @@ EnvironmentPtr Environment::create(const ValuePtr lambda, const ValueVector& arg return nullptr; } - auto list = makePtr(); + auto nodes = ValueVector(); for (; it != arguments.end(); ++it) { - list->add(*it); + nodes.push_back(*it); } - env->set(bindings[i + 1], list); + env->set(bindings[i + 1], makePtr(nodes)); return env; } diff --git a/src/eval.cpp b/src/eval.cpp index 9f4788c..89ed667 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -156,22 +156,29 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env) Error::the().add(::format("'{}' not found", ast)); return nullptr; } + return result; } else if (is(ast_raw_ptr)) { - std::shared_ptr result = nullptr; - (is(ast_raw_ptr)) ? result = makePtr() : result = makePtr(); const auto& nodes = std::static_pointer_cast(ast)->nodes(); - for (const auto& node : nodes) { - m_ast_stack.push(node); + size_t count = nodes.size(); + auto evaluated_nodes = ValueVector(count); + + for (size_t i = 0; i < count; ++i) { + m_ast_stack.push(nodes[i]); m_env_stack.push(env); ValuePtr eval_node = evalImpl(); if (eval_node == nullptr) { return nullptr; } - result->add(eval_node); + evaluated_nodes.at(i) = eval_node; } - return result; + + if (is(ast_raw_ptr)) { + return makePtr(evaluated_nodes); + } + + return makePtr(evaluated_nodes); } else if (is(ast_raw_ptr)) { auto result = makePtr(); @@ -185,6 +192,7 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env) } result->add(element.first, element_node); } + return result; } diff --git a/src/functions.cpp b/src/functions.cpp index ed00943..a2a2b58 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -39,7 +39,7 @@ static struct FUNCTION_STRUCT_NAME(unique) \ FUNCTION_STRUCT_NAME(unique)( \ symbol, \ - [](ValueVectorIt begin, ValueVectorIt end) -> ValuePtr lambda); + [](ValueVectorConstIt begin, ValueVectorConstIt end) -> ValuePtr lambda); #define ADD_FUNCTION(symbol, lambda) ADD_FUNCTION_IMPL(__LINE__, symbol, lambda); @@ -419,11 +419,11 @@ ADD_FUNCTION( VALUE_CAST(collection, Collection, (*begin)); const auto& collection_nodes = collection->nodes(); - ValueVector* result_nodes = new ValueVector(collection_nodes.size() + 1); - result_nodes->at(0) = first; - std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes->begin() + 1); + auto result_nodes = ValueVector(collection_nodes.size() + 1); + result_nodes.at(0) = first; + std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes.begin() + 1); - return makePtr(*result_nodes); + return makePtr(result_nodes); }); // (concat (list 1) (list 2 3)) -> (1 2 3) @@ -436,15 +436,15 @@ ADD_FUNCTION( count += collection->size(); } - auto result_nodes = new ValueVector(count); + auto result_nodes = ValueVector(count); size_t offset = 0; for (auto it = begin; it != end; ++it) { const auto& collection_nodes = std::static_pointer_cast(*it)->nodes(); - std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes->begin() + offset); + std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes.begin() + offset); offset += collection_nodes.size(); } - return makePtr(*result_nodes); + return makePtr(result_nodes); }); // (vec (list 1 2 3)) @@ -529,7 +529,7 @@ ADD_FUNCTION( VALUE_CAST(collection, Collection, (*std::prev(end))); - ValueVector arguments(begin + 1, end - 1); + auto arguments = ValueVector(begin + 1, end - 1); arguments.reserve(arguments.size() + collection->size()); // Append list nodes to the argument leftovers @@ -551,7 +551,7 @@ ADD_FUNCTION( return value; }); -// (map (fn* (x) (* x 2)) (list 1 2 3)) +// (map (fn* (x) (* x 2)) (list 1 2 3)) -> (2 4 6) ADD_FUNCTION( "map", { @@ -561,23 +561,23 @@ ADD_FUNCTION( VALUE_CAST(collection, Collection, (*(begin + 1))); const auto& collection_nodes = collection->nodes(); - auto result = makePtr(); + size_t count = collection->size(); + auto nodes = ValueVector(count); if (is(callable.get())) { auto function = std::static_pointer_cast(callable)->function(); - for (const auto& node : collection_nodes) { - auto arguments = ValueVector { node }; - result->add(function(arguments.begin(), arguments.end())); + for (size_t i = 0; i < count; ++i) { + nodes.at(i) = function(collection_nodes.begin() + i, collection_nodes.begin() + i + 1); } } else { auto lambda = std::static_pointer_cast(callable); - for (const auto& node : collection_nodes) { - result->add(eval(lambda->body(), Environment::create(lambda, { node }))); + for (size_t i = 0; i < count; ++i) { + nodes.at(i) = (eval(lambda->body(), Environment::create(lambda, { collection_nodes[i] }))); } } - return result; + return makePtr(nodes); }); // (throw x) @@ -697,18 +697,16 @@ ADD_FUNCTION("keyword", STRING_TO_TYPE("keyword", Keyword)); // ----------------------------------------- +// (vector 1 2 3) -> [1 2 3] ADD_FUNCTION( "vector", { auto result = makePtr(); - for (auto it = begin; it != end; ++it) { - result->add(*it); - } - - return result; + return makePtr(begin, end); }); +// (hash-map "foo" 5 :bar 10) -> {"foo" 5 :bar 10} ADD_FUNCTION( "hash-map", { @@ -796,6 +794,7 @@ ADD_FUNCTION( return makePtr(hash_map->exists(*(begin + 1))); }); +// (keys {"foo" 3 :bar 5}) -> ("foo" :bar) ADD_FUNCTION( "keys", { @@ -803,21 +802,25 @@ ADD_FUNCTION( VALUE_CAST(hash_map, HashMap, (*begin)); - auto result = makePtr(); + size_t count = hash_map->size(); + auto nodes = ValueVector(count); + size_t i = 0; auto elements = hash_map->elements(); for (auto pair : elements) { if (pair.first.front() == 0x7f) { // 127 - result->add(makePtr(pair.first.substr(1))); + nodes.at(i) = makePtr(pair.first.substr(1)); } else { - result->add(makePtr(pair.first)); + nodes.at(i) = makePtr(pair.first); } + i++; } - return result; + return makePtr(nodes); }); +// (vals {"foo" 3 :bar 5}) -> (3 5) ADD_FUNCTION( "vals", { @@ -825,14 +828,17 @@ ADD_FUNCTION( VALUE_CAST(hash_map, HashMap, (*begin)); - auto result = makePtr(); + size_t count = hash_map->size(); + auto nodes = ValueVector(count); + size_t i = 0; auto elements = hash_map->elements(); for (auto pair : elements) { - result->add(pair.second); + nodes.at(i) = pair.second; + i++; } - return result; + return makePtr(nodes); }); ADD_FUNCTION( @@ -909,19 +915,19 @@ ADD_FUNCTION( size_t collection_count = collection_nodes.size(); size_t argument_count = SIZE(); - ValueVector* nodes = new ValueVector(argument_count + collection_count); + auto nodes = ValueVector(argument_count + collection_count); if (is(collection.get())) { - std::reverse_copy(begin, end, nodes->begin()); - std::copy(collection_nodes.begin(), collection_nodes.end(), nodes->begin() + argument_count); + std::reverse_copy(begin, end, nodes.begin()); + std::copy(collection_nodes.begin(), collection_nodes.end(), nodes.begin() + argument_count); - return makePtr(*nodes); + return makePtr(nodes); } - std::copy(collection_nodes.begin(), collection_nodes.end(), nodes->begin()); - std::copy(begin, end, nodes->begin() + collection_count); + std::copy(collection_nodes.begin(), collection_nodes.end(), nodes.begin()); + std::copy(begin, end, nodes.begin() + collection_count); - return makePtr(*nodes); + return makePtr(nodes); }); // (seq '(1 2 3)) -> (1 2 3) @@ -958,14 +964,15 @@ ADD_FUNCTION( return makePtr(); } - auto result = makePtr(); + size_t count = string->size(); + auto nodes = ValueVector(count); const auto& data = string->data(); - for (const auto& character : data) { - result->add(makePtr(character)); + for (size_t i = 0; i < count; ++i) { + nodes.at(i) = makePtr(data[i]); } - return result; + return makePtr(nodes); } Error::the().add(::format("wrong argument type: Collection or String, {}", front)); diff --git a/src/reader.cpp b/src/reader.cpp index dfd81ab..5011185 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -122,24 +122,24 @@ ValuePtr Reader::readSpliceUnquote() return nullptr; } - auto list = makePtr(); - list->add(makePtr("splice-unquote")); - list->add(readImpl()); + auto nodes = ValueVector(2); + nodes.at(0) = makePtr("splice-unquote"); + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readList() { ignore(); // ( - auto list = makePtr(); + auto nodes = ValueVector(); while (!isEOF() && peek().type != Token::Type::ParenClose) { auto node = readImpl(); if (node == nullptr) { return nullptr; } - list->add(node); + nodes.push_back(node); } if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // ) @@ -147,27 +147,27 @@ ValuePtr Reader::readList() return nullptr; } - return list; + return makePtr(nodes); } ValuePtr Reader::readVector() { ignore(); // [ - auto vector = makePtr(); + auto nodes = ValueVector(); while (!isEOF() && peek().type != Token::Type::BracketClose) { auto node = readImpl(); if (node == nullptr) { return nullptr; } - vector->add(node); + nodes.push_back(node); } if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ] Error::the().add("expected ']', got EOF"); } - return vector; + return makePtr(nodes); } ValuePtr Reader::readHashMap() @@ -213,11 +213,11 @@ ValuePtr Reader::readQuote() return nullptr; } - auto list = makePtr(); - list->add(makePtr("quote")); - list->add(readImpl()); + auto nodes = ValueVector(2); + nodes.at(0) = makePtr("quote"); + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readQuasiQuote() @@ -229,11 +229,11 @@ ValuePtr Reader::readQuasiQuote() return nullptr; } - auto list = makePtr(); - list->add(makePtr("quasiquote")); - list->add(readImpl()); + auto nodes = ValueVector(2); + nodes.at(0) = makePtr("quasiquote"); + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readUnquote() @@ -245,11 +245,11 @@ ValuePtr Reader::readUnquote() return nullptr; } - auto list = makePtr(); - list->add(makePtr("unquote")); - list->add(readImpl()); + auto nodes = ValueVector(2); + nodes.at(0) = makePtr("unquote"); + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readWithMeta() @@ -263,14 +263,12 @@ ValuePtr Reader::readWithMeta() } retreat(); - auto list = makePtr(); - list->add(makePtr("with-meta")); - ValuePtr first = readImpl(); - ValuePtr second = readImpl(); - list->add(second); - list->add(first); + auto nodes = ValueVector(3); + nodes.at(0) = makePtr("with-meta"); + nodes.at(2) = readImpl(); // Note: second Value is read first + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readDeref() @@ -282,11 +280,11 @@ ValuePtr Reader::readDeref() return nullptr; } - auto list = makePtr(); - list->add(makePtr("deref")); - list->add(readImpl()); + auto nodes = ValueVector(2); + nodes.at(0) = makePtr("deref"); + nodes.at(1) = readImpl(); - return list; + return makePtr(nodes); } ValuePtr Reader::readString() diff --git a/src/step6_file.cpp b/src/step6_file.cpp index 07c2894..e2f1cb9 100644 --- a/src/step6_file.cpp +++ b/src/step6_file.cpp @@ -93,13 +93,14 @@ static auto installLambdas(EnvironmentPtr env) -> void static auto makeArgv(EnvironmentPtr env, std::vector arguments) -> void { - auto list = makePtr(); - if (arguments.size() > 1) { - for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { - list->add(makePtr(*it)); + size_t count = arguments.size(); + auto nodes = ValueVector(count - 1); + if (count > 1) { + for (size_t i = 1; i < count; ++i) { + nodes.at(i) = makePtr(arguments[i]); } } - env->set("*ARGV*", list); + env->set("*ARGV*", makePtr(nodes)); } } // namespace blaze diff --git a/src/step7_quote.cpp b/src/step7_quote.cpp index 07c2894..e2f1cb9 100644 --- a/src/step7_quote.cpp +++ b/src/step7_quote.cpp @@ -93,13 +93,14 @@ static auto installLambdas(EnvironmentPtr env) -> void static auto makeArgv(EnvironmentPtr env, std::vector arguments) -> void { - auto list = makePtr(); - if (arguments.size() > 1) { - for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { - list->add(makePtr(*it)); + size_t count = arguments.size(); + auto nodes = ValueVector(count - 1); + if (count > 1) { + for (size_t i = 1; i < count; ++i) { + nodes.at(i) = makePtr(arguments[i]); } } - env->set("*ARGV*", list); + env->set("*ARGV*", makePtr(nodes)); } } // namespace blaze diff --git a/src/step8_macros.cpp b/src/step8_macros.cpp index 9ea0b5f..4c298c3 100644 --- a/src/step8_macros.cpp +++ b/src/step8_macros.cpp @@ -100,13 +100,14 @@ static auto installLambdas(EnvironmentPtr env) -> void static auto makeArgv(EnvironmentPtr env, std::vector arguments) -> void { - auto list = makePtr(); - if (arguments.size() > 1) { - for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { - list->add(makePtr(*it)); + size_t count = arguments.size(); + auto nodes = ValueVector(count - 1); + if (count > 1) { + for (size_t i = 1; i < count; ++i) { + nodes.at(i) = makePtr(arguments[i]); } } - env->set("*ARGV*", list); + env->set("*ARGV*", makePtr(nodes)); } } // namespace blaze diff --git a/src/step9_try.cpp b/src/step9_try.cpp index 5c61076..63bb230 100644 --- a/src/step9_try.cpp +++ b/src/step9_try.cpp @@ -100,13 +100,14 @@ static auto installLambdas(EnvironmentPtr env) -> void static auto makeArgv(EnvironmentPtr env, std::vector arguments) -> void { - auto list = makePtr(); - if (arguments.size() > 1) { - for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { - list->add(makePtr(*it)); + size_t count = arguments.size(); + auto nodes = ValueVector(count - 1); + if (count > 1) { + for (size_t i = 1; i < count; ++i) { + nodes.at(i) = makePtr(arguments[i]); } } - env->set("*ARGV*", list); + env->set("*ARGV*", makePtr(nodes)); } } // namespace blaze diff --git a/src/stepA_mal.cpp b/src/stepA_mal.cpp index edd699d..0ed1be7 100644 --- a/src/stepA_mal.cpp +++ b/src/stepA_mal.cpp @@ -112,13 +112,14 @@ static auto installLambdas(EnvironmentPtr env) -> void static auto makeArgv(EnvironmentPtr env, std::vector arguments) -> void { - auto list = makePtr(); - if (arguments.size() > 1) { - for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { - list->add(makePtr(*it)); + size_t count = arguments.size(); + auto nodes = ValueVector(count - 1); + if (count > 1) { + for (size_t i = 1; i < count; ++i) { + nodes.at(i) = makePtr(arguments[i]); } } - env->set("*ARGV*", list); + env->set("*ARGV*", makePtr(nodes)); } } // namespace blaze