#pragma once
+#include <memory>
#include <string>
#include <vector>
{
public:
std::size_t Count;
- std::vector<boost::variant<NoteAndDuration, boost::recursive_wrapper<NoteSequence>>> Notes;
+ std::vector<boost::recursive_wrapper<NoteSequence>> Notes;
SourceLocation Location;
};
{
public:
std::size_t Count;
- std::vector<boost::variant<NoteAndDuration, NoteRepeatExpression, boost::recursive_wrapper<NoteSequence>>> Notes;
+ std::vector<boost::recursive_wrapper<NoteSequence>> Notes;
SourceLocation Location;
};
for (auto&& i : ast.Notes)
{
- int startTime = m_DeltaTime;
- int endTime = startTime;
+ m_IR.Blocks[newIndex.ID].Events.emplace_back((*this)(i));
+ }
- for (auto&& j : i.Notes)
- {
- m_IR.Blocks[newIndex.ID].Events.emplace_back(j.apply_visitor(*this));
- endTime = std::max(endTime, m_DeltaTime);
- m_DeltaTime = startTime;
- }
+ return newIndex;
+}
+
+IR::Block::EventType Phrase2IRCompiler::operator()(const AST::NoteAndExpression& ast)
+{
+ auto newIndex = AllocBlock();
+
+ int startTime = m_DeltaTime;
+ int endTime = startTime;
- m_DeltaTime = endTime;
+ for (auto&& i : ast.Notes)
+ {
+ m_IR.Blocks[newIndex.ID].Events.emplace_back(i.apply_visitor(*this));
+ endTime = std::max(endTime, m_DeltaTime);
+ m_DeltaTime = startTime;
}
+ m_DeltaTime = endTime;
return newIndex;
}
ast.Notes.begin(),
ast.Notes.end(),
childBlockEventArray.begin(),
- [this] (auto&& x) { return x.apply_visitor(*this); }
+ [this] (auto&& x) { return (*this)(x.get()); }
);
for (std::size_t i = 0; i < ast.Count; i++)
for (auto&& i : ast.Notes)
{
- auto childBlockItem = i.apply_visitor(*this);
-
- for (std::size_t j = 0; j < ast.Count; j++)
+ for (auto&& j : i.get().Notes)
{
- m_IR.Blocks[newIndex.ID].Events.emplace_back(childBlockItem);
+ auto childBlockItem = (*this)(j);
+
+ for (std::size_t k = 0; k < ast.Count; k++)
+ {
+ m_IR.Blocks[newIndex.ID].Events.emplace_back(childBlockItem);
+ }
}
}
IR::Block::EventType operator()(const AST::NoteSequenceBlock& ast);
IR::Block::EventType operator()(const AST::NoteSequence& ast);
+ IR::Block::EventType operator()(const AST::NoteAndExpression& ast);
IR::Block::EventType operator()(const AST::NoteAndDuration& ast);
IR::Block::EventType operator()(const AST::NoteRepeatExpression& ast);
#include <algorithm>
#include <string>
#include <type_traits>
+#include <utility>
#include <pegtl.hh>
namespace Parser
{
+template<typename T>
+AST::NoteSequence MakeNoteSequence(T node)
+{
+ AST::NoteAndExpression nae;
+ nae.Location = node.Location;
+ nae.Notes.emplace_back(node);
+
+ AST::NoteSequence ns;
+ ns.Location = node.Location;
+ ns.Notes.push_back(std::move(nae));
+
+ return ns;
+}
+
class PhraseState
{
public:
template<typename TParentState, typename... TCommonStates>
void success(TParentState& st, TCommonStates&...)
{
- st.ASTNode.Notes.emplace_back(ASTNode);
+ st.ASTNode.Notes.emplace_back(MakeNoteSequence(ASTNode));
}
void OnParse(AST::NoteSequence node)
template<typename TParentState, typename... TCommonStates>
void success(TParentState& st, TCommonStates&...)
{
- st.ASTNode.Notes.emplace_back(ASTNode);
+ st.ASTNode.Notes.emplace_back(MakeNoteSequence(ASTNode));
}
void OnParse(AST::SimpleDurationWithModifier node)
BOOST_REQUIRE(noteSeqStatement.NoteSeq.is_initialized());
auto noteSeq = *noteSeqStatement.NoteSeq;
- BOOST_CHECK_EQUAL(noteSeq.Notes.size(), 1u);
+ BOOST_REQUIRE_EQUAL(noteSeq.Notes.size(), 1u);
auto noteAndExpr = noteSeq.Notes.at(0);
- BOOST_CHECK_EQUAL(noteAndExpr.Notes.size(), 3u);
+ BOOST_REQUIRE_EQUAL(noteAndExpr.Notes.size(), 3u);
{
- auto noteAndDuration = boost::get<AST::NoteAndDuration>(noteAndExpr.Notes.at(0));
+ auto noteAndDuration = boost::get<AST::NoteAndDuration>(boost::get<AST::NoteSequence>(noteAndExpr.Notes.at(0)).Notes.at(0).Notes.at(0));
BOOST_CHECK(!noteAndDuration.Duration.is_initialized());
BOOST_CHECK_EQUAL(boost::get<AST::NoteNumber>(noteAndDuration.Note).Name.Name, 'C');
BOOST_CHECK(!boost::get<AST::NoteNumber>(noteAndDuration.Note).Octave.is_initialized());
}
{
- auto noteAndDuration = boost::get<AST::NoteAndDuration>(noteAndExpr.Notes.at(1));
+ auto noteAndDuration = boost::get<AST::NoteAndDuration>(boost::get<AST::NoteSequence>(noteAndExpr.Notes.at(1)).Notes.at(0).Notes.at(0));
BOOST_CHECK(!noteAndDuration.Duration.is_initialized());
BOOST_CHECK_EQUAL(boost::get<AST::NoteNumber>(noteAndDuration.Note).Name.Name, 'E');
BOOST_CHECK(!boost::get<AST::NoteNumber>(noteAndDuration.Note).Octave.is_initialized());
}
{
- auto noteAndDuration = boost::get<AST::NoteAndDuration>(noteAndExpr.Notes.at(2));
+ auto noteAndDuration = boost::get<AST::NoteAndDuration>(boost::get<AST::NoteSequence>(noteAndExpr.Notes.at(2)).Notes.at(0).Notes.at(0));
BOOST_CHECK(!noteAndDuration.Duration.is_initialized());
BOOST_CHECK_EQUAL(boost::get<AST::NoteNumber>(noteAndDuration.Note).Name.Name, 'G');
BOOST_CHECK(!boost::get<AST::NoteNumber>(noteAndDuration.Note).Octave.is_initialized());