Report error when index is too large

This commit is contained in:
Robert Bendun 2022-09-04 13:16:40 +02:00
parent 3b1500313c
commit 1597b678e1
3 changed files with 36 additions and 3 deletions

View File

@ -166,6 +166,16 @@ namespace errors
std::string name;
};
/// When user tries to get element from collection with index higher then collection size
struct Out_Of_Range
{
/// Index that was required by the user
size_t required_index;
/// Size of accessed collection
size_t size;
};
/// Collection of messages that are considered internal and should not be printed to the end user.
namespace internal
{
@ -191,6 +201,7 @@ namespace errors
Missing_Variable,
Not_Callable,
Operation_Requires_Midi_Connection,
Out_Of_Range,
Undefined_Operator,
Unexpected_Empty_Source,
Unexpected_Keyword,

View File

@ -145,6 +145,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
[](errors::internal::Unexpected_Token const&) { return "Unexpected token"; },
[](errors::Expected_Expression_Separator_Before const&) { return "Missing semicolon"; },
[](errors::Literal_As_Identifier const&) { return "Literal used in place of an identifier"; },
[](errors::Out_Of_Range const&) { return "Index out of range"; },
[](errors::Unsupported_Types_For const& type) {
return type.type == errors::Unsupported_Types_For::Function
? "Function called with wrong arguments"
@ -339,6 +340,18 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
}
os << '\n' << pretty::end;
},
[&](errors::Out_Of_Range const& err) {
if (err.size == 0) {
os << "Can't get " << err.required_index << " element out of empty collection\n";
} else {
os << "Can't get " << err.required_index << " element from collection with only " << err.size << " elements\n";
}
os << '\n';
print_error_line(loc);
},
[&](errors::Unexpected_Keyword const&) { unimplemented(); },
}, err.details);

View File

@ -348,16 +348,25 @@ Result<Value> Block::operator()(Interpreter &i, std::vector<Value> arguments)
return result;
}
/// Helper that produces error when trying to access container with too few elements for given index
static inline Result<void> guard_index(unsigned index, unsigned size)
{
if (index < size) return {};
return Error {
.details = errors::Out_Of_Range { .required_index = index, .size = size }
};
}
// TODO Add memoization
Result<Value> Block::index(Interpreter &i, unsigned position)
{
assert(parameters.size() == 0, "cannot index into block with parameters (for now)");
if (body.type != Ast::Type::Sequence) {
assert(position == 0, "Out of range"); // TODO(assert)
Try(guard_index(position, 1));
return i.eval((Ast)body);
}
assert(position < body.arguments.size(), "Out of range"); // TODO(assert)
Try(guard_index(position, body.arguments.size()));
return i.eval((Ast)body.arguments[position]);
}
@ -368,7 +377,7 @@ usize Block::size() const
Result<Value> Array::index(Interpreter &, unsigned position)
{
assert(position < elements.size(), "Out of range"); // TODO(assert)
Try(guard_index(position, elements.size()));
return elements[position];
}