Browse Source

Everywhere: Remove Collection::add(), they are not mutable

master
Riyyi 1 year ago
parent
commit
ce0443a20e
  1. 9
      src/ast.cpp
  2. 5
      src/ast.h
  3. 6
      src/environment.cpp
  4. 20
      src/eval.cpp
  5. 87
      src/functions.cpp
  6. 64
      src/reader.cpp
  7. 11
      src/step6_file.cpp
  8. 11
      src/step7_quote.cpp
  9. 11
      src/step8_macros.cpp
  10. 11
      src/step9_try.cpp
  11. 11
      src/stepA_mal.cpp

9
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 ValueVector Collection::rest() const
{ {
auto start = (m_nodes.size() > 0) ? m_nodes.begin() + 1 : m_nodes.end(); auto start = (m_nodes.size() > 0) ? m_nodes.begin() + 1 : m_nodes.end();

5
src/ast.h

@ -94,8 +94,6 @@ class Collection : public Value {
public: public:
virtual ~Collection() = default; virtual ~Collection() = default;
void add(ValuePtr node);
// TODO: rename size -> count // TODO: rename size -> count
size_t size() const { return m_nodes.size(); } size_t size() const { return m_nodes.size(); }
bool empty() const { return m_nodes.size() == 0; } bool empty() const { return m_nodes.size() == 0; }
@ -219,6 +217,7 @@ public:
virtual ~String() = default; virtual ~String() = default;
const std::string& data() const { return m_data; } const std::string& data() const { return m_data; }
size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); } bool empty() const { return m_data.empty(); }
WITH_NO_META(); WITH_NO_META();
@ -324,7 +323,7 @@ private:
// ----------------------------------------- // -----------------------------------------
using FunctionType = std::function<ValuePtr(ValueVectorIt, ValueVectorIt)>; using FunctionType = std::function<ValuePtr(ValueVectorConstIt, ValueVectorConstIt)>;
class Function final : public Callable { class Function final : public Callable {
public: public:

6
src/environment.cpp

@ -43,11 +43,11 @@ EnvironmentPtr Environment::create(const ValuePtr lambda, const ValueVector& arg
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector();
for (; it != arguments.end(); ++it) { for (; it != arguments.end(); ++it) {
list->add(*it); nodes.push_back(*it);
} }
env->set(bindings[i + 1], list); env->set(bindings[i + 1], makePtr<List>(nodes));
return env; return env;
} }

20
src/eval.cpp

@ -156,22 +156,29 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env)
Error::the().add(::format("'{}' not found", ast)); Error::the().add(::format("'{}' not found", ast));
return nullptr; return nullptr;
} }
return result; return result;
} }
else if (is<Collection>(ast_raw_ptr)) { else if (is<Collection>(ast_raw_ptr)) {
std::shared_ptr<Collection> result = nullptr;
(is<List>(ast_raw_ptr)) ? result = makePtr<List>() : result = makePtr<Vector>();
const auto& nodes = std::static_pointer_cast<Collection>(ast)->nodes(); const auto& nodes = std::static_pointer_cast<Collection>(ast)->nodes();
for (const auto& node : nodes) { size_t count = nodes.size();
m_ast_stack.push(node); auto evaluated_nodes = ValueVector(count);
for (size_t i = 0; i < count; ++i) {
m_ast_stack.push(nodes[i]);
m_env_stack.push(env); m_env_stack.push(env);
ValuePtr eval_node = evalImpl(); ValuePtr eval_node = evalImpl();
if (eval_node == nullptr) { if (eval_node == nullptr) {
return nullptr; return nullptr;
} }
result->add(eval_node); evaluated_nodes.at(i) = eval_node;
} }
return result;
if (is<List>(ast_raw_ptr)) {
return makePtr<List>(evaluated_nodes);
}
return makePtr<Vector>(evaluated_nodes);
} }
else if (is<HashMap>(ast_raw_ptr)) { else if (is<HashMap>(ast_raw_ptr)) {
auto result = makePtr<HashMap>(); auto result = makePtr<HashMap>();
@ -185,6 +192,7 @@ ValuePtr Eval::evalAst(ValuePtr ast, EnvironmentPtr env)
} }
result->add(element.first, element_node); result->add(element.first, element_node);
} }
return result; return result;
} }

