OSDN Git Service

IRProcessor のイベント変換部分を追加
authorstarg <starg@users.osdn.me>
Tue, 13 Sep 2016 16:33:58 +0000 (01:33 +0900)
committerstarg <starg@users.osdn.me>
Tue, 13 Sep 2016 16:33:58 +0000 (01:33 +0900)
include/irprocessor/irprocessor.hpp
src/irprocessor/CMakeLists.txt
src/irprocessor/irprocessor.cpp
src/irprocessor/pch.hpp

index ce24bad..324b6f3 100644 (file)
@@ -1,8 +1,18 @@
 
 #pragma once
 
+#include <deque>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <boost/variant.hpp>
+
+#include <ast/attribute.hpp>
 #include <compiler/base.hpp>
 #include <ir/module.hpp>
+#include <irprocessor/attrprocfactory.hpp>
 
 namespace YAMML
 {
@@ -10,7 +20,7 @@ namespace YAMML
 namespace IRProcessor
 {
 
-class IRCompiler : public Compiler::CompilerBase
+class IRCompiler : public Compiler::CompilerBase, public boost::static_visitor<>
 {
 public:
     template<typename T>
@@ -26,10 +36,27 @@ public:
     std::string GetSourceName() const;
     const IR::Module& GetIR() const;
 
+    void operator()(IR::TrackList& trackList);
+    void operator()(AST::Command& command);
+
+    void operator()(IR::Event& ev);
+    void operator()(IR::BlockReference& blockRef);
+
+    void CompileBlock(IR::BlockReference blockRef);
+
 private:
     void CompileTrackBlock(std::size_t index);
 
+    void AddAttributeProcessorFactory(std::unique_ptr<IAttributeProcessorFactory> pAttributeProcessorFactory);
+    void InitializeAttributeProcessorFactories();
+
+    void RegisterAttributeProcessors(const std::vector<AST::Attribute>& attributes);
+
+    IR::BlockReference DuplicateBlock(IR::BlockReference blockRef);
+
     IR::Module m_IR;
+    std::unordered_map<std::string, std::unique_ptr<IAttributeProcessorFactory>> m_AttributeProcessorFactoryMap;
+    std::deque<std::vector<std::unique_ptr<IAttributeProcessor>>> m_AttributeProcessorStack;
 };
 
 } // namespace IRProcessor
index c3da93d..7d85943 100644 (file)
@@ -1,5 +1,7 @@
 
 set(IRProcessorHeaders
+    ../../include/irprocessor/attrproc.hpp
+    ../../include/irprocessor/attrprocfactory.hpp
     ../../include/irprocessor/irprocessor.hpp
 )
 
index f282b1e..7595fdb 100644 (file)
@@ -1,6 +1,9 @@
 
+#include <algorithm>
 #include <exception>
+#include <utility>
 
+#include <common/containerutil.hpp>
 #include <exceptions/messageexception.hpp>
 #include <irprocessor/irprocessor.hpp>
 #include <message/message.hpp>
@@ -55,26 +58,126 @@ const IR::Module& IRCompiler::GetIR() const
     return m_IR;
 }
 
+void IRCompiler::InitializeAttributeProcessorFactories()
+{
+
+}
+
+void IRCompiler::AddAttributeProcessorFactory(std::unique_ptr<IAttributeProcessorFactory> pAttributeProcessorFactory)
+{
+    auto name = pAttributeProcessorFactory->GetAttributeName();
+    m_AttributeProcessorFactoryMap[name] = std::move(pAttributeProcessorFactory);
+}
+
+void IRCompiler::RegisterAttributeProcessors(const std::vector<AST::Attribute>& attributes)
+{
+    std::vector<std::unique_ptr<IAttributeProcessor>> attrProcessors;
+    attrProcessors.reserve(attributes.size());
+
+    for (auto&& i : attributes)
+    {
+        auto itFactory = m_AttributeProcessorFactoryMap.find(i.Name);
+
+        if (itFactory == m_AttributeProcessorFactoryMap.end())
+        {
+            throw Exceptions::MessageException(
+                Message::MessageItem{
+                    Message::MessageKind::Error,
+                    Message::MessageID::InvalidAttributeName,
+                    GetSourceName(),
+                    i.Location,
+                    {i.Name}
+                }
+            );
+        }
+        else
+        {
+            attrProcessors.push_back(itFactory->second->CreateProcessor(i));
+        }
+    }
+
+    m_AttributeProcessorStack.push_back(std::move(attrProcessors));
+}
+
+IR::BlockReference IRCompiler::DuplicateBlock(IR::BlockReference blockRef)
+{
+    IR::BlockReference newRef{m_IR.Blocks.size()};
+    m_IR.Blocks.push_back(m_IR.Blocks.at(blockRef.ID));
+    return newRef;
+}
+
 void IRCompiler::CompileTrackBlock(std::size_t index)
 {
-    // TODO
+    RegisterAttributeProcessors(m_IR.TrackBlocks.at(index).Attributes);
+    Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
 
-    if (!m_IR.TrackBlocks[index].Attributes.empty())
+    for (auto&& i : m_IR.TrackBlocks[index].Blocks)
     {
-        auto attribute = m_IR.TrackBlocks[index].Attributes.at(0);
+        i.apply_visitor(*this);
+    }
+}
 
-        throw Exceptions::MessageException(
-            Message::MessageItem{
-                Message::MessageKind::Error,
-                Message::MessageID::InvalidAttributeName,
-                GetSourceName(),
-                attribute.Location,
-                {attribute.Name}
-            }
-        );
+void IRCompiler::operator()(IR::TrackList& trackList)
+{
+    RegisterAttributeProcessors(trackList.Attributes);
+    Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
+
+    for (auto&& i : trackList.Tracks)
+    {
+        RegisterAttributeProcessors(i.Attributes);
+        Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop2(m_AttributeProcessorStack);
+
+        for (auto&& j : i.Items)
+        {
+            RegisterAttributeProcessors(j.Attributes);
+            Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop3(m_AttributeProcessorStack);
+
+            auto dupRef = DuplicateBlock(j.Block);
+            j.Block = dupRef;
+
+            CompileBlock(dupRef);
+        }
     }
 }
 
+void IRCompiler::operator()(AST::Command&)
+{
+    // no-op
+}
+
+void IRCompiler::CompileBlock(IR::BlockReference blockRef)
+{
+    RegisterAttributeProcessors(m_IR.Blocks.at(blockRef.ID).Attributes);
+    Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
+
+    for (auto&& i : m_IR.Blocks[blockRef.ID].Events)
+    {
+        i.apply_visitor(*this);
+    }
+}
+
+void IRCompiler::operator()(IR::Event& ev)
+{
+    std::for_each(
+        m_AttributeProcessorStack.rbegin(),
+        m_AttributeProcessorStack.rend(),
+        [&ev] (auto&& x)
+        {
+            for (auto&& i : x)
+            {
+                i->TransformEvent(ev);
+            }
+        }
+    );
+}
+
+void IRCompiler::operator()(IR::BlockReference& blockRef)
+{
+    // 'blockRef' here should be referenced by a single block, thus no need to duplicate it.
+    // blockRef = DuplicateBlock(blockRef);
+    CompileBlock(blockRef);
+}
+
 } // namespace IRProcessor
 
 } // namespace YAMML
index fd4f8fd..3d402e2 100644 (file)
@@ -2,8 +2,10 @@
 #pragma once
 
 #include <algorithm>
+#include <deque>
 #include <exception>
 #include <functional>
+#include <memory>
 #include <string>
 #include <unordered_map>
 #include <utility>