1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_SYMBOLS_VALUE_INCLUDED
  7 #define CMAJOR_SYMBOLS_VALUE_INCLUDED
  8 #include <cmajor/symbols/Symbol.hpp>
  9 #include <cmajor/ir/Emitter.hpp>
 10 
 11 namespace cmajor { namespace symbols {
 12 
 13 using soulng::lexer::Span;
 14 using namespace cmajor::ir;
 15 
 16 class TypeSymbol;
 17 
 18 enum class ValueType : uint8_t 
 19 {
 20     noneboolValuesbyteValuebyteValueshortValueushortValueintValueuintValue
 21     longValueulongValuefloatValuedoubleValuecharValuewcharValueucharValue
 22     stringValuewstringValueustringValuenullValuepointerValuearrayValuestructuredValue
 23     uuidValue
 24     maxValue
 25 };
 26 
 27 std::string ValueTypeStr(ValueType valueType);
 28 
 29 ValueType CommonType(ValueType leftValueType right);
 30 
 31 TypeSymbol* GetTypeFor(ValueType valueTypeSymbolTable* symbolTable);
 32 
 33 class Value 
 34 {
 35 public:
 36     Value(const Span& span_const boost::uuids::uuid& moduleId_ValueType valueType_);
 37     virtual ~Value();
 38     virtual Value* Clone() const = 0;
 39     virtual Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const = 0;
 40     virtual void* IrValue(Emitter& emitter) = 0;
 41     virtual void Write(BinaryWriter& writer) = 0;
 42     virtual void Read(BinaryReader& reader) = 0;
 43     virtual bool IsComplete() const { return true; }
 44     virtual bool IsScopedValue() const { return false; }
 45     virtual bool IsFunctionGroupValue() const { return false; }
 46     virtual bool IsArrayReferenceValue() const { return false; }
 47     virtual bool IsStructuredReferenceValue() const { return false; }
 48     virtual bool IsStringReferenceValue() const { return false; }
 49     virtual bool IsComplexValue() const { return false; }
 50     virtual Value* GetSubject() { return this; }
 51     virtual std::string ToString() const { return std::string(); }
 52     virtual TypeSymbol* GetType(SymbolTable* symbolTable) = 0;
 53     virtual void SetType(TypeSymbol* type_) {}
 54     const Span& GetSpan() const { return span; }
 55     const boost::uuids::uuid& ModuleId() const { return moduleId; }
 56     ValueType GetValueType() const { return valueType; }
 57     std::unique_ptr<sngxml::dom::Element> ToDomElement();
 58     virtual const char* ClassName() const { return "Value";  }
 59 private:
 60     Span span;
 61     boost::uuids::uuid moduleId;
 62     ValueType valueType;
 63 };
 64 
 65 class BoolValue public Value
 66 {
 67 public:
 68     typedef bool OperandType;
 69     BoolValue(const Span& span_const boost::uuids::uuid& moduleId_bool value_);
 70     Value* Clone() const override  { return new BoolValue(GetSpan()ModuleId()value); }
 71     void* IrValue(Emitter& emitter) override;
 72     void Write(BinaryWriter& writer) override;
 73     void Read(BinaryReader& reader) override;
 74     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
 75     std::string ToString() const override { return value ? "true" : "false"; }
 76     TypeSymbol* GetType(SymbolTable* symbolTable) override;
 77     bool GetValue() const { return value; }
 78     const char* ClassName() const override { return "BoolValue"; }
 79 private:
 80     bool value;
 81 };
 82 
 83 class SByteValue public Value
 84 {
 85 public:
 86     typedef int8_t OperandType;
 87     SByteValue(const Span& span_const boost::uuids::uuid& moduleId_int8_t value_);
 88     Value* Clone() const override  { return new SByteValue(GetSpan()ModuleId()value); }
 89     void* IrValue(Emitter& emitter) override;
 90     void Write(BinaryWriter& writer) override;
 91     void Read(BinaryReader& reader) override;
 92     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
 93     std::string ToString() const override { return std::to_string(value); }
 94     TypeSymbol* GetType(SymbolTable* symbolTable) override;
 95     int8_t GetValue() const { return value; }
 96     const char* ClassName() const override { return "SByteValue"; }
 97 private:
 98     int8_t value;
 99 };
100 
101 class ByteValue public Value
102 {
103 public:
104     typedef uint8_t OperandType;
105     ByteValue(const Span& span_const boost::uuids::uuid& moduleId_uint8_t value_);
106     Value* Clone() const override  { return new ByteValue(GetSpan()ModuleId()value); }
107     void* IrValue(Emitter& emitter) override;
108     void Write(BinaryWriter& writer) override;
109     void Read(BinaryReader& reader) override;
110     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
111     std::string ToString() const override { return std::to_string(value); }
112     TypeSymbol* GetType(SymbolTable* symbolTable) override;
113     uint8_t GetValue() const { return value; }
114     const char* ClassName() const override { return "ByteValue"; }
115 private:
116     uint8_t value;
117 };
118 
119 class ShortValue public Value
120 {
121 public:
122     typedef int16_t OperandType;
123     ShortValue(const Span& span_const boost::uuids::uuid& moduleId_int16_t value_);
124     Value* Clone() const override  { return new ShortValue(GetSpan()ModuleId()value); }
125     void* IrValue(Emitter& emitter) override;
126     void Write(BinaryWriter& writer) override;
127     void Read(BinaryReader& reader) override;
128     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
129     std::string ToString() const override { return std::to_string(value); }
130     TypeSymbol* GetType(SymbolTable* symbolTable) override;
131     int16_t GetValue() const { return value; }
132     const char* ClassName() const override { return "ShortValue"; }
133 private:
134     int16_t value;
135 };
136 
137 class UShortValue public Value
138 {
139 public:
140     typedef uint16_t OperandType;
141     UShortValue(const Span& span_const boost::uuids::uuid& moduleId_uint16_t value_);
142     Value* Clone() const override  { return new UShortValue(GetSpan()ModuleId()value); }
143     void* IrValue(Emitter& emitter) override;
144     void Write(BinaryWriter& writer) override;
145     void Read(BinaryReader& reader) override;
146     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
147     std::string ToString() const override { return std::to_string(value); }
148     TypeSymbol* GetType(SymbolTable* symbolTable) override;
149     uint16_t GetValue() const { return value; }
150     const char* ClassName() const override { return "UShortValue"; }
151 private:
152     uint16_t value;
153 };
154 
155 class IntValue public Value
156 {
157 public:
158     typedef int32_t OperandType;
159     IntValue(const Span& span_const boost::uuids::uuid& moduleId_int32_t value_);
160     Value* Clone() const override  { return new IntValue(GetSpan()ModuleId()value); }
161     void* IrValue(Emitter& emitter) override;
162     void Write(BinaryWriter& writer) override;
163     void Read(BinaryReader& reader) override;
164     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
165     std::string ToString() const override { return std::to_string(value); }
166     TypeSymbol* GetType(SymbolTable* symbolTable) override;
167     int32_t GetValue() const { return value; }
168     const char* ClassName() const override { return "IntValue"; }
169 private:
170     int32_t value;
171 };
172 
173 class UIntValue public Value
174 {
175 public:
176     typedef uint32_t OperandType;
177     UIntValue(const Span& span_const boost::uuids::uuid& moduleId_uint32_t value_);
178     Value* Clone() const override  { return new UIntValue(GetSpan()ModuleId()value); }
179     void* IrValue(Emitter& emitter) override;
180     void Write(BinaryWriter& writer) override;
181     void Read(BinaryReader& reader) override;
182     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
183     std::string ToString() const override { return std::to_string(value); }
184     TypeSymbol* GetType(SymbolTable* symbolTable) override;
185     uint32_t GetValue() const { return value; }
186     const char* ClassName() const override { return "UIntValue"; }
187 private:
188     uint32_t value;
189 };
190 
191 class LongValue public Value
192 {
193 public:
194     typedef int64_t OperandType;
195     LongValue(const Span& span_const boost::uuids::uuid& moduleId_int64_t value_);
196     Value* Clone() const override  { return new LongValue(GetSpan()ModuleId()value); }
197     void* IrValue(Emitter& emitter) override;
198     void Write(BinaryWriter& writer) override;
199     void Read(BinaryReader& reader) override;
200     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
201     std::string ToString() const override { return std::to_string(value); }
202     TypeSymbol* GetType(SymbolTable* symbolTable) override;
203     int64_t GetValue() const { return value; }
204     const char* ClassName() const override { return "LongValue"; }
205 private:
206     int64_t value;
207 };
208 
209 class ULongValue public Value
210 {
211 public:
212     typedef uint64_t OperandType;
213     ULongValue(const Span& span_const boost::uuids::uuid& moduleId_uint64_t value_);
214     Value* Clone() const override  { return new ULongValue(GetSpan()ModuleId()value); }
215     void* IrValue(Emitter& emitter) override;
216     void Write(BinaryWriter& writer) override;
217     void Read(BinaryReader& reader) override;
218     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
219     std::string ToString() const override { return std::to_string(value); }
220     TypeSymbol* GetType(SymbolTable* symbolTable) override;
221     uint64_t GetValue() const { return value; }
222     const char* ClassName() const override { return "ULongValue"; }
223 private:
224     uint64_t value;
225 };
226 
227 class FloatValue public Value
228 {
229 public:
230     typedef float OperandType;
231     FloatValue(const Span& span_const boost::uuids::uuid& moduleId_float value_);
232     Value* Clone() const override  { return new FloatValue(GetSpan()ModuleId()value); }
233     void* IrValue(Emitter& emitter) override;
234     void Write(BinaryWriter& writer) override;
235     void Read(BinaryReader& reader) override;
236     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
237     std::string ToString() const override { return std::to_string(value); }
238     TypeSymbol* GetType(SymbolTable* symbolTable) override;
239     float GetValue() const { return value; }
240     const char* ClassName() const override { return "FloatValue"; }
241 private:
242     float value;
243 };
244 
245 class DoubleValue public Value
246 {
247 public:
248     typedef double OperandType;
249     DoubleValue(const Span& span_const boost::uuids::uuid& moduleId_double value_);
250     Value* Clone() const override  { return new DoubleValue(GetSpan()ModuleId()value); }
251     void* IrValue(Emitter& emitter) override;
252     void Write(BinaryWriter& writer) override;
253     void Read(BinaryReader& reader) override;
254     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
255     std::string ToString() const override { return std::to_string(value); }
256     TypeSymbol* GetType(SymbolTable* symbolTable) override;
257     double GetValue() const { return value; }
258     const char* ClassName() const override { return "DoubleValue"; }
259 private:
260     double value;
261 };
262 
263 class CharValue public Value
264 {
265 public:
266     typedef unsigned char OperandType;
267     CharValue(const Span& span_const boost::uuids::uuid& moduleId_unsigned char value_);
268     Value* Clone() const override  { return new CharValue(GetSpan()ModuleId()value); }
269     void* IrValue(Emitter& emitter) override;
270     void Write(BinaryWriter& writer) override;
271     void Read(BinaryReader& reader) override;
272     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
273     std::string ToString() const override { return std::to_string(value); }
274     TypeSymbol* GetType(SymbolTable* symbolTable) override;
275     unsigned char GetValue() const { return value; }
276     const char* ClassName() const override { return "CharValue"; }
277 private:
278     unsigned char value;
279 };
280 
281 class WCharValue public Value
282 {
283 public:
284     typedef char16_t OperandType;
285     WCharValue(const Span& span_const boost::uuids::uuid& moduleId_char16_t value_);
286     Value* Clone() const override  { return new WCharValue(GetSpan()ModuleId()value); }
287     void* IrValue(Emitter& emitter) override;
288     void Write(BinaryWriter& writer) override;
289     void Read(BinaryReader& reader) override;
290     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
291     std::string ToString() const override { return std::to_string(value); }
292     TypeSymbol* GetType(SymbolTable* symbolTable) override;
293     char16_t GetValue() const { return value; }
294     const char* ClassName() const override { return "WCharValue"; }
295 private:
296     char16_t value;
297 };
298 
299 class UCharValue public Value
300 {
301 public:
302     typedef char32_t OperandType;
303     UCharValue(const Span& span_const boost::uuids::uuid& moduleId_char32_t value_);
304     Value* Clone() const override  { return new UCharValue(GetSpan()ModuleId()value); }
305     void* IrValue(Emitter& emitter) override;
306     void Write(BinaryWriter& writer) override;
307     void Read(BinaryReader& reader) override;
308     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
309     std::string ToString() const override { return std::to_string(value); }
310     TypeSymbol* GetType(SymbolTable* symbolTable) override;
311     char32_t GetValue() const { return value; }
312     const char* ClassName() const override { return "UCharValue"; }
313 private:
314     char32_t value;
315 };
316 
317 class StringValue public Value
318 {
319 public:
320     StringValue(const Span& span_const boost::uuids::uuid& moduleId_int stringId_const std::string& str_);
321     Value* Clone() const override  { return new StringValue(GetSpan()ModuleId()stringIdstr); }
322     void* IrValue(Emitter& emitter) override;
323     void Write(BinaryWriter& writer) override;
324     void Read(BinaryReader& reader) override;
325     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
326     TypeSymbol* GetType(SymbolTable* symbolTable) override;
327     int StringId() const { return stringId; }
328     const std::string& Str() const { return str; }
329     const char* ClassName() const override { return "StringValue"; }
330 private:
331     int stringId;
332     std::string str;
333 };
334 
335 class WStringValue public Value
336 {
337 public:
338     WStringValue(const Span& span_const boost::uuids::uuid& moduleId_int stringId_const std::u16string& str_);
339     Value* Clone() const override  { return new WStringValue(GetSpan()ModuleId()stringIdstr); }
340     void* IrValue(Emitter& emitter) override;
341     void Write(BinaryWriter& writer) override;
342     void Read(BinaryReader& reader) override;
343     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
344     TypeSymbol* GetType(SymbolTable* symbolTable) override;
345     int StringId() const { return stringId; }
346     const std::u16string& Str() const { return str; }
347     const char* ClassName() const override { return "WStringValue"; }
348 private:
349     int stringId;
350     std::u16string str;
351 };
352 
353 class UStringValue public Value
354 {
355 public:
356     UStringValue(const Span& span_const boost::uuids::uuid& moduleId_int stringId_const std::u32string& str_);
357     Value* Clone() const override  { return new UStringValue(GetSpan()ModuleId()stringIdstr); }
358     void* IrValue(Emitter& emitter) override;
359     void Write(BinaryWriter& writer) override;
360     void Read(BinaryReader& reader) override;
361     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
362     TypeSymbol* GetType(SymbolTable* symbolTable) override;
363     int StringId() const { return stringId; }
364     const std::u32string& Str() const { return str; }
365     const char* ClassName() const override { return "UStringValue"; }
366 private:
367     int stringId;
368     std::u32string str;
369 };
370 
371 class NullValue public Value
372 {
373 public:
374     NullValue(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* nullPtrType_);
375     Value* Clone() const override  { return new NullValue(GetSpan()ModuleId()nullPtrType); }
376     void* IrValue(Emitter& emitter) override;
377     void Write(BinaryWriter& writer) override;
378     void Read(BinaryReader& reader) override;
379     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
380     std::string ToString() const override { return "null"; }
381     TypeSymbol* GetType(SymbolTable* symbolTable) override;
382     const char* ClassName() const override { return "NullValue"; }
383 private:
384     TypeSymbol* nullPtrType;
385 };
386 
387 class PointerValue public Value
388 {
389 public:
390     typedef const void* OperandType;
391     PointerValue(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* typeconst void* ptr_);
392     Value* Clone() const override  { return new PointerValue(GetSpan()ModuleId()typeptr); }
393     void* IrValue(Emitter& emitter) override;
394     void Write(BinaryWriter& writer) override;
395     void Read(BinaryReader& reader) override;
396     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
397     TypeSymbol* GetType(SymbolTable* symbolTable) override;
398     void SetType(TypeSymbol* type_) override { type = type_; }
399     TypeSymbol* PointeeType() const;
400     const void* GetValue() const { return ptr; }
401     Value* Add(int64_t offset) const;
402     Value* Sub(int64_t offset) const;
403     Value* Sub(const void* thatPtr) const;
404     Value* Deref() const;
405     const char* ClassName() const override { return "PointerValue"; }
406 private:
407     TypeSymbol* type;
408     const void* ptr;
409 };
410 
411 class ArrayValue public Value
412 {
413 public:
414     ArrayValue(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* type_std::std::vector<std::std::unique_ptr<Value>>&&elementValues_);
415     ArrayValue(const ArrayValue&) = delete;
416     ArrayValue& operator=(const ArrayValue&) = delete;
417     Value* Clone() const override;
418     void* IrValue(Emitter& emitter) override;
419     void Write(BinaryWriter& writer) override;
420     void Read(BinaryReader& reader) override;
421     bool IsComplexValue() const override { return true; }
422     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
423     TypeSymbol* GetType(SymbolTable* symbolTable) override { return type; }
424     void SetType(TypeSymbol* type_) override { type = type_; }
425     const std::std::vector<std::std::unique_ptr<Value>>&Elements() const{returnelementValues;}
426     std::std::vector<std::std::unique_ptr<Value>>&Elements(){returnelementValues;}
427     const char* ClassName() const override { return "ArrayValue"; }
428 private:
429     std::vector<std::std::unique_ptr<Value>>elementValues;
430     TypeSymbol* type;
431 };
432 
433 class StructuredValue public Value
434 {
435 public:
436     StructuredValue(const Span& span_const boost::uuids::uuid& moduleId_TypeSymbol* type_std::std::vector<std::std::unique_ptr<Value>>&&memberValues_);
437     StructuredValue(const StructuredValue&) = delete;
438     StructuredValue& operator=(const StructuredValue&) = delete;
439     Value* Clone() const override;
440     void* IrValue(Emitter& emitter) override;
441     void Write(BinaryWriter& writer) override;
442     void Read(BinaryReader& reader) override;
443     bool IsComplexValue() const override { return true; }
444     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
445     void SetType(TypeSymbol* type_) override { type = type_; }
446     TypeSymbol* GetType(SymbolTable* symbolTable) override { return type; }
447     const std::std::vector<std::std::unique_ptr<Value>>&Members() const{returnmemberValues;}
448     std::std::vector<std::std::unique_ptr<Value>>&Members(){returnmemberValues;}
449     const char* ClassName() const override { return "StructuredValue"; }
450 private:
451     std::vector<std::std::unique_ptr<Value>>memberValues;
452     TypeSymbol* type;
453 };
454 
455 class UuidValue public Value
456 {
457 public:
458     UuidValue(const Span& span_const boost::uuids::uuid& moduleId_int uuidId_);
459     Value* Clone() const override { return new UuidValue(GetSpan()ModuleId()uuidId); }
460     void* IrValue(Emitter& emitter) override;
461     void Write(BinaryWriter& writer) override;
462     void Read(BinaryReader& reader) override;
463     Value* As(TypeSymbol* targetTypebool castconst Span& spanconst boost::uuids::uuid& moduleIdbool dontThrow) const override;
464     TypeSymbol* GetType(SymbolTable* symbolTable) override;
465     int UuidId() const { return uuidId; }
466     const char* ClassName() const override { return "UuidValue"; }
467 private:
468     int uuidId;
469 };
470 
471 
472 template<typename ValueT>
473 inline bool ValuesEqual(const ValueT& leftconst ValueT& right)
474 {
475     return left.GetValue() == right.GetValue();
476 }
477 
478 template<typename ValueT>
479 inline size_t GetHashCode(const ValueT& value)
480 {
481     return static_cast<size_t>(value.GetValue());
482 }
483 
484 struct IntegralValue 
485 {
486     IntegralValue(Value* value_) : value(value_) {}
487     Value* value;
488 };
489 
490 bool operator==(IntegralValue leftIntegralValue right);
491 
492 inline bool operator!=(IntegralValue leftIntegralValue right)
493 {
494     return !(left == right);
495 }
496 
497 struct IntegralValueHash 
498 {
499     size_t operator()(IntegralValue integralValue) const;
500 };
501 
502 void WriteValue(Value* valueBinaryWriter& writer);
503 std::unique_ptr<Value> ReadValue(BinaryReader& readerconst Span& spanconst boost::uuids::uuid& moduleId);
504 
505 } } // namespace cmajor::symbols
506 
507 #endif // CMAJOR_SYMBOLS_VALUE_INCLUDED