OSDN Git Service

NoteRepeatEachExpression 関連の簡素化・修正
authorstarg <starg@users.osdn.me>
Mon, 22 Aug 2016 05:58:41 +0000 (14:58 +0900)
committerstarg <starg@users.osdn.me>
Mon, 22 Aug 2016 05:58:41 +0000 (14:58 +0900)
include/ast/phrase.hpp
src/ast2ir/phrase2ir.cpp
src/ast2ir/phrase2ir.hpp
src/parser/action_state_phrase.hpp
test/parser/parsertest.cpp

index c3362c5..86dab8b 100644 (file)
@@ -1,6 +1,7 @@
 
 #pragma once
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -95,7 +96,7 @@ class NoteRepeatExpression final
 {
 public:
     std::size_t Count;
-    std::vector<boost::variant<NoteAndDuration, boost::recursive_wrapper<NoteSequence>>> Notes;
+    std::vector<boost::recursive_wrapper<NoteSequence>> Notes;
     SourceLocation Location;
 };
 
@@ -103,7 +104,7 @@ class NoteRepeatEachExpression final
 {
 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;
 };
 
index 3eca89a..a5b4605 100644 (file)
@@ -147,19 +147,27 @@ IR::Block::EventType Phrase2IRCompiler::operator()(const AST::NoteSequence& ast)
 
     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;
 }
 
@@ -186,7 +194,7 @@ IR::Block::EventType Phrase2IRCompiler::operator()(const AST::NoteRepeatExpressi
         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++)
@@ -207,11 +215,14 @@ IR::Block::EventType Phrase2IRCompiler::operator()(const AST::NoteRepeatEachExpr
 
     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);
+            }
         }
     }
 
index d53ab2a..a056684 100644 (file)
@@ -32,6 +32,7 @@ public:
     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);
index 4fc8b97..7c8cad1 100644 (file)
@@ -4,6 +4,7 @@
 #include <algorithm>
 #include <string>
 #include <type_traits>
+#include <utility>
 
 #include <pegtl.hh>
 
@@ -20,6 +21,20 @@ namespace YAMML
 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:
@@ -217,7 +232,7 @@ 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)
@@ -255,7 +270,7 @@ 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::SimpleDurationWithModifier node)
index f836e47..c097895 100644 (file)
@@ -62,27 +62,27 @@ composition Main
             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());