Skip to content

Commit

Permalink
nyan: Dict data type (breaks).
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Oct 27, 2020
1 parent c1b62b5 commit fcff6b1
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 5 deletions.
1 change: 1 addition & 0 deletions nyan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ add_library(nyan SHARED
value_token.cpp
value/boolean.cpp
value/container.cpp
value/dict.cpp
value/file.cpp
value/number.cpp
value/object.cpp
Expand Down
29 changes: 29 additions & 0 deletions nyan/value/dict.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2020-2020 the nyan authors, LGPLv3+. See copying.md for legal info.

#include "dict.h"

#include "../error.h"
#include "../util.h"


namespace nyan {

Dict::Dict() = default;

Dict::Dict(std::unordered_map<ValueHolder,ValueHolder> &&values) {
for (auto &value : values) {
this->values.insert(std::move(value));
}
}


const BasicType &Dict::get_type() const {
constexpr static BasicType type{
primitive_t::CONTAINER,
container_t::DICT,
};

return type;
}

} // namespace nyan
159 changes: 159 additions & 0 deletions nyan/value/dict.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// Copyright 2020-2020 the nyan authors, LGPLv3+. See copying.md for legal info.
#pragma once


#include <unordered_map>

#include "../api_error.h"
#include "../compiler.h"
#include "../util.h"
#include "container.h"
#include "value.h"


namespace nyan {


/**
* Nyan value to store a dict/map/assocated array of things.
*
* T is the underlying storage type to store the Values.
*/
class Dict : Value {
public:
using iterator = ContainerIterator<std::pair<Value,Value>>;
using const_iterator = ContainerIterator<const std::pair<Value,Value>>;
using holder_iterator = ContainerIterator<std::pair<ValueHolder,ValueHolder>>;
using holder_const_iterator = ContainerIterator<const std::pair<ValueHolder,ValueHolder>>;

using value_storage = std::unordered_map<ValueHolder,ValueHolder>;
using key_type = typename value_storage::key_type;
using element_type = typename value_storage::value_type;
using value_const_iterator = typename value_storage::const_iterator;


Dict();
Dict(std::unordered_map<ValueHolder,ValueHolder> &&values);


size_t hash() const override {
throw APIError{"Dicts are not hashable."};
}


size_t size() const {
return this->values.size();
}


void clear() {
this->values.clear();
}


const value_storage &get() const {
return this->values;
}

iterator begin() {
throw Error{
"Dicts are not non-const-iterable. "
"make it const by using e.g. "
"for (auto &it = std::as_const(container))"
};
}


iterator end() {
// also throw the error above.
return this->begin();
}

const_iterator begin() const {
auto real_iterator = std::make_unique<
DictIterator<value_const_iterator,
const_iterator::elem_type>>(std::begin(this->values));

return const_iterator{std::move(real_iterator)};
}


const_iterator end() const {
auto real_iterator = std::make_unique<
DictIterator<value_const_iterator,
const_iterator::elem_type>>(std::end(this->values));

return const_iterator{std::move(real_iterator)};
}


holder_iterator values_begin() {
throw Error{
"Set values holders are not non-const-iterable."
};
}


holder_iterator values_end() {
// also throw the error above.
return this->values_begin();
}


/**
* Get an iterator to the underlying set storage.
* Contrary to the above, this will allow to get the
* ValueHolders.
*/
holder_const_iterator values_begin() const {
auto real_iterator = std::make_unique<
DefaultIterator<value_const_iterator,
holder_const_iterator::elem_type>>(
std::begin(this->values)
);

return holder_const_iterator{std::move(real_iterator)};
}

/**
* Iterator to end of the underlying storage.
*/
holder_const_iterator values_end() const {
auto real_iterator = std::make_unique<
DefaultIterator<value_const_iterator,
holder_const_iterator::elem_type>>(
std::end(this->values)
);

return holder_const_iterator{std::move(real_iterator)};
}


ValueHolder copy() const override;
std::string str() const override;
std::string repr() const override;

bool add(const ValueHolder &value);
bool contains(const ValueHolder &value) const;
bool remove(const ValueHolder &value);

const std::unordered_set<nyan_op> &allowed_operations(const Type &with_type) const override;
const BasicType &get_type() const override;

protected:
void apply_value(const Value &value, nyan_op operation) override;


bool equals(const Value &other) const override {
auto &other_val = dynamic_cast<const Dict &>(other);

return values == other_val.values;
}

/**
* Dict value storage (this is an unordered map).
*/
value_storage values;
};

} // namespace nyan
3 changes: 0 additions & 3 deletions nyan/value/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@

namespace nyan {

/** datatype used for unordered set storage */
using set_t = std::unordered_set<ValueHolder>;


/**
* Nyan value to store a unordered set of things.
Expand Down
4 changes: 2 additions & 2 deletions nyan/value/set_types.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019-2019 the nyan authors, LGPLv3+. See copying.md for legal info.
// Copyright 2019-2020 the nyan authors, LGPLv3+. See copying.md for legal info.
#pragma once

#include <unordered_set>
Expand All @@ -9,7 +9,7 @@

namespace nyan {

/** datatype used for ordered set storage */
/** datatype used for (unordered) set storage */
using set_t = std::unordered_set<ValueHolder>;


Expand Down
3 changes: 3 additions & 0 deletions nyan/value/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ ValueHolder Value::from_ast(const Type &target_type,
case container_t::ORDEREDSET:
return {std::make_shared<OrderedSet>(std::move(values))};

case container_t::DICT:
// TODO

default:
throw InternalError{"value creation for unhandled container type"};
}
Expand Down

0 comments on commit fcff6b1

Please sign in to comment.