Fix nested arithmetic expressions with undefined operator
This commit is contained in:
parent
a03d22ce8d
commit
ddad9eafba
@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `ceil`, `round`, `floor` didn't behave well with negative numbers
|
- `ceil`, `round`, `floor` didn't behave well with negative numbers
|
||||||
- `duration` wasn't filling note length from context and summed all notes inside chord, when it should take max
|
- `duration` wasn't filling note length from context and summed all notes inside chord, when it should take max
|
||||||
- `try` evaluated arguments too quickly
|
- `try` evaluated arguments too quickly
|
||||||
|
- Nested arithmetic expression with undefined operator reports proper error and don't crash
|
||||||
|
|
||||||
## [0.3.1]
|
## [0.3.1]
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
static Ast wrap_if_several(std::vector<Ast> &&ast, Ast(*wrapper)(std::vector<Ast>));
|
static Ast wrap_if_several(std::vector<Ast> &&ast, Ast(*wrapper)(std::vector<Ast>));
|
||||||
|
|
||||||
static usize precedense(std::string_view op);
|
static std::optional<usize> precedense(std::string_view op);
|
||||||
|
|
||||||
static inline bool is_identifier_looking(Token::Type type)
|
static inline bool is_identifier_looking(Token::Type type)
|
||||||
{
|
{
|
||||||
@ -159,8 +159,23 @@ Result<Ast> Parser::parse_rhs_of_infix_expression(Ast lhs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto op = consume();
|
auto op = consume();
|
||||||
|
auto lhs_precedense = precedense(lhs.token.source);
|
||||||
|
auto op_precedense = precedense(op.source);
|
||||||
|
|
||||||
if (precedense(lhs.token.source) >= precedense(op.source)) {
|
if (!lhs_precedense) {
|
||||||
|
return Error {
|
||||||
|
.details = errors::Undefined_Operator { .op = std::string(lhs.token.source), },
|
||||||
|
.location = lhs.token.location,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!op_precedense) {
|
||||||
|
return Error {
|
||||||
|
.details = errors::Undefined_Operator { .op = std::string(op.source), },
|
||||||
|
.location = op.location,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*lhs_precedense >= *op_precedense) {
|
||||||
lhs.arguments.emplace_back(std::move(rhs));
|
lhs.arguments.emplace_back(std::move(rhs));
|
||||||
Ast ast;
|
Ast ast;
|
||||||
ast.location = op.location;
|
ast.location = op.location;
|
||||||
@ -544,7 +559,7 @@ constexpr bool one_of(std::string_view id, auto const& ...args)
|
|||||||
return ((id == args) || ...);
|
return ((id == args) || ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
static usize precedense(std::string_view op)
|
static std::optional<usize> precedense(std::string_view op)
|
||||||
{
|
{
|
||||||
// Operators that are not included below are
|
// Operators that are not included below are
|
||||||
// postfix index operator [] since it have own precedense rules and is not binary expression but its own kind of expression
|
// postfix index operator [] since it have own precedense rules and is not binary expression but its own kind of expression
|
||||||
@ -562,7 +577,7 @@ static usize precedense(std::string_view op)
|
|||||||
if (one_of(op, "*", "/", "%", "&")) return 400;
|
if (one_of(op, "*", "/", "%", "&")) return 400;
|
||||||
if (one_of(op, "**")) return 500;
|
if (one_of(op, "**")) return 500;
|
||||||
|
|
||||||
unreachable();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(Ast const& lhs, Ast const& rhs)
|
bool operator==(Ast const& lhs, Ast const& rhs)
|
||||||
|
Loading…
Reference in New Issue
Block a user