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