87
src/functions.cpp

@ -39,7 +39,7 @@
static struct FUNCTION_STRUCT_NAME(unique) \ static struct FUNCTION_STRUCT_NAME(unique) \
FUNCTION_STRUCT_NAME(unique)( \ FUNCTION_STRUCT_NAME(unique)( \
symbol, \ symbol, \
[](ValueVectorIt begin, ValueVectorIt end) -> ValuePtr lambda); [](ValueVectorConstIt begin, ValueVectorConstIt end) -> ValuePtr lambda);
#define ADD_FUNCTION(symbol, lambda) ADD_FUNCTION_IMPL(__LINE__, symbol, lambda); #define ADD_FUNCTION(symbol, lambda) ADD_FUNCTION_IMPL(__LINE__, symbol, lambda);
@ -419,11 +419,11 @@ ADD_FUNCTION(
VALUE_CAST(collection, Collection, (*begin)); VALUE_CAST(collection, Collection, (*begin));
const auto& collection_nodes = collection->nodes(); const auto& collection_nodes = collection->nodes();
ValueVector* result_nodes = new ValueVector(collection_nodes.size() + 1); auto result_nodes = ValueVector(collection_nodes.size() + 1);
result_nodes->at(0) = first; result_nodes.at(0) = first;
std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes->begin() + 1); std::copy(collection_nodes.begin(), collection_nodes.end(), result_nodes.begin() + 1);
return makePtr<List>(*result_nodes); return makePtr<List>(result_nodes);
}); });
// (concat (list 1) (list 2 3)) -> (1 2 3) // (concat (list 1) (list 2 3)) -> (1 2 3)
@ -436,15 +436,15 @@ ADD_FUNCTION(
count += collection->size(); count += collection->size();
} }
auto result_nodes = new ValueVector(count); auto result_nodes = ValueVector(count);
size_t offset = 0; size_t offset = 0;
for (auto it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
const auto& collection_nodes = std::static_pointer_cast<Collection>(*it)->nodes(); const auto& collection_nodes = std::static_pointer_cast<Collection>(*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(); offset += collection_nodes.size();
} }
return makePtr<List>(*result_nodes); return makePtr<List>(result_nodes);
}); });
// (vec (list 1 2 3)) // (vec (list 1 2 3))
@ -529,7 +529,7 @@ ADD_FUNCTION(
VALUE_CAST(collection, Collection, (*std::prev(end))); 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()); arguments.reserve(arguments.size() + collection->size());
// Append list nodes to the argument leftovers // Append list nodes to the argument leftovers
@ -551,7 +551,7 @@ ADD_FUNCTION(
return value; 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( ADD_FUNCTION(
"map", "map",
{ {
@ -561,23 +561,23 @@ ADD_FUNCTION(
VALUE_CAST(collection, Collection, (*(begin + 1))); VALUE_CAST(collection, Collection, (*(begin + 1)));
const auto& collection_nodes = collection->nodes(); const auto& collection_nodes = collection->nodes();
auto result = makePtr<List>(); size_t count = collection->size();
auto nodes = ValueVector(count);
if (is<Function>(callable.get())) { if (is<Function>(callable.get())) {
auto function = std::static_pointer_cast<Function>(callable)->function(); auto function = std::static_pointer_cast<Function>(callable)->function();
for (const auto& node : collection_nodes) { for (size_t i = 0; i < count; ++i) {
auto arguments = ValueVector { node }; nodes.at(i) = function(collection_nodes.begin() + i, collection_nodes.begin() + i + 1);
result->add(function(arguments.begin(), arguments.end()));
} }
} }
else { else {
auto lambda = std::static_pointer_cast<Lambda>(callable); auto lambda = std::static_pointer_cast<Lambda>(callable);
for (const auto& node : collection_nodes) { for (size_t i = 0; i < count; ++i) {
result->add(eval(lambda->body(), Environment::create(lambda, { node }))); nodes.at(i) = (eval(lambda->body(), Environment::create(lambda, { collection_nodes[i] })));
} }
} }
return result; return makePtr<List>(nodes);
}); });
// (throw x) // (throw x)
@ -697,18 +697,16 @@ ADD_FUNCTION("keyword", STRING_TO_TYPE("keyword", Keyword));
// ----------------------------------------- // -----------------------------------------
// (vector 1 2 3) -> [1 2 3]
ADD_FUNCTION( ADD_FUNCTION(
"vector", "vector",
{ {
auto result = makePtr<Vector>(); auto result = makePtr<Vector>();
for (auto it = begin; it != end; ++it) { return makePtr<Vector>(begin, end);
result->add(*it);
}
return result;
}); });
// (hash-map "foo" 5 :bar 10) -> {"foo" 5 :bar 10}
ADD_FUNCTION( ADD_FUNCTION(
"hash-map", "hash-map",
{ {
@ -796,6 +794,7 @@ ADD_FUNCTION(
return makePtr<Constant>(hash_map->exists(*(begin + 1))); return makePtr<Constant>(hash_map->exists(*(begin + 1)));
}); });
// (keys {"foo" 3 :bar 5}) -> ("foo" :bar)
ADD_FUNCTION( ADD_FUNCTION(
"keys", "keys",
{ {
@ -803,21 +802,25 @@ ADD_FUNCTION(
VALUE_CAST(hash_map, HashMap, (*begin)); VALUE_CAST(hash_map, HashMap, (*begin));
auto result = makePtr<List>(); size_t count = hash_map->size();
auto nodes = ValueVector(count);
size_t i = 0;
auto elements = hash_map->elements(); auto elements = hash_map->elements();
for (auto pair : elements) { for (auto pair : elements) {
if (pair.first.front() == 0x7f) { // 127 if (pair.first.front() == 0x7f) { // 127
result->add(makePtr<Keyword>(pair.first.substr(1))); nodes.at(i) = makePtr<Keyword>(pair.first.substr(1));
} }
else { else {
result->add(makePtr<String>(pair.first)); nodes.at(i) = makePtr<String>(pair.first);
} }
i++;
} }
return result; return makePtr<List>(nodes);
}); });
// (vals {"foo" 3 :bar 5}) -> (3 5)
ADD_FUNCTION( ADD_FUNCTION(
"vals", "vals",
{ {
@ -825,14 +828,17 @@ ADD_FUNCTION(
VALUE_CAST(hash_map, HashMap, (*begin)); VALUE_CAST(hash_map, HashMap, (*begin));
auto result = makePtr<List>(); size_t count = hash_map->size();
auto nodes = ValueVector(count);
size_t i = 0;
auto elements = hash_map->elements(); auto elements = hash_map->elements();
for (auto pair : elements) { for (auto pair : elements) {
result->add(pair.second); nodes.at(i) = pair.second;
i++;
} }
return result; return makePtr<List>(nodes);
}); });
ADD_FUNCTION( ADD_FUNCTION(
@ -909,19 +915,19 @@ ADD_FUNCTION(
size_t collection_count = collection_nodes.size(); size_t collection_count = collection_nodes.size();
size_t argument_count = SIZE(); size_t argument_count = SIZE();
ValueVector* nodes = new ValueVector(argument_count + collection_count); auto nodes = ValueVector(argument_count + collection_count);
if (is<List>(collection.get())) { if (is<List>(collection.get())) {
std::reverse_copy(begin, end, nodes->begin()); std::reverse_copy(begin, end, nodes.begin());
std::copy(collection_nodes.begin(), collection_nodes.end(), nodes->begin() + argument_count); std::copy(collection_nodes.begin(), collection_nodes.end(), nodes.begin() + argument_count);
return makePtr<List>(*nodes); return makePtr<List>(nodes);
} }
std::copy(collection_nodes.begin(), collection_nodes.end(), nodes->begin()); std::copy(collection_nodes.begin(), collection_nodes.end(), nodes.begin());
std::copy(begin, end, nodes->begin() + collection_count); std::copy(begin, end, nodes.begin() + collection_count);
return makePtr<Vector>(*nodes); return makePtr<Vector>(nodes);
}); });
// (seq '(1 2 3)) -> (1 2 3) // (seq '(1 2 3)) -> (1 2 3)
@ -958,14 +964,15 @@ ADD_FUNCTION(
return makePtr<Constant>(); return makePtr<Constant>();
} }
auto result = makePtr<List>(); size_t count = string->size();
auto nodes = ValueVector(count);
const auto& data = string->data(); const auto& data = string->data();
for (const auto& character : data) { for (size_t i = 0; i < count; ++i) {
result->add(makePtr<String>(character)); nodes.at(i) = makePtr<String>(data[i]);
} }
return result; return makePtr<List>(nodes);
} }
Error::the().add(::format("wrong argument type: Collection or String, {}", front)); Error::the().add(::format("wrong argument type: Collection or String, {}", front));

