Index operator binds more tightly then function call

This commit is contained in:
Robert Bendun 2022-06-11 17:55:52 +02:00
parent b7d879bf70
commit b930ef4e6e
4 changed files with 27 additions and 2 deletions

View File

@ -2,7 +2,7 @@ MAKEFLAGS="-j $(grep -c ^processor /proc/cpuinfo)"
CXXFLAGS:=$(CXXFLAGS) -std=c++20 -Wall -Wextra -Werror=switch -Werror=return-type -Werror=unused-result CXXFLAGS:=$(CXXFLAGS) -std=c++20 -Wall -Wextra -Werror=switch -Werror=return-type -Werror=unused-result
CPPFLAGS:=$(CPPFLAGS) -Ilib/expected/ -Ilib/ut/ -Ilib/midi/include -Isrc/ CPPFLAGS:=$(CPPFLAGS) -Ilib/expected/ -Ilib/ut/ -Ilib/midi/include -Isrc/
RELEASE_FLAGS=-O3 RELEASE_FLAGS=-O3
DEBUG_FLAGS=-O0 -ggdb DEBUG_FLAGS=-O0 -ggdb -fsanitize=undefined
CXX=g++ CXX=g++
LDFLAGS=-L./lib/midi/ LDFLAGS=-L./lib/midi/

View File

@ -151,6 +151,10 @@ def main():
print("[ERROR] Expected test case") print("[ERROR] Expected test case")
exit(1) exit(1)
interpreter = os.getenv("INTERPRETER")
if interpreter:
Interpreter = interpreter
for path in argv[2:]: for path in argv[2:]:
if os.path.exists(path): if os.path.exists(path):
if os.path.isdir(path): if os.path.isdir(path):

View File

@ -561,6 +561,9 @@ struct Parser
/// Parse infix expression /// Parse infix expression
Result<Ast> parse_infix_expression(); Result<Ast> parse_infix_expression();
/// Parse either index expression or atomic expression
Result<Ast> parse_index_expression();
/// Parse function call, literal etc /// Parse function call, literal etc
Result<Ast> parse_atomic_expression(); Result<Ast> parse_atomic_expression();

View File

@ -119,10 +119,11 @@ Result<Ast> Parser::parse_variable_declaration()
Result<Ast> Parser::parse_infix_expression() Result<Ast> Parser::parse_infix_expression()
{ {
auto atomics = Try(parse_many(*this, &Parser::parse_atomic_expression, std::nullopt, At_Least::One)); auto atomics = Try(parse_many(*this, &Parser::parse_index_expression, std::nullopt, At_Least::One));
auto lhs = wrap_if_several(std::move(atomics), Ast::call); auto lhs = wrap_if_several(std::move(atomics), Ast::call);
if (expect(Token::Type::Operator) || expect(Token::Type::Keyword, "and") || expect(Token::Type::Keyword, "or")) { if (expect(Token::Type::Operator) || expect(Token::Type::Keyword, "and") || expect(Token::Type::Keyword, "or")) {
assert(not expect(Token::Type::Operator, "."), "This should be handled by parse_index_expression");
auto op = consume(); auto op = consume();
return parse_expression().map([&](Ast rhs) { return parse_expression().map([&](Ast rhs) {
return Ast::binary(std::move(op), std::move(lhs), std::move(rhs)); return Ast::binary(std::move(op), std::move(lhs), std::move(rhs));
@ -132,6 +133,23 @@ Result<Ast> Parser::parse_infix_expression()
return lhs; return lhs;
} }
Result<Ast> Parser::parse_index_expression()
{
auto result = Try(parse_atomic_expression());
while (expect(Token::Type::Operator, ".")) {
auto op = consume();
if (auto maybe_index = parse_atomic_expression(); maybe_index.has_value()) {
result = Ast::binary(std::move(op), std::move(result), *std::move(maybe_index));
} else {
// TODO Report that error occured during parsing of index expression
return std::move(maybe_index).error();
}
}
return result;
}
Result<Ast> Parser::parse_atomic_expression() Result<Ast> Parser::parse_atomic_expression()
{ {
switch (Try(peek_type())) { switch (Try(peek_type())) {