Skip to content
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

Adapt nyan to new specification #84

Closed
wants to merge 71 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
ef6cf3b
lexer: Add '!' (bang) as symbol.
heinezen Oct 5, 2020
ec687e0
lexer: Enforce 'version' as first argument in file.
heinezen Oct 6, 2020
e017655
lexer: Fix dates and include dict type.
heinezen Oct 12, 2020
05f74f6
parser: Read arbitrary member type arguments.
heinezen Oct 16, 2020
1083219
nyan: Allow floats for int operations.
heinezen Oct 17, 2020
d075d25
nyan: Define values for float/int positive and negative infinty.
heinezen Oct 17, 2020
c9a9daa
nyan: Calculus rules for infinity.
heinezen Oct 18, 2020
d2a9005
lexer: Parse inf/-inf tokens.
heinezen Oct 19, 2020
e29f7d4
nyan: Fix handling infinity pointer.
heinezen Oct 19, 2020
8e902ec
nyan: Change bool's True/False to pythonic notation.
heinezen Oct 19, 2020
0b873cf
nyan: ValueToken for more complex values.
heinezen Oct 24, 2020
096317c
nyan: Use ValueToken while creating AST and Value instances.
heinezen Oct 25, 2020
c1b62b5
parser: Parse dict items.
heinezen Oct 25, 2020
32df34b
nyan: Dict data type.
heinezen Oct 27, 2020
6b19fab
nyan: Make 'element_type' of Type a vector.
heinezen Nov 22, 2020
6902201
dict: Create dicts from nyan file.
heinezen Nov 22, 2020
4b005dd
dict: Intersection operation.
heinezen Nov 23, 2020
80ea0e9
dict: Iterator logic.
heinezen Nov 25, 2020
f4000a4
refactor: Rename container types to composite types. Include type mod…
heinezen Nov 26, 2020
5995d04
parser: Allow limiting the number of read elements in comma_list().
heinezen Nov 28, 2020
4497163
parser: Allow nested types.
heinezen Nov 28, 2020
5090faf
init: New function for extracting value from ValueToken.
heinezen Dec 11, 2020
28465f5
nyan: Check for "None" value.
heinezen Dec 11, 2020
436071b
nyan: None value.
heinezen Dec 12, 2020
2eee390
nyan: Check modifiers.
heinezen Dec 12, 2020
6d02965
refactor: Add comments to ast.h.
heinezen Dec 12, 2020
1af9713
refactor: Add comments to api_error.h.
heinezen Dec 16, 2020
f1a190e
refactor: Add comments to basic_type.h.
heinezen Dec 16, 2020
fee9488
refactor: Add comments to c3.h.
heinezen Dec 16, 2020
78cd996
refactor: Add comments to change_tracker.h.
heinezen Dec 16, 2020
aeeaa1b
refactor: Add comments to curve.h.
heinezen Dec 16, 2020
d1c52d9
refactor: Add comments to database.h.
heinezen Dec 16, 2020
9c2a7fe
refactor: Add comments to error.h.
heinezen Dec 16, 2020
06212ba
refactor: Add comments to file.h.
heinezen Dec 16, 2020
ecbb66f
refactor: Add comments to id_token.h.
heinezen Dec 16, 2020
ef2bf3a
refactor: Add comments to inheritance_change.h.
heinezen Dec 16, 2020
458bb5e
refactor: Add comments to lang_error.h.
heinezen Dec 16, 2020
9a4c8ab
refactor: Add comments to location.h.
heinezen Dec 16, 2020
6358d0e
refactor: Add comments to member_info.h.
heinezen Dec 19, 2020
36af270
refactor: Add comments to member.h.
heinezen Dec 19, 2020
312914b
refactor: Add comments to meta_info.h.
heinezen Dec 19, 2020
6756dc1
refactor: Add comments to namespace_finder.h.
heinezen Dec 20, 2020
d139bab
refactor: Add comments to namespace.h.
heinezen Dec 20, 2020
a54937e
refactor: Add comments to object_history.h.
heinezen Dec 20, 2020
bf5db02
refactor: Add comments to object_info.h.
heinezen Dec 20, 2020
4025fff
refactor: Add comments to object_notifier.h.
heinezen Dec 20, 2020
5ed8e63
refactor: Add comments to object_state.h.
heinezen Dec 20, 2020
d48c873
refactor: Add comments to object.h.
heinezen Dec 20, 2020
a345388
refactor: Add comments to ops.h.
heinezen Dec 20, 2020
492d730
refactor: Add comments to parser.h.
heinezen Dec 20, 2020
c6e080a
refactor: Add comments to patch_info.h.
heinezen Dec 20, 2020
0f79321
refactor: Add comments to state_history.h.
heinezen Dec 20, 2020
9122237
refactor: Add comments to state.h.
heinezen Dec 20, 2020
543478d
refactor: Add comments to token_stream.h.
heinezen Dec 20, 2020
8ba7e7a
refactor: Add comments to token.h.
heinezen Dec 20, 2020
549855c
refactor: Add comments to transaction.h.
heinezen Dec 21, 2020
ba2cdfc
refactor: Add comments to type.h.
heinezen Dec 21, 2020
7d5dfaa
refactor: Add comments to util.h.
heinezen Dec 21, 2020
22b1725
refactor: Add comments to value_token.h.
heinezen Dec 21, 2020
8fd9b9e
refactor: Add comments to value.h.
heinezen Dec 21, 2020
ccae9c0
refactor: Add comments to value_holder.h.
heinezen Dec 21, 2020
bb3dfd4
refactor: Convert tabs to spaces in files.
heinezen Dec 21, 2020
1a092e3
fix copyright dates.
heinezen Dec 21, 2020
90097df
nyan: Assign None directly on Member::apply().
heinezen Dec 23, 2020
3cb82d7
parser: Use switch statement for differentiating composite types.
heinezen Jan 15, 2021
590c268
dict: Comment fixes.
heinezen Jan 15, 2021
2831c7e
ast: Use size_t for comma list boundary.
heinezen Jan 15, 2021
a83907e
nyan: Cody styling for is_none() function.
heinezen Jan 15, 2021
8e537c9
nyan: Remove unused parameters from lambda functions.
heinezen Jan 15, 2021
b8952bf
nyan: Better description for None.
heinezen Jan 15, 2021
72f5e03
parser: Replace ifs in handle_modifiers() with switch statement.
heinezen Jan 15, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
199 changes: 199 additions & 0 deletions nyan/value/dict.cpp
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();
TheJJ marked this conversation as resolved.
Show resolved Hide resolved
}


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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the python standard is to always use repr for the dict members. so Dict::str and Dict::repr can be identicall, and use the repr variant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so just use return this->repr(); in this function?

Copy link
Member

Choose a reason for hiding this comment

The 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
123 changes: 123 additions & 0 deletions nyan/value/dict.h
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
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
TheJJ marked this conversation as resolved.
Show resolved Hide resolved

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