OSDN Git Service

IRProcessor のイベント変換部分を追加
[yamml/yamml-git.git] / src / irprocessor / irprocessor.cpp
1
2 #include <algorithm>
3 #include <exception>
4 #include <utility>
5
6 #include <common/containerutil.hpp>
7 #include <exceptions/messageexception.hpp>
8 #include <irprocessor/irprocessor.hpp>
9 #include <message/message.hpp>
10
11 namespace YAMML
12 {
13
14 namespace IRProcessor
15 {
16
17 bool IRCompiler::Compile()
18 {
19     try
20     {
21         std::size_t numberOfTrackBlocks = m_IR.TrackBlocks.size();
22
23         for (std::size_t i = 0; i < numberOfTrackBlocks; i++)
24         {
25             CompileTrackBlock(i);
26         }
27
28         return !HasErrors();
29     }
30     catch (const Exceptions::MessageException& e)
31     {
32         AddMessage(e.Item);
33         return false;
34     }
35     catch (const std::exception& e)
36     {
37         AddMessage(
38             Message::MessageItem{
39                 Message::MessageKind::FetalError,
40                 Message::MessageID::UnknownInIRProcessor,
41                 GetSourceName(),
42                 {0, 0},
43                 {e.what()}
44             }
45         );
46
47         return false;
48     }
49 }
50
51 std::string IRCompiler::GetSourceName() const
52 {
53     return m_IR.Name;
54 }
55
56 const IR::Module& IRCompiler::GetIR() const
57 {
58     return m_IR;
59 }
60
61 void IRCompiler::InitializeAttributeProcessorFactories()
62 {
63
64 }
65
66 void IRCompiler::AddAttributeProcessorFactory(std::unique_ptr<IAttributeProcessorFactory> pAttributeProcessorFactory)
67 {
68     auto name = pAttributeProcessorFactory->GetAttributeName();
69     m_AttributeProcessorFactoryMap[name] = std::move(pAttributeProcessorFactory);
70 }
71
72 void IRCompiler::RegisterAttributeProcessors(const std::vector<AST::Attribute>& attributes)
73 {
74     std::vector<std::unique_ptr<IAttributeProcessor>> attrProcessors;
75     attrProcessors.reserve(attributes.size());
76
77     for (auto&& i : attributes)
78     {
79         auto itFactory = m_AttributeProcessorFactoryMap.find(i.Name);
80
81         if (itFactory == m_AttributeProcessorFactoryMap.end())
82         {
83             throw Exceptions::MessageException(
84                 Message::MessageItem{
85                     Message::MessageKind::Error,
86                     Message::MessageID::InvalidAttributeName,
87                     GetSourceName(),
88                     i.Location,
89                     {i.Name}
90                 }
91             );
92         }
93         else
94         {
95             attrProcessors.push_back(itFactory->second->CreateProcessor(i));
96         }
97     }
98
99     m_AttributeProcessorStack.push_back(std::move(attrProcessors));
100 }
101
102 IR::BlockReference IRCompiler::DuplicateBlock(IR::BlockReference blockRef)
103 {
104     IR::BlockReference newRef{m_IR.Blocks.size()};
105     m_IR.Blocks.push_back(m_IR.Blocks.at(blockRef.ID));
106     return newRef;
107 }
108
109 void IRCompiler::CompileTrackBlock(std::size_t index)
110 {
111     RegisterAttributeProcessors(m_IR.TrackBlocks.at(index).Attributes);
112     Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
113
114     for (auto&& i : m_IR.TrackBlocks[index].Blocks)
115     {
116         i.apply_visitor(*this);
117     }
118 }
119
120 void IRCompiler::operator()(IR::TrackList& trackList)
121 {
122     RegisterAttributeProcessors(trackList.Attributes);
123     Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
124
125     for (auto&& i : trackList.Tracks)
126     {
127         RegisterAttributeProcessors(i.Attributes);
128         Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop2(m_AttributeProcessorStack);
129
130         for (auto&& j : i.Items)
131         {
132             RegisterAttributeProcessors(j.Attributes);
133             Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop3(m_AttributeProcessorStack);
134
135             auto dupRef = DuplicateBlock(j.Block);
136             j.Block = dupRef;
137
138             CompileBlock(dupRef);
139         }
140     }
141 }
142
143 void IRCompiler::operator()(AST::Command&)
144 {
145     // no-op
146 }
147
148 void IRCompiler::CompileBlock(IR::BlockReference blockRef)
149 {
150     RegisterAttributeProcessors(m_IR.Blocks.at(blockRef.ID).Attributes);
151     Common::AutoPop<decltype(m_AttributeProcessorStack)> autoPop(m_AttributeProcessorStack);
152
153     for (auto&& i : m_IR.Blocks[blockRef.ID].Events)
154     {
155         i.apply_visitor(*this);
156     }
157 }
158
159 void IRCompiler::operator()(IR::Event& ev)
160 {
161     std::for_each(
162         m_AttributeProcessorStack.rbegin(),
163         m_AttributeProcessorStack.rend(),
164         [&ev] (auto&& x)
165         {
166             for (auto&& i : x)
167             {
168                 i->TransformEvent(ev);
169             }
170         }
171     );
172 }
173
174 void IRCompiler::operator()(IR::BlockReference& blockRef)
175 {
176     // 'blockRef' here should be referenced by a single block, thus no need to duplicate it.
177     // blockRef = DuplicateBlock(blockRef);
178     CompileBlock(blockRef);
179 }
180
181 } // namespace IRProcessor
182
183 } // namespace YAMML