64
src/reader.cpp

@ -122,24 +122,24 @@ ValuePtr Reader::readSpliceUnquote()
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector(2);
list->add(makePtr<Symbol>("splice-unquote")); nodes.at(0) = makePtr<Symbol>("splice-unquote");
list->add(readImpl()); nodes.at(1) = readImpl();
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readList() ValuePtr Reader::readList()
{ {
ignore(); // ( ignore(); // (
auto list = makePtr<List>(); auto nodes = ValueVector();
while (!isEOF() && peek().type != Token::Type::ParenClose) { while (!isEOF() && peek().type != Token::Type::ParenClose) {
auto node = readImpl(); auto node = readImpl();
if (node == nullptr) { if (node == nullptr) {
return nullptr; return nullptr;
} }
list->add(node); nodes.push_back(node);
} }
if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // ) if (!consumeSpecific(Token { .type = Token::Type::ParenClose })) { // )
@ -147,27 +147,27 @@ ValuePtr Reader::readList()
return nullptr; return nullptr;
} }
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readVector() ValuePtr Reader::readVector()
{ {
ignore(); // [ ignore(); // [
auto vector = makePtr<Vector>(); auto nodes = ValueVector();
while (!isEOF() && peek().type != Token::Type::BracketClose) { while (!isEOF() && peek().type != Token::Type::BracketClose) {
auto node = readImpl(); auto node = readImpl();
if (node == nullptr) { if (node == nullptr) {
return nullptr; return nullptr;
} }
vector->add(node); nodes.push_back(node);
} }
if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ] if (!consumeSpecific(Token { .type = Token::Type::BracketClose })) { // ]
Error::the().add("expected ']', got EOF"); Error::the().add("expected ']', got EOF");
} }
return vector; return makePtr<Vector>(nodes);
} }
ValuePtr Reader::readHashMap() ValuePtr Reader::readHashMap()
@ -213,11 +213,11 @@ ValuePtr Reader::readQuote()
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector(2);
list->add(makePtr<Symbol>("quote")); nodes.at(0) = makePtr<Symbol>("quote");
list->add(readImpl()); nodes.at(1) = readImpl();
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readQuasiQuote() ValuePtr Reader::readQuasiQuote()
@ -229,11 +229,11 @@ ValuePtr Reader::readQuasiQuote()
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector(2);
list->add(makePtr<Symbol>("quasiquote")); nodes.at(0) = makePtr<Symbol>("quasiquote");
list->add(readImpl()); nodes.at(1) = readImpl();
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readUnquote() ValuePtr Reader::readUnquote()
@ -245,11 +245,11 @@ ValuePtr Reader::readUnquote()
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector(2);
list->add(makePtr<Symbol>("unquote")); nodes.at(0) = makePtr<Symbol>("unquote");
list->add(readImpl()); nodes.at(1) = readImpl();
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readWithMeta() ValuePtr Reader::readWithMeta()
@ -263,14 +263,12 @@ ValuePtr Reader::readWithMeta()
} }
retreat(); retreat();
auto list = makePtr<List>(); auto nodes = ValueVector(3);
list->add(makePtr<Symbol>("with-meta")); nodes.at(0) = makePtr<Symbol>("with-meta");
ValuePtr first = readImpl(); nodes.at(2) = readImpl(); // Note: second Value is read first
ValuePtr second = readImpl(); nodes.at(1) = readImpl();
list->add(second);
list->add(first);
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readDeref() ValuePtr Reader::readDeref()
@ -282,11 +280,11 @@ ValuePtr Reader::readDeref()
return nullptr; return nullptr;
} }
auto list = makePtr<List>(); auto nodes = ValueVector(2);
list->add(makePtr<Symbol>("deref")); nodes.at(0) = makePtr<Symbol>("deref");
list->add(readImpl()); nodes.at(1) = readImpl();
return list; return makePtr<List>(nodes);
} }
ValuePtr Reader::readString() ValuePtr Reader::readString()

