-
-
Notifications
You must be signed in to change notification settings - Fork 31
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
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 |
---|---|---|
|
@@ -84,10 +84,12 @@ const std::unordered_set<nyan_op> &Filename::allowed_operations(const Type &with | |
nyan_op::ASSIGN, | ||
}; | ||
|
||
if (with_type.get_primitive_type() == primitive_t::FILENAME) { | ||
switch (with_type.get_primitive_type()) { | ||
case primitive_t::FILENAME: | ||
case primitive_t::NONE: | ||
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. why can we assign 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. |
||
return ops; | ||
} | ||
else { | ||
|
||
default: | ||
return no_nyan_ops; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -390,6 +390,10 @@ template <typename T> | |
const std::unordered_set<nyan_op> & | ||
Number<T>::allowed_operations(const Type &with_type) const { | ||
|
||
const static std::unordered_set<nyan_op> none_ops{ | ||
nyan_op::ASSIGN, | ||
}; | ||
|
||
const static std::unordered_set<nyan_op> ops{ | ||
nyan_op::ASSIGN, | ||
nyan_op::ADD_ASSIGN, | ||
|
@@ -403,6 +407,10 @@ Number<T>::allowed_operations(const Type &with_type) const { | |
case primitive_t::FLOAT: | ||
case primitive_t::INT: | ||
return ops; | ||
|
||
case primitive_t::NONE: | ||
return none_ops; | ||
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. why can we assign 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. |
||
|
||
default: | ||
return no_nyan_ops; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,10 +64,12 @@ const std::unordered_set<nyan_op> &ObjectValue::allowed_operations(const Type &w | |
nyan_op::ASSIGN, | ||
}; | ||
|
||
if (with_type.get_primitive_type() == primitive_t::OBJECT) { | ||
switch (with_type.get_primitive_type()) { | ||
case primitive_t::OBJECT: | ||
case primitive_t::NONE: | ||
return ops; | ||
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. why can we assign 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. |
||
} | ||
else { | ||
|
||
default: | ||
return no_nyan_ops; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,9 +69,9 @@ std::string OrderedSet::repr() const { | |
|
||
const std::unordered_set<nyan_op> &OrderedSet::allowed_operations(const Type &with_type) const { | ||
|
||
if (not with_type.is_container()) { | ||
return no_nyan_ops; | ||
} | ||
const static std::unordered_set<nyan_op> none_ops{ | ||
nyan_op::ASSIGN, | ||
}; | ||
|
||
const static std::unordered_set<nyan_op> orderedset_ops{ | ||
nyan_op::ASSIGN, | ||
|
@@ -88,6 +88,13 @@ const std::unordered_set<nyan_op> &OrderedSet::allowed_operations(const Type &wi | |
nyan_op::INTERSECT_ASSIGN, | ||
}; | ||
|
||
if (with_type.get_primitive_type() == primitive_t::NONE) { | ||
return none_ops; | ||
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. why can we assign 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. |
||
} | ||
|
||
if (not with_type.is_container()) { | ||
return no_nyan_ops; | ||
} | ||
|
||
switch (with_type.get_composite_type()) { | ||
case composite_t::ORDEREDSET: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,9 +73,9 @@ std::string Set::repr() const { | |
|
||
const std::unordered_set<nyan_op> &Set::allowed_operations(const Type &with_type) const { | ||
|
||
if (not with_type.is_container()) { | ||
return no_nyan_ops; | ||
} | ||
const static std::unordered_set<nyan_op> none_ops{ | ||
nyan_op::ASSIGN, | ||
}; | ||
|
||
const static std::unordered_set<nyan_op> set_ops{ | ||
nyan_op::ASSIGN, | ||
|
@@ -90,6 +90,14 @@ const std::unordered_set<nyan_op> &Set::allowed_operations(const Type &with_type | |
nyan_op::INTERSECT_ASSIGN, | ||
}; | ||
|
||
if (with_type.get_primitive_type() == primitive_t::NONE) { | ||
return none_ops; | ||
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. why can we assign 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. |
||
} | ||
|
||
if (not with_type.is_container()) { | ||
return no_nyan_ops; | ||
} | ||
|
||
switch (with_type.get_composite_type()) { | ||
case composite_t::SET: | ||
return set_ops; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,10 +79,18 @@ const std::unordered_set<nyan_op> &Text::allowed_operations(const Type &with_typ | |
nyan_op::ADD_ASSIGN, | ||
}; | ||
|
||
if (with_type.get_primitive_type() == primitive_t::TEXT) { | ||
const static std::unordered_set<nyan_op> none_ops{ | ||
nyan_op::ASSIGN, | ||
}; | ||
|
||
switch (with_type.get_primitive_type()) { | ||
case primitive_t::TEXT: | ||
return ops; | ||
} | ||
else { | ||
|
||
case primitive_t::NONE: | ||
return none_ops; | ||
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. why can we assign 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. |
||
|
||
default: | ||
return no_nyan_ops; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,6 +124,18 @@ static void handle_modifiers(const std::vector<Type> &modifiers, | |
const ValueHolder &value_holder, | ||
std::vector<std::pair<fqon_t, Location>> *objs_in_values) { | ||
bool contains_optional = false; | ||
for (auto &mod: modifiers) { | ||
auto modifier_type = mod.get_composite_type(); | ||
|
||
if (modifier_type == composite_t::OPTIONAL) { | ||
TheJJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||
contains_optional = true; | ||
} | ||
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. interesting corner case, which 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. It is just assigned to the member because 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. ok that resolves that, but what about |
||
} | ||
|
||
if (typeid(*value_holder.get_value()) == typeid(None&) and not contains_optional) { | ||
throw InternalError{"NoneValue is content, but no optional modifier was found"}; | ||
} | ||
|
||
for (auto &mod: modifiers) { | ||
auto modifier_type = mod.get_composite_type(); | ||
|
||
|
@@ -133,7 +145,9 @@ static void handle_modifiers(const std::vector<Type> &modifiers, | |
|
||
if (modifier_type == composite_t::CHILDREN) { | ||
if (unlikely(typeid(*value_holder.get_value()) != typeid(ObjectValue&))) { | ||
throw InternalError{"children type requires ObjectValue as content"}; | ||
if (not contains_optional) { | ||
throw InternalError{"children type requires ObjectValue as content"}; | ||
} | ||
} | ||
|
||
// Check if object fqon is a child (i.e. not the same fqon as the member type) | ||
|
@@ -147,19 +161,16 @@ static void handle_modifiers(const std::vector<Type> &modifiers, | |
|
||
if (modifier_type == composite_t::ABSTRACT) { | ||
if (unlikely(typeid(*value_holder.get_value()) != typeid(ObjectValue&))) { | ||
throw InternalError{"abstract type requires ObjectValue as content"}; | ||
if (not contains_optional) { | ||
throw InternalError{"abstract type requires ObjectValue as content"}; | ||
} | ||
} | ||
|
||
// Remove last element here, so the object is not checked | ||
// for non-abstractness later | ||
objs_in_values->pop_back(); | ||
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. that's bad, since there's also other checks with all the objects used as values. better would be that within that check which validates if objects used as values can be used as such, the checker is aware of the modifiers and validate 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. This is a list and not a set, so it's technically fine. It removes only the reference that was added right after the value was created. Although having a set overall would definitely better for not wasting memory on the value. 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. no, it's not about lists or sets, rather removing this object from the to-be-checked bunch of names :) |
||
} | ||
} | ||
|
||
if (typeid(*value_holder.get_value()) == typeid(None&) and not contains_optional) { | ||
throw InternalError{"NoneValue is content, but no optional modifier was found"}; | ||
} | ||
|
||
} | ||
ValueHolder Value::from_ast(const Type &target_type, | ||
const ASTMemberValue &astmembervalue, | ||
|
@@ -205,7 +216,7 @@ ValueHolder Value::from_ast(const Type &target_type, | |
return value; | ||
} | ||
|
||
composite_t composite_type = astmembervalue.get_composite_type(); | ||
composite_t composite_type = current_type.get_composite_type(); | ||
|
||
// For sets/orderedsets (with primitive values) | ||
std::vector<ValueHolder> values; | ||
|
@@ -218,17 +229,30 @@ ValueHolder Value::from_ast(const Type &target_type, | |
values.reserve(astmembervalue.get_values().size()); | ||
|
||
// convert all tokens to values | ||
const std::vector<Type> *element_type = target_type.get_element_type(); | ||
const std::vector<Type> *element_type = current_type.get_element_type(); | ||
if (unlikely(element_type == nullptr)) { | ||
throw InternalError{"container element type is nonexisting"}; | ||
} | ||
|
||
Type cur_elem_type = element_type->at(0); | ||
std::vector<Type> elem_modifiers; | ||
while (cur_elem_type.is_modifier()) { | ||
elem_modifiers.insert(elem_modifiers.begin(), cur_elem_type); | ||
cur_elem_type = cur_elem_type.get_element_type()->at(0); | ||
} | ||
|
||
std::vector<Type> target_types{cur_elem_type}; | ||
for (auto &value_token : astmembervalue.get_values()) { | ||
values.push_back( | ||
value_from_value_token(*element_type, | ||
value_token, | ||
get_fqon)[0] | ||
); | ||
ValueHolder value = value_from_value_token( | ||
target_types, | ||
value_token, | ||
get_fqon | ||
)[0]; | ||
|
||
handle_modifiers(elem_modifiers, value, objs_in_values); | ||
|
||
values.push_back(value); | ||
|
||
} | ||
|
||
switch (composite_type) { | ||
|
@@ -252,13 +276,32 @@ ValueHolder Value::from_ast(const Type &target_type, | |
throw InternalError{"container element type is nonexisting"}; | ||
} | ||
|
||
Type cur_elem_type_key = element_type->at(0); | ||
std::vector<Type> elem_modifiers_key; | ||
while (cur_elem_type_key.is_modifier()) { | ||
elem_modifiers_key.insert(elem_modifiers_key.begin(), cur_elem_type_key); | ||
cur_elem_type_key = cur_elem_type_key.get_element_type()->at(0); | ||
} | ||
|
||
Type cur_elem_type_value = element_type->at(1); | ||
std::vector<Type> elem_modifiers_value; | ||
while (cur_elem_type_value.is_modifier()) { | ||
elem_modifiers_value.insert(elem_modifiers_value.begin(), cur_elem_type_value); | ||
cur_elem_type_value = cur_elem_type_value.get_element_type()->at(0); | ||
} | ||
|
||
std::vector<Type> target_types{cur_elem_type_key, cur_elem_type_value}; | ||
|
||
for (auto &value_token : astmembervalue.get_values()) { | ||
std::vector<ValueHolder> keyval = value_from_value_token( | ||
*element_type, | ||
target_types, | ||
value_token, | ||
get_fqon | ||
); | ||
|
||
handle_modifiers(elem_modifiers_key, keyval[0], objs_in_values); | ||
handle_modifiers(elem_modifiers_value, keyval[1], objs_in_values); | ||
|
||
items.insert(std::make_pair(keyval[0], keyval[1])); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why can we assign
= None
to a dict? that shouldn't work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None
is assigned directly to the member, it's not applied like the other values. However, we still need to list it here because assigning None is an allowed operation.