-
-
Notifications
You must be signed in to change notification settings - Fork 33
Adapt nyan to new specification #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
ef6cf3b
ec687e0
e017655
05f74f6
1083219
d075d25
c9a9daa
d2a9005
e29f7d4
8e902ec
0b873cf
096317c
c1b62b5
32df34b
6b19fab
6902201
4b005dd
80ea0e9
f4000a4
5995d04
4497163
5090faf
28465f5
436071b
2eee390
6d02965
1af9713
f1a190e
fee9488
78cd996
aeeaa1b
d1c52d9
9c2a7fe
06212ba
ecbb66f
ef2bf3a
458bb5e
9a4c8ab
6358d0e
36af270
312914b
6756dc1
d139bab
a54937e
bf5db02
4025fff
5ed8e63
d48c873
a345388
492d730
c6e080a
0f79321
9122237
543478d
8ba7e7a
549855c
ba2cdfc
7d5dfaa
22b1725
8fd9b9e
ccae9c0
bb3dfd4
1a092e3
90097df
3cb82d7
590c268
2831c7e
a83907e
8e537c9
b8952bf
72f5e03
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// Copyright 2020-2020 the nyan authors, LGPLv3+. See copying.md for legal info. | ||
|
||
#include "dict.h" | ||
|
||
#include "orderedset.h" | ||
#include "set.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)); | ||
} | ||
} | ||
|
||
|
||
ValueHolder Dict::copy() const { | ||
// TODO | ||
// return {std::make_shared<Dict>(*this)}; | ||
return ValueHolder(); | ||
} | ||
|
||
|
||
std::string Dict::str() const { | ||
// same as repr(), except we use str(). | ||
|
||
std::ostringstream builder; | ||
builder << "{"; | ||
builder << util::strjoin( | ||
", ", this->values, | ||
[] (const auto &val) { | ||
return val.first->str() + ": " + val.second->str(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the python standard is to always use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, i'd say so. |
||
} | ||
); | ||
builder << "}"; | ||
|
||
return builder.str(); | ||
} | ||
|
||
|
||
std::string Dict::repr() const { | ||
// same as str(), except we use repr(). | ||
|
||
std::ostringstream builder; | ||
builder << "{"; | ||
builder << util::strjoin( | ||
", ", this->values, | ||
[] (const auto &val) { | ||
return val.first->repr() + ": " + val.second->repr(); | ||
} | ||
); | ||
builder << "}"; | ||
|
||
return builder.str(); | ||
} | ||
|
||
|
||
const BasicType &Dict::get_type() const { | ||
constexpr static BasicType type{ | ||
primitive_t::CONTAINER, | ||
container_t::DICT, | ||
}; | ||
|
||
return type; | ||
} | ||
|
||
void Dict::apply_value(const Value &value, nyan_op operation) { | ||
auto dict_applier = [](auto &member_value, auto operand, nyan_op operation) { | ||
switch (operation) { | ||
case nyan_op::ASSIGN: | ||
member_value.clear(); | ||
// fall through | ||
|
||
// TODO | ||
case nyan_op::UNION_ASSIGN: | ||
case nyan_op::ADD_ASSIGN: { | ||
for (auto &val : operand) { | ||
member_value.insert(val); | ||
} | ||
break; | ||
} | ||
|
||
case nyan_op::INTERSECT_ASSIGN: | ||
// TODO | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break; | ||
|
||
default: | ||
throw InternalError{"unknown dict value application"}; | ||
} | ||
}; | ||
|
||
auto set_applier = [](auto &member_value, auto operand, nyan_op operation) { | ||
switch (operation) { | ||
case nyan_op::SUBTRACT_ASSIGN: { | ||
for (auto &val : operand) { | ||
member_value.erase(val); | ||
} | ||
break; | ||
} | ||
|
||
case nyan_op::INTERSECT_ASSIGN: | ||
// TODO | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break; | ||
|
||
default: | ||
throw InternalError{"unknown dict value application"}; | ||
} | ||
}; | ||
|
||
|
||
if (typeid(Set&) == typeid(value)) { | ||
const Set *change = dynamic_cast<const Set *>(&value); | ||
|
||
if (unlikely(change == nullptr)) { | ||
using namespace std::string_literals; | ||
throw InternalError{ | ||
"set value application was not a container, it was: "s | ||
+ util::demangle(typeid(value).name()) | ||
+ " and couldn't cast to " | ||
+ util::demangle(typeid(change).name())}; | ||
} | ||
|
||
set_applier(this->values, change->get(), operation); | ||
|
||
} | ||
else if (typeid(OrderedSet&) == typeid(value)) { | ||
const OrderedSet *change = dynamic_cast<const OrderedSet *>(&value); | ||
|
||
if (unlikely(change == nullptr)) { | ||
using namespace std::string_literals; | ||
throw InternalError{ | ||
"set value application was not a container, it was: "s | ||
+ util::demangle(typeid(value).name()) | ||
+ " and couldn't cast to " | ||
+ util::demangle(typeid(change).name())}; | ||
} | ||
|
||
set_applier(this->values, change->get(), operation); | ||
|
||
} | ||
else if (typeid(Dict&) == typeid(value)) { | ||
const Dict *change = dynamic_cast<const Dict *>(&value); | ||
|
||
if (unlikely(change == nullptr)) { | ||
using namespace std::string_literals; | ||
throw InternalError{ | ||
"set value application was not a container, it was: "s | ||
+ util::demangle(typeid(value).name()) | ||
+ " and couldn't cast to " | ||
+ util::demangle(typeid(change).name())}; | ||
} | ||
|
||
dict_applier(this->values, change->get(), operation); | ||
} | ||
else { | ||
throw InternalError("expected Container instance for operation, but got" | ||
+ std::string(typeid(value).name())); | ||
} | ||
|
||
|
||
} | ||
|
||
const std::unordered_set<nyan_op> &Dict::allowed_operations(const Type &with_type) const { | ||
|
||
if (not with_type.is_container()) { | ||
return no_nyan_ops; | ||
} | ||
|
||
const static std::unordered_set<nyan_op> set_ops{ | ||
nyan_op::SUBTRACT_ASSIGN, | ||
nyan_op::INTERSECT_ASSIGN, | ||
}; | ||
|
||
const static std::unordered_set<nyan_op> dict_ops{ | ||
nyan_op::ASSIGN, | ||
nyan_op::ADD_ASSIGN, | ||
nyan_op::UNION_ASSIGN, | ||
nyan_op::INTERSECT_ASSIGN, | ||
}; | ||
|
||
switch (with_type.get_container_type()) { | ||
case container_t::SET: | ||
case container_t::ORDEREDSET: | ||
return set_ops; | ||
|
||
case container_t::DICT: | ||
return dict_ops; | ||
|
||
default: | ||
return no_nyan_ops; | ||
} | ||
} | ||
|
||
} // namespace nyan |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// 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 { | ||
|
||
/** | ||
* Container iterator for the Set. | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* Used for walking over the contained values, | ||
* i.e. it unpacks the ValueHolders! | ||
* | ||
*/ | ||
template<typename iter_type, typename elem_type> | ||
class DictIterator : public ContainerIterBase<elem_type> { | ||
public: | ||
using this_type = DictIterator<iter_type, elem_type>; | ||
using base_type = ContainerIterBase<elem_type>; | ||
|
||
explicit DictIterator(iter_type &&iter) | ||
: | ||
iterator{std::move(iter)} {} | ||
|
||
/** | ||
* Advance the iterator to the next element in the dict. | ||
*/ | ||
base_type &operator ++() override { | ||
++this->iterator; | ||
return *this; | ||
} | ||
|
||
/** | ||
* Get the element the iterator is currently pointing to. | ||
*/ | ||
elem_type &operator *() const override { | ||
// unpack the ValueHolder! | ||
return *(*this->iterator); | ||
} | ||
|
||
protected: | ||
/** | ||
* compare two iterators | ||
*/ | ||
bool equals(const base_type &other) const override { | ||
auto other_me = dynamic_cast<const this_type &>(other); | ||
return (this->iterator == other_me.iterator); | ||
} | ||
|
||
/** | ||
* The wrapped std::iterator, from the Set std::unordered_set. | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
iter_type iterator; | ||
}; | ||
|
||
|
||
/** | ||
* Nyan value to store a dict/map/assocated array of things. | ||
* | ||
* T is the underlying storage type to store the Values. | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
class Dict : Value { | ||
public: | ||
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; | ||
} | ||
|
||
ValueHolder copy() const override; | ||
std::string str() const override; | ||
std::string repr() const override; | ||
|
||
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 |
Uh oh!
There was an error while loading. Please reload this page.