11
src/step6_file.cpp

@ -93,13 +93,14 @@ static auto installLambdas(EnvironmentPtr env) -> void
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{ {
auto list = makePtr<List>(); size_t count = arguments.size();
if (arguments.size() > 1) { auto nodes = ValueVector(count - 1);
for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { if (count > 1) {
list->add(makePtr<String>(*it)); for (size_t i = 1; i < count; ++i) {
nodes.at(i) = makePtr<String>(arguments[i]);
} }
} }
env->set("*ARGV*", list); env->set("*ARGV*", makePtr<List>(nodes));
} }
} // namespace blaze } // namespace blaze

11
src/step7_quote.cpp

@ -93,13 +93,14 @@ static auto installLambdas(EnvironmentPtr env) -> void
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{ {
auto list = makePtr<List>(); size_t count = arguments.size();
if (arguments.size() > 1) { auto nodes = ValueVector(count - 1);
for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { if (count > 1) {
list->add(makePtr<String>(*it)); for (size_t i = 1; i < count; ++i) {
nodes.at(i) = makePtr<String>(arguments[i]);
} }
} }
env->set("*ARGV*", list); env->set("*ARGV*", makePtr<List>(nodes));
} }
} // namespace blaze } // namespace blaze

11
src/step8_macros.cpp

