Skip to content

Commit

Permalink
Merge pull request #101 from paulfd/parser-rework
Browse files Browse the repository at this point in the history
Changed the way the parser handles multiple parameters in opcodes
  • Loading branch information
paulfd authored Mar 6, 2020
2 parents eed69f8 + 692b2cd commit 291920f
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 281 deletions.
40 changes: 4 additions & 36 deletions src/sfizz/Opcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,19 @@ sfz::Opcode::Opcode(absl::string_view inputOpcode, absl::string_view inputValue)
while (nextNumIndex != opcode.npos) {
const auto numLetters = nextNumIndex - nextCharIndex;
parameterPosition += numLetters;
lettersOnlyHash = hash(opcode.substr(nextCharIndex, numLetters), lettersOnlyHash);
lettersOnlyHash = hashNoAmpersand(opcode.substr(nextCharIndex, numLetters), lettersOnlyHash);
nextCharIndex = opcode.find_first_not_of("1234567890", nextNumIndex);

uint32_t returnedValue;
hasBackParameter = (nextCharIndex == opcode.npos);
const auto numDigits = hasBackParameter ? opcode.npos : nextCharIndex - nextNumIndex;
const auto numDigits = (nextCharIndex == opcode.npos) ? opcode.npos : nextCharIndex - nextNumIndex;
if (absl::SimpleAtoi(opcode.substr(nextNumIndex, numDigits), &returnedValue)) {
// ASSERT(returnedValue < std::numeric_limits<uint8_t>::max());
parameterPositions.push_back(parameterPosition);
lettersOnlyHash = hash("&", lettersOnlyHash);
parameters.push_back(returnedValue);
}

nextNumIndex = opcode.find_first_of("1234567890", nextCharIndex);
}

if (nextCharIndex != opcode.npos)
lettersOnlyHash = hash(opcode.substr(nextCharIndex), lettersOnlyHash);
}

absl::optional<uint8_t> sfz::Opcode::backParameter() const noexcept
{
if (hasBackParameter && !parameters.empty())
return parameters.back();

return {};
}

absl::optional<uint8_t> sfz::Opcode::firstParameter() const noexcept
{
if (!hasBackParameter && !parameters.empty())
return parameters.front();

if (hasBackParameter && parameters.size() > 1)
return parameters.front();

return {};
}

absl::optional<uint8_t> sfz::Opcode::middleParameter() const noexcept
{
if (!hasBackParameter && parameters.size() > 1)
return parameters[1];

if (hasBackParameter && parameters.size() > 2)
return parameters[1];

return {};
lettersOnlyHash = hashNoAmpersand(opcode.substr(nextCharIndex), lettersOnlyHash);
}
12 changes: 3 additions & 9 deletions src/sfizz/Opcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ namespace sfz {
*/
struct Opcode {
Opcode() = delete;
absl::optional<uint8_t> backParameter() const noexcept;
absl::optional<uint8_t> firstParameter() const noexcept;
absl::optional<uint8_t> middleParameter() const noexcept;
Opcode(absl::string_view inputOpcode, absl::string_view inputValue);
absl::string_view opcode {};
absl::string_view value {};
uint64_t lettersOnlyHash { Fnv1aBasis };
// This is to handle the integer parameters of some opcodes
std::vector<uint8_t> parameters;
std::vector<int> parameterPositions;
bool hasBackParameter { false };
std::vector<uint16_t> parameters;
LEAK_DETECTOR(Opcode);
};

Expand Down Expand Up @@ -192,9 +187,8 @@ template <class ValueType>
inline void setCCPairFromOpcode(const Opcode& opcode, absl::optional<CCValuePair>& target, const Range<ValueType>& validRange)
{
auto value = readOpcode(opcode.value, validRange);
const auto backParameter = opcode.backParameter();
if (value && backParameter && Default::ccNumberRange.containsWithEnd(*backParameter))
target = std::make_pair(*backParameter, *value);
if (value && Default::ccNumberRange.containsWithEnd(opcode.parameters.back()))
target = std::make_pair(opcode.parameters.back(), *value);
else
target = {};
}
Expand Down
Loading

0 comments on commit 291920f

Please sign in to comment.