ArkScript
A small, fast, functional and scripting language for video games
Value.cpp
Go to the documentation of this file.
1 #include <Ark/VM/Value.hpp>
2 
3 #include <Ark/Utils.hpp>
4 
5 #define init_const_type(is_const, type) ((is_const ? (1 << 7) : 0) | static_cast<uint8_t>(type))
6 
7 namespace Ark
8 {
9  Value::Value() noexcept :
10  m_const_type(init_const_type(false, ValueType::Undefined))
11  {}
12 
13  // --------------------------
14 
15  Value::Value(ValueType type) noexcept :
16  m_const_type(init_const_type(false, type))
17  {
18  if (type == ValueType::List)
19  m_value = std::vector<Value>();
20  else if (type == ValueType::String)
21  m_value = "";
22 
23 #ifdef ARK_PROFILER_COUNT
24  value_creations++;
25 #endif
26  }
27 
28 #ifdef ARK_PROFILER_COUNT
29  extern unsigned value_creations = 0;
30  extern unsigned value_copies = 0;
31  extern unsigned value_moves = 0;
32 
33  Value::Value(const Value& val) noexcept :
34  m_value(val.m_value),
35  m_const_type(val.m_const_type)
36  {
37  if (valueType() != ValueType::Reference)
38  value_copies++;
39  }
40 
41  Value::Value(Value&& other) noexcept
42  {
43  m_value = std::move(other.m_value);
44  m_const_type = std::move(other.m_const_type);
45 
46  if (valueType() != ValueType::Reference)
47  value_moves++;
48  }
49 
50  Value& Value::operator=(const Value& other) noexcept
51  {
52  m_value = other.m_value;
53  m_const_type = other.m_const_type;
54 
55  if (valueType() != ValueType::Reference)
56  value_copies++;
57 
58  return *this;
59  }
60 #endif
61 
62  Value::Value(int value) noexcept :
63  m_const_type(init_const_type(false, ValueType::Number)), m_value(static_cast<double>(value))
64  {}
65 
66  Value::Value(float value) noexcept :
67  m_const_type(init_const_type(false, ValueType::Number)), m_value(static_cast<double>(value))
68  {}
69 
70  Value::Value(double value) noexcept :
71  m_const_type(init_const_type(false, ValueType::Number)), m_value(value)
72  {}
73 
74  Value::Value(const std::string& value) noexcept :
75  m_const_type(init_const_type(false, ValueType::String)), m_value(value.c_str())
76  {}
77 
78  Value::Value(const String& value) noexcept :
79  m_const_type(init_const_type(false, ValueType::String)), m_value(value)
80  {}
81 
82  Value::Value(const char* value) noexcept :
83  m_const_type(init_const_type(false, ValueType::String)), m_value(value)
84  {}
85 
87  m_const_type(init_const_type(false, ValueType::PageAddr)), m_value(value)
88  {}
89 
90  Value::Value(Value::ProcType value) noexcept :
91  m_const_type(init_const_type(false, ValueType::CProc)), m_value(value)
92  {}
93 
94  Value::Value(std::vector<Value>&& value) noexcept :
95  m_const_type(init_const_type(false, ValueType::List)), m_value(std::move(value))
96  {}
97 
98  Value::Value(internal::Closure&& value) noexcept :
99  m_const_type(init_const_type(false, ValueType::Closure)), m_value(std::move(value))
100  {}
101 
102  Value::Value(UserType&& value) noexcept :
103  m_const_type(init_const_type(false, ValueType::User)), m_value(std::move(value))
104  {}
105 
106  Value::Value(Value* ref) noexcept :
107  m_const_type(init_const_type(true, ValueType::Reference)), m_value(ref)
108  {}
109 
110  // --------------------------
111 
112  std::vector<Value>& Value::list()
113  {
114  return std::get<std::vector<Value>>(m_value);
115  }
116 
118  {
119  return std::get<internal::Closure>(m_value);
120  }
121 
123  {
124  return std::get<String>(m_value);
125  }
126 
128  {
129  return std::get<UserType>(m_value);
130  }
131 
133  {
134  return std::get<Value*>(m_value);
135  }
136 
137  // --------------------------
138 
139  void Value::push_back(const Value& value)
140  {
141  list().push_back(value);
142  }
143 
144  void Value::push_back(Value&& value)
145  {
146  list().push_back(std::move(value));
147  }
148 
149 
150  void Value::toString(std::ostream& os, VM& vm) const noexcept
151  {
152  switch (valueType())
153  {
154  case ValueType::Number:
155  {
156  double d = number();
157  os.precision(Utils::digPlaces(d) + Utils::decPlaces(d));
158  os << d;
159  break;
160  }
161 
162  case ValueType::String:
163  os << string().c_str();
164  break;
165 
166  case ValueType::PageAddr:
167  os << "Function @ " << pageAddr();
168  break;
169 
170  case ValueType::CProc:
171  os << "CProcedure";
172  break;
173 
174  case ValueType::List:
175  {
176  os << "[";
177  for (auto it = constList().begin(), it_end = constList().end(); it != it_end; ++it)
178  {
179  if (it->valueType() == ValueType::String)
180  {
181  os << "\"";
182  it->toString(os, vm);
183  os << "\"";
184  }
185  else
186  it->toString(os, vm);
187  if (it + 1 != it_end)
188  os << " ";
189  }
190  os << "]";
191  break;
192  }
193 
194  case ValueType::Closure:
195  closure().toString(os, vm);
196  break;
197 
198  case ValueType::User:
199  os << usertype();
200  break;
201 
202  case ValueType::Nil:
203  os << "nil";
204  break;
205 
206  case ValueType::True:
207  os << "true";
208  break;
209 
210  case ValueType::False:
211  os << "false";
212  break;
213 
215  os << "undefined";
216  break;
217 
219  reference()->toString(os, vm);
220  break;
221 
222  case ValueType::InstPtr:
223  os << "Instruction @ " << pageAddr();
224  break;
225 
226  default:
227  os << "~\\._./~";
228  break;
229  }
230  }
231 }
Lots of utilities about string, filesystem and more.
#define init_const_type(is_const, type)
Definition: Value.cpp:5
A class to be use C++ objects in ArkScript.
Definition: UserType.hpp:50
The ArkScript virtual machine, executing ArkScript bytecode.
Definition: VM.hpp:47
std::vector< Value > & list()
Return the stored list as a reference.
Definition: Value.cpp:112
internal::Closure & refClosure()
Return a reference to the closure held by the value.
Definition: Value.cpp:117
Value * reference() const
Return the stored internal object reference.
Definition: Value.cpp:132
Value(*)(std::vector< Value > &, VM *) ProcType
Definition: Value.hpp:74
Value() noexcept
Construct a new Value object.
Definition: Value.cpp:9
void push_back(const Value &value)
Add an element to the list held by the value (if the value type is set to list)
Definition: Value.cpp:139
String & stringRef()
Return the stored string as a reference.
Definition: Value.cpp:122
Value_t m_value
Definition: Value.hpp:303
void toString(std::ostream &os, VM &vm) const noexcept
Definition: Value.cpp:150
UserType & usertypeRef()
Return the stored user type as a reference.
Definition: Value.cpp:127
Closure management.
Definition: Closure.hpp:45
int decPlaces(double d)
Count the number of decimals for a double.
Definition: Utils.cpp:5
int digPlaces(double d)
Count the number of digits for a double.
Definition: Utils.cpp:21
uint16_t PageAddr_t
Definition: Closure.hpp:38
Definition: Builtins.hpp:21
ValueType
Definition: Value.hpp:40