Report error when index is too large
This commit is contained in:
parent
3b1500313c
commit
1597b678e1
@ -166,6 +166,16 @@ namespace errors
|
|||||||
std::string name;
|
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.
|
/// Collection of messages that are considered internal and should not be printed to the end user.
|
||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
@ -191,6 +201,7 @@ namespace errors
|
|||||||
Missing_Variable,
|
Missing_Variable,
|
||||||
Not_Callable,
|
Not_Callable,
|
||||||
Operation_Requires_Midi_Connection,
|
Operation_Requires_Midi_Connection,
|
||||||
|
Out_Of_Range,
|
||||||
Undefined_Operator,
|
Undefined_Operator,
|
||||||
Unexpected_Empty_Source,
|
Unexpected_Empty_Source,
|
||||||
Unexpected_Keyword,
|
Unexpected_Keyword,
|
||||||
|
@ -145,6 +145,7 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
|||||||
[](errors::internal::Unexpected_Token const&) { return "Unexpected token"; },
|
[](errors::internal::Unexpected_Token const&) { return "Unexpected token"; },
|
||||||
[](errors::Expected_Expression_Separator_Before const&) { return "Missing semicolon"; },
|
[](errors::Expected_Expression_Separator_Before const&) { return "Missing semicolon"; },
|
||||||
[](errors::Literal_As_Identifier const&) { return "Literal used in place of an identifier"; },
|
[](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) {
|
[](errors::Unsupported_Types_For const& type) {
|
||||||
return type.type == errors::Unsupported_Types_For::Function
|
return type.type == errors::Unsupported_Types_For::Function
|
||||||
? "Function called with wrong arguments"
|
? "Function called with wrong arguments"
|
||||||
@ -339,6 +340,18 @@ std::ostream& operator<<(std::ostream& os, Error const& err)
|
|||||||
}
|
}
|
||||||
os << '\n' << pretty::end;
|
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(); },
|
[&](errors::Unexpected_Keyword const&) { unimplemented(); },
|
||||||
}, err.details);
|
}, err.details);
|
||||||
|
|
||||||
|
15
src/value.cc
15
src/value.cc
@ -348,16 +348,25 @@ Result<Value> Block::operator()(Interpreter &i, std::vector<Value> arguments)
|
|||||||
return result;
|
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
|
// TODO Add memoization
|
||||||
Result<Value> Block::index(Interpreter &i, unsigned position)
|
Result<Value> Block::index(Interpreter &i, unsigned position)
|
||||||
{
|
{
|
||||||
assert(parameters.size() == 0, "cannot index into block with parameters (for now)");
|
assert(parameters.size() == 0, "cannot index into block with parameters (for now)");
|
||||||
if (body.type != Ast::Type::Sequence) {
|
if (body.type != Ast::Type::Sequence) {
|
||||||
assert(position == 0, "Out of range"); // TODO(assert)
|
Try(guard_index(position, 1));
|
||||||
return i.eval((Ast)body);
|
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]);
|
return i.eval((Ast)body.arguments[position]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +377,7 @@ usize Block::size() const
|
|||||||
|
|
||||||
Result<Value> Array::index(Interpreter &, unsigned position)
|
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];
|
return elements[position];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user