1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/cmsxi/Value.hpp>
  7 #include <cmajor/cmsxi/Context.hpp>
  8 #include <soulng/util/TextUtils.hpp>
  9 
 10 namespace cmsxi {
 11 
 12 Value::Value()
 13 {
 14 }
 15 
 16 Value::~Value()
 17 {
 18 }
 19 
 20 void Value::AddDependencies(GlobalVariable* variableconst std::std::unordered_map<std::stringGlobalVariable*>&nameMapstd::std::unordered_map<GlobalVariable*
 21     std::std::set<GlobalVariable*>>&dependenciesContext&context)
 22 {
 23 }
 24 
 25 BoolValue::BoolValue() : ConstantValue()value(false)
 26 {
 27 }
 28 
 29 BoolValue::BoolValue(bool value_) : ConstantValue()value(value_)
 30 {
 31 }
 32 
 33 Type* BoolValue::GetType(Context& context)
 34 {
 35     return context.GetBoolType();
 36 }
 37 
 38 std::string BoolValue::Name(Context& context)
 39 {
 40     return value ? "true" : "false";
 41 }
 42 
 43 SByteValue::SByteValue() : ConstantValue()value(0)
 44 {
 45 }
 46 
 47 SByteValue::SByteValue(int8_t value_) : ConstantValue()value(value_)
 48 {
 49 }
 50 
 51 Type* SByteValue::GetType(Context& context)
 52 {
 53     return context.GetSByteType();
 54 }
 55 
 56 std::string SByteValue::Name(Context& context)
 57 {
 58     return std::to_string(value);
 59 }
 60 
 61 ByteValue::ByteValue() : ConstantValue()value(0)
 62 {
 63 }
 64 
 65 ByteValue::ByteValue(uint8_t value_) : ConstantValue()value(value_)
 66 {
 67 }
 68 
 69 Type* ByteValue::GetType(Context& context)
 70 {
 71     return context.GetByteType();
 72 }
 73 
 74 std::string ByteValue::Name(Context& context)
 75 {
 76     return std::to_string(value);
 77 }
 78 
 79 ShortValue::ShortValue() : ConstantValue()value(0)
 80 {
 81 }
 82 
 83 ShortValue::ShortValue(int16_t value_) : ConstantValue()value(value_)
 84 {
 85 }
 86 
 87 Type* ShortValue::GetType(Context& context)
 88 {
 89     return context.GetShortType();
 90 }
 91 
 92 std::string ShortValue::Name(Context& context)
 93 {
 94     return std::to_string(value);
 95 }
 96 
 97 UShortValue::UShortValue() : ConstantValue()value(0)
 98 {
 99 }
100 
101 UShortValue::UShortValue(uint16_t value_) : ConstantValue()value(value_)
102 {
103 }
104 
105 Type* UShortValue::GetType(Context& context)
106 {
107     return context.GetUShortType();
108 }
109 
110 std::string UShortValue::Name(Context& context)
111 {
112     return std::to_string(value);
113 }
114 
115 IntValue::IntValue() : ConstantValue()value(0)
116 {
117 }
118 
119 IntValue::IntValue(int32_t value_) : ConstantValue()value(value_)
120 {
121 }
122 
123 Type* IntValue::GetType(Context& context)
124 {
125     return context.GetIntType();
126 }
127 
128 std::string IntValue::Name(Context& context)
129 {
130     return std::to_string(value);
131 }
132 
133 UIntValue::UIntValue() : ConstantValue()value(0)
134 {
135 }
136 
137 UIntValue::UIntValue(uint32_t value_) : ConstantValue()value(value_)
138 {
139 }
140 
141 Type* UIntValue::GetType(Context& context)
142 {
143     return context.GetUIntType();
144 }
145 
146 std::string UIntValue::Name(Context& context)
147 {
148     return std::to_string(value);
149 }
150 
151 LongValue::LongValue() : ConstantValue()value(0)
152 {
153 }
154 
155 LongValue::LongValue(int64_t value_) : ConstantValue()value(value_)
156 {
157 }
158 
159 Type* LongValue::GetType(Context& context)
160 {
161     return context.GetLongType();
162 }
163 
164 std::string LongValue::Name(Context& context)
165 {
166     return std::to_string(value);
167 }
168 
169 ULongValue::ULongValue() : ConstantValue()value(0)
170 {
171 }
172 
173 ULongValue::ULongValue(uint64_t value_) : ConstantValue()value(value_)
174 {
175 }
176 
177 Type* ULongValue::GetType(Context& context)
178 {
179     return context.GetULongType();
180 }
181 
182 std::string ULongValue::Name(Context& context)
183 {
184     return std::to_string(value);
185 }
186 
187 FloatValue::FloatValue() : ConstantValue()value(0.0)
188 {
189 }
190 
191 FloatValue::FloatValue(float value_) : ConstantValue()value(value_)
192 {
193 }
194 
195 Type* FloatValue::GetType(Context& context)
196 {
197     return context.GetFloatType();
198 }
199 
200 std::string FloatValue::Name(Context& context)
201 {
202     return std::to_string(value);
203 }
204 
205 DoubleValue::DoubleValue() : ConstantValue()value(0.0)
206 {
207 }
208 
209 DoubleValue::DoubleValue(double value_) : value(value_)
210 {
211 }
212 
213 Type* DoubleValue::GetType(Context& context)
214 {
215     return context.GetDoubleType();
216 }
217 
218 std::string DoubleValue::Name(Context& context)
219 {
220     return std::to_string(value);
221 }
222 
223 NullValue::NullValue(PtrType* ptrType_) : ConstantValue()ptrType(ptrType_)
224 {
225 }
226 
227 Type* NullValue::GetType(Context& context)
228 {
229     return ptrType;
230 }
231 
232 std::string NullValue::Name(Context& context)
233 {
234     return "null";
235 }
236 
237 ArrayValue::ArrayValue(Type* type_const std::std::vector<ConstantValue*>&elements_conststd::string&prefix_):ConstantValue()type(type_)elements(elements_)prefix(prefix_)
238 {
239 }
240 
241 std::string ArrayValue::Name(Context& context)
242 {
243     std::string name = prefix + "[ ";
244     bool first = true;
245     for (ConstantValue* element : elements)
246     {
247         if (first)
248         {
249             first = false;
250         }
251         else
252         {
253             name.append(", ");
254         }
255         if (element->IsAggregateValue())
256         {
257             name.append(element->Name(context));
258         }
259         else
260         {
261             name.append(element->GetType(context)->Name()).append(" ").append(element->Name(context));
262         }
263     }
264     name.append(" ]");
265     return name;
266 }
267 
268 void ArrayValue::AddDependencies(GlobalVariable* variableconst std::std::unordered_map<std::stringGlobalVariable*>&nameMap
269     std::std::unordered_map<GlobalVariable*std::std::set<GlobalVariable*>>&dependenciesContext&context)
270 {
271     for (Value* element : elements)
272     {
273         if (element)
274         {
275             auto it = nameMap.find(element->Name(context));
276             if (it != nameMap.cend())
277             {
278                 dependencies[variable].insert(it->second);
279             }
280             element->AddDependencies(variablenameMapdependenciescontext);
281         }
282     }
283 }
284 
285 void ArrayValue::AddElement(ConstantValue* element)
286 {
287     elements.push_back(element);
288 }
289 
290 StructureValue::StructureValue(Type* type_const std::std::vector<ConstantValue*>&members_):ConstantValue()type(type_)members(members_)
291 {
292 }
293 
294 Type* StructureValue::GetType(Context& context)
295 {
296     return type;
297 }
298 
299 std::string StructureValue::Name(Context& context)
300 {
301     std::string name = "{ ";
302     bool first = true;
303     for (ConstantValue* member : members)
304     {
305         if (first)
306         {
307             first = false;
308         }
309         else
310         {
311             name.append(", ");
312         }
313         if (member->IsAggregateValue())
314         {
315             name.append(member->Name(context));
316         }
317         else
318         {
319             name.append(member->GetType(context)->Name()).append(" ").append(member->Name(context));
320         }
321     }
322     name.append(" }");
323     return name;
324 }
325 
326 void StructureValue::AddMember(ConstantValue* member)
327 {
328     members.push_back(member);
329 }
330 
331 void StructureValue::AddDependencies(GlobalVariable* variableconst std::std::unordered_map<std::stringGlobalVariable*>&nameMap
332     std::std::unordered_map<GlobalVariable*std::std::set<GlobalVariable*>>&dependenciesContext&context)
333 {
334     for (Value* member : members)
335     {
336         auto it = nameMap.find(member->Name(context));
337         if (it != nameMap.cend())
338         {
339             dependencies[variable].insert(it->second);
340         }
341         member->AddDependencies(variablenameMapdependenciescontext);
342     }
343 }
344 
345 StringValue::StringValue(Type* type_const std::string& value_) : ConstantValue()type(type_)value(value_)
346 {
347 }
348 
349 std::string StringValue::Name(Context& context)
350 {
351     std::string name("\"");
352     for (char c : value)
353     {
354         if (c == '"')
355         {
356             name.append("\\").append(soulng::util::ToHexString(static_cast<uint8_t>(c)));
357         }
358         else if (c == '\\')
359         {
360             name.append("\\").append(soulng::util::ToHexString(static_cast<uint8_t>(c)));
361         }
362         else if (c >= 32 && c < 127)
363         {
364             name.append(1c);
365         }
366         else
367         {
368             name.append("\\").append(soulng::util::ToHexString(static_cast<uint8_t>(c)));
369         }
370     }
371     name.append("\\").append(soulng::util::ToHexString(static_cast<uint8_t>(0)));
372     name.append("\"");
373     return name;
374 }
375 
376 Type* StringValue::GetType(Context& context)
377 {
378     return type;
379 }
380 
381 ConversionValue::ConversionValue(Type* type_ConstantValue* from_) : ConstantValue()type(type_)from(from_)
382 {
383 }
384 
385 std::string ConversionValue::Name(Context& context)
386 {
387     std::string name = "conv(";
388     name.append(from->GetType(context)->Name()).append(1' ').append(from->Name(context)).append(1')');
389     return name;
390 }
391 
392 Type* ConversionValue::GetType(Context& context)
393 {
394     return type;
395 }
396 
397 void ConversionValue::AddDependencies(GlobalVariable* variableconst std::std::unordered_map<std::stringGlobalVariable*>&nameMapstd::std::unordered_map<GlobalVariable*std::std::set<GlobalVariable*>>&dependencies
398     Context& context)
399 {
400     auto it = nameMap.find(from->Name(context));
401     if (it != nameMap.cend())
402     {
403         dependencies[variable].insert(it->second);
404     }
405 }
406 
407 ClsIdValue::ClsIdValue(const std::string& typeId_) : ConstantValue()typeId(typeId_)
408 {
409 }
410 
411 std::string ClsIdValue::Name(Context& context)
412 {
413     std::string name = "clsid(" + typeId + ")";
414     return name;
415 }
416 
417 Type* ClsIdValue::GetType(Context& context)
418 {
419     return context.GetPtrType(context.GetVoidType());
420 }
421 
422 } // namespace cmsxi