diff --git a/doc/protocol.xml b/doc/protocol.xml index 23584b5f0..0b49cedab 100644 --- a/doc/protocol.xml +++ b/doc/protocol.xml @@ -268,6 +268,13 @@ time stamp). + + + + "EXPRESSION1 AND EXPRESSION2 ...": combine two or + more expressions with logical "and". + + diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index e9d609a5f..35a4b9865 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -334,7 +334,23 @@ SongFilter::ParseExpression(const char *&s, bool fold_case) return first; } - throw std::runtime_error("Nested expressions not yet implemented"); + if (ExpectWord(s) != "AND") + throw std::runtime_error("'AND' expected"); + + auto and_filter = std::make_unique(); + and_filter->AddItem(std::move(first)); + + while (true) { + and_filter->AddItem(ParseExpression(s, fold_case)); + + if (*s == ')') { + ++s; + return and_filter; + } + + if (ExpectWord(s) != "AND") + throw std::runtime_error("'AND' expected"); + } } auto type = ExpectFilterType(s);