ArkScript
A small, fast, functional and scripting language for video games
Value.hpp
Go to the documentation of this file.
1 /**
2  * @file Value.hpp
3  * @author Default value type handled by the virtual machine
4  * @brief
5  * @version 0.3
6  * @date 2020-10-27
7  *
8  * @copyright Copyright (c) 2020-2021
9  *
10  */
11 
12 #ifndef ARK_VM_VALUE_HPP
13 #define ARK_VM_VALUE_HPP
14 
15 #include <vector>
16 #include <variant>
17 #include <string> // for conversions
18 #include <cinttypes>
19 #include <iostream>
20 #include <memory>
21 #include <functional>
22 #include <utility>
23 #include <Ark/String.hpp> // our string implementation
24 #include <array>
25 
26 #include <Ark/VM/Value/Closure.hpp>
28 #include <Ark/Platform.hpp>
29 #include <Ark/Profiling.hpp>
30 
31 namespace Ark
32 {
33  class VM;
34 
35  // Note from the creator: we can have at most 0b01111111 (127) different types
36  // because type index is stored on the 7 right most bits of a uint8_t in the class Value.
37  // Order is also important because we are doing some optimizations to check ranges
38  // of types based on their integer values.
39  enum class ValueType
40  {
41  List = 0,
42  Number = 1,
43  String = 2,
44  PageAddr = 3,
45  CProc = 4,
46  Closure = 5,
47  User = 6,
48 
49  Nil = 7,
50  True = 8,
51  False = 9,
52  Undefined = 10,
53  Reference = 11,
54  InstPtr = 12,
55 
56  Any = 99
57  };
58 
59  const std::array<std::string, 13> types_to_str = {
60  "List", "Number", "String", "Function",
61  "CProc", "Closure", "UserType", "Nil",
62  "Bool", "Bool", "Undefined", "Reference",
63  "InstPtr"
64  };
65 
66 // for debugging purposes only
67 #ifdef ARK_PROFILER_COUNT
68  extern unsigned value_creations, value_copies, value_moves;
69 #endif
70 
71  class ARK_API Value
72  {
73  public:
74  using ProcType = Value (*)(std::vector<Value>&, VM*); // std::function<Value (std::vector<Value>&, VM*)>
75  using Iterator = std::vector<Value>::iterator;
76  using ConstIterator = std::vector<Value>::const_iterator;
77 
78  using Value_t = std::variant<
79  double, // 8 bytes
80  String, // 16 bytes
81  internal::PageAddr_t, // 2 bytes
82  ProcType, // 8 bytes
83  internal::Closure, // 24 bytes
84  UserType, // 24 bytes
85  std::vector<Value>, // 24 bytes
86  Value* // 8 bytes
87  >; // +8 bytes overhead
88  // total 32 bytes
89 
90  /**
91  * @brief Construct a new Value object
92  *
93  */
94  Value() noexcept;
95 
96  /**
97  * @brief Construct a new Value object
98  *
99  * @param type the value type which is going to be held
100  */
101  explicit Value(ValueType type) noexcept;
102 
103  /**
104  * @brief Construct a new Value object
105  * @details Use at your own risks. Asking for a value type N and putting a non-matching value
106  * will result in errors at runtime.
107  *
108  * @tparam T
109  * @param type value type wanted
110  * @param value value needed
111  */
112  template <typename T>
113  Value(ValueType type, T&& value) noexcept :
114  m_const_type(static_cast<uint8_t>(type)),
115  m_value(std::move(value))
116  {}
117 
118 #ifdef ARK_PROFILER_COUNT
119  Value(const Value& val) noexcept;
120  Value(Value&& other) noexcept;
121  Value& operator=(const Value& other) noexcept;
122 #endif
123 
124  /**
125  * @brief Construct a new Value object as a Number
126  *
127  * @param value
128  */
129  explicit Value(int value) noexcept;
130 
131  /**
132  * @brief Construct a new Value object as a Number
133  *
134  * @param value
135  */
136  explicit Value(float value) noexcept;
137 
138  /**
139  * @brief Construct a new Value object as a Number
140  *
141  * @param value
142  */
143  explicit Value(double value) noexcept;
144 
145  /**
146  * @brief Construct a new Value object as a String
147  *
148  * @param value
149  */
150  explicit Value(const std::string& value) noexcept;
151 
152  /**
153  * @brief Construct a new Value object as a String
154  *
155  * @param value
156  */
157  explicit Value(const String& value) noexcept;
158 
159  /**
160  * @brief Construct a new Value object as a String
161  *
162  * @param value
163  */
164  explicit Value(const char* value) noexcept;
165 
166  /**
167  * @brief Construct a new Value object as a Function
168  *
169  * @param value
170  */
171  explicit Value(internal::PageAddr_t value) noexcept;
172 
173  /**
174  * @brief Construct a new Value object from a C++ function
175  *
176  * @param value
177  */
178  explicit Value(Value::ProcType value) noexcept;
179 
180  /**
181  * @brief Construct a new Value object as a List
182  *
183  * @param value
184  */
185  explicit Value(std::vector<Value>&& value) noexcept;
186 
187  /**
188  * @brief Construct a new Value object as a Closure
189  *
190  * @param value
191  */
192  explicit Value(internal::Closure&& value) noexcept;
193 
194  /**
195  * @brief Construct a new Value object as a UserType
196  *
197  * @param value
198  */
199  explicit Value(UserType&& value) noexcept;
200 
201  /**
202  * @brief Construct a new Value object as a reference to an internal object
203  *
204  * @param ref
205  */
206  explicit Value(Value* ref) noexcept;
207 
208  /**
209  * @brief Return the value type
210  *
211  * @return ValueType
212  */
213  inline ValueType valueType() const noexcept;
214 
215  /**
216  * @brief Check if a function is held
217  *
218  * @return true on success
219  * @return false on failure
220  */
221  inline bool isFunction() const noexcept;
222 
223  /**
224  * @brief Return the stored number
225  *
226  * @return double
227  */
228  inline double number() const;
229 
230  /**
231  * @brief Return the stored string
232  *
233  * @return const String&
234  */
235  inline const String& string() const;
236 
237  /**
238  * @brief Return the stored list
239  *
240  * @return const std::vector<Value>&
241  */
242  inline const std::vector<Value>& constList() const;
243 
244  /**
245  * @brief Return the stored user type
246  *
247  * @return const UserType&
248  */
249  inline const UserType& usertype() const;
250 
251  /**
252  * @brief Return the stored list as a reference
253  *
254  * @return std::vector<Value>&
255  */
256  std::vector<Value>& list();
257 
258  /**
259  * @brief Return the stored string as a reference
260  *
261  * @return String&
262  */
263  String& stringRef();
264 
265  /**
266  * @brief Return the stored user type as a reference
267  *
268  * @return UserType&
269  */
270  UserType& usertypeRef();
271 
272  /**
273  * @brief Return the stored internal object reference
274  *
275  * @return Value*
276  */
277  Value* reference() const;
278 
279  /**
280  * @brief Add an element to the list held by the value (if the value type is set to list)
281  *
282  * @param value
283  */
284  void push_back(const Value& value);
285 
286  /**
287  * @brief Add an element to the list held by the value (if the value type is set to list)
288  *
289  * @param value
290  */
291  void push_back(Value&& value);
292 
293  void toString(std::ostream& os, VM& vm) const noexcept;
294 
295  friend ARK_API_INLINE bool operator==(const Value& A, const Value& B) noexcept;
296  friend ARK_API_INLINE bool operator<(const Value& A, const Value& B) noexcept;
297  friend ARK_API_INLINE bool operator!(const Value& A) noexcept;
298 
299  friend class Ark::VM;
300 
301  private:
302  uint8_t m_const_type; ///< First bit if for constness, right most bits are for type
303  Value_t m_value;
304 
305  // private getters only for the virtual machine
306 
307  /**
308  * @brief Return the page address held by the value
309  *
310  * @return internal::PageAddr_t
311  */
312  inline internal::PageAddr_t pageAddr() const;
313 
314  /**
315  * @brief Return the C Function held by the value
316  *
317  * @return const ProcType&
318  */
319  inline const ProcType& proc() const;
320 
321  /**
322  * @brief Return the closure held by the value
323  *
324  * @return const internal::Closure&
325  */
326  inline const internal::Closure& closure() const;
327 
328  /**
329  * @brief Return a reference to the closure held by the value
330  *
331  * @return internal::Closure&
332  */
333  internal::Closure& refClosure();
334 
335  /**
336  * @brief Check if the value is const or not
337  *
338  * @return true
339  * @return false
340  */
341  inline bool isConst() const noexcept;
342 
343  /**
344  * @brief Set the Const object
345  *
346  * @param value
347  */
348  inline void setConst(bool value) noexcept;
349  };
350 
351 #include "inline/Value.inl"
352 }
353 
354 #endif
Subtype of the value type, handling closures.
ArkScript configuration macros.
#define ARK_API_INLINE
Definition: Platform.hpp:51
#define ARK_API
Definition: Platform.hpp:41
Subtype of the value, capable of handling any C++ type.
A class to be use C++ objects in ArkScript.
Definition: UserType.hpp:50
The ArkScript virtual machine, executing ArkScript bytecode.
Definition: VM.hpp:47
Value(*)(std::vector< Value > &, VM *) ProcType
Definition: Value.hpp:74
std::variant< double, String, internal::PageAddr_t, ProcType, internal::Closure, UserType, std::vector< Value >, Value * > Value_t
Definition: Value.hpp:87
std::vector< Value >::iterator Iterator
Definition: Value.hpp:75
ValueType valueType() const noexcept
Return the value type.
std::vector< Value >::const_iterator ConstIterator
Definition: Value.hpp:76
Closure management.
Definition: Closure.hpp:45
uint16_t PageAddr_t
Definition: Closure.hpp:38
Definition: Builtins.hpp:21
ValueType
Definition: Value.hpp:40
const std::array< std::string, 13 > types_to_str
Definition: Value.hpp:59