diff --git a/Makefile b/Makefile index 829c7a9..bfad6f9 100644 --- a/Makefile +++ b/Makefile @@ -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 CPPFLAGS:=$(CPPFLAGS) -Ilib/expected/ -Ilib/ut/ -Ilib/midi/include -Isrc/ RELEASE_FLAGS=-O3 -DEBUG_FLAGS=-O0 -ggdb +DEBUG_FLAGS=-O0 -ggdb -fsanitize=undefined CXX=g++ LDFLAGS=-L./lib/midi/ diff --git a/etc/tools/test.py b/etc/tools/test.py index 5c35402..82934f2 100755 --- a/etc/tools/test.py +++ b/etc/tools/test.py @@ -151,6 +151,10 @@ def main(): print("[ERROR] Expected test case") exit(1) + interpreter = os.getenv("INTERPRETER") + if interpreter: + Interpreter = interpreter + for path in argv[2:]: if os.path.exists(path): if os.path.isdir(path): diff --git a/src/musique.hh b/src/musique.hh index 031d42a..9ebc20c 100644 --- a/src/musique.hh +++ b/src/musique.hh @@ -561,6 +561,9 @@ struct Parser /// Parse infix expression Result parse_infix_expression(); + /// Parse either index expression or atomic expression + Result parse_index_expression(); + /// Parse function call, literal etc Result parse_atomic_expression(); diff --git a/src/parser.cc b/src/parser.cc index e45fd87..a21611d 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -119,10 +119,11 @@ Result Parser::parse_variable_declaration() Result 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); 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(); return parse_expression().map([&](Ast rhs) { return Ast::binary(std::move(op), std::move(lhs), std::move(rhs)); @@ -132,6 +133,23 @@ Result Parser::parse_infix_expression() return lhs; } +Result 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 Parser::parse_atomic_expression() { switch (Try(peek_type())) {