@ -100,13 +100,14 @@ static auto installLambdas(EnvironmentPtr env) -> void
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{ {
auto list = makePtr<List>(); size_t count = arguments.size();
if (arguments.size() > 1) { auto nodes = ValueVector(count - 1);
for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { if (count > 1) {
list->add(makePtr<String>(*it)); for (size_t i = 1; i < count; ++i) {
nodes.at(i) = makePtr<String>(arguments[i]);
} }
} }
env->set("*ARGV*", list); env->set("*ARGV*", makePtr<List>(nodes));
} }
} // namespace blaze } // namespace blaze

11
src/step9_try.cpp

@ -100,13 +100,14 @@ static auto installLambdas(EnvironmentPtr env) -> void
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{ {
auto list = makePtr<List>(); size_t count = arguments.size();
if (arguments.size() > 1) { auto nodes = ValueVector(count - 1);
for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { if (count > 1) {
list->add(makePtr<String>(*it)); for (size_t i = 1; i < count; ++i) {
nodes.at(i) = makePtr<String>(arguments[i]);
} }
} }
env->set("*ARGV*", list); env->set("*ARGV*", makePtr<List>(nodes));
} }
} // namespace blaze } // namespace blaze

11
src/stepA_mal.cpp

@ -112,13 +112,14 @@ static auto installLambdas(EnvironmentPtr env) -> void
static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void static auto makeArgv(EnvironmentPtr env, std::vector<std::string> arguments) -> void
{ {
auto list = makePtr<List>(); size_t count = arguments.size();
if (arguments.size() > 1) { auto nodes = ValueVector(count - 1);
for (auto it = arguments.begin() + 1; it != arguments.end(); ++it) { if (count > 1) {
list->add(makePtr<String>(*it)); for (size_t i = 1; i < count; ++i) {
nodes.at(i) = makePtr<String>(arguments[i]);
} }
} }
env->set("*ARGV*", list); env->set("*ARGV*", makePtr<List>(nodes));
} }
} // namespace blaze } // namespace blaze

Loading…
Cancel
Save