131
132
133
134
135
136
137
138
139
140
|
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
return nullptr;
}
private:
llvm::SmallVector< T, 16 > m_storage;
unordered_map< uint32_t, T > m_uidStorage;
};
// We need to lower types before consuming them from the CIR. Ideally we'd do this while building the CIR
// but as things are now it would involve enormous refactoring to store lowered types in a bunch of high level
// objects, and all the code to round trip them to EIR would have to deal with them, while also making sure
// they aren't actually participating in pattern matching.
// A significant redesign will probably allow for an elegant solution, but that's for the rewrite.
// In the mean time we use this ugly helper that lowers the type when reading it from the CIR, if not previously done.
// Since it needs the context we have to store the current context as a static member. This will have to do for
// the BS compiler...
class LowerableType
{
public:
template< typename T >
LowerableType( T&& type ) :
m_type( forward< T >( type ) )
{}
const auto& type() const { return m_type; }
const eir::Term& get() const;
auto operator<( const LowerableType& other ) const
{
return m_type < other.m_type;
}
auto operator==( const LowerableType& other ) const
{
return m_type == other.m_type;
}
private:
eir::Term m_type;
mutable optional< eir::Term > m_loweredType;
};
// Same as above for values
class LowerableValue
{
public:
template< typename T >
LowerableValue( T&& val ) :
m_val( forward< T >( val ) )
{}
const auto& val() const { return m_val; }
const eir::Value& get() const;
eir::Value& modify();
auto operator<( const LowerableValue& other ) const
{
return m_val < other.m_val;
}
auto operator==( const LowerableValue& other ) const
{
return m_val == other.m_val;
}
private:
eir::Value m_val;
mutable optional< eir::Value > m_loweredVal;
};
}
#endif
|