5#include <unordered_map>
38 std::unordered_map<std::string, Value>
fields;
43 using DataType = std::variant<std::monostate, bool, int64_t, double, std::string,
44 std::shared_ptr<StructInstance>, std::shared_ptr<ArrayInstance>>;
78 Value(std::shared_ptr<StructInstance> s) :
data(std::move(s))
82 Value(std::shared_ptr<ArrayInstance> a) :
data(std::move(a))
89 if (std::holds_alternative<std::monostate>(
data))
91 if (std::holds_alternative<bool>(
data))
93 if (std::holds_alternative<int64_t>(
data))
95 if (std::holds_alternative<double>(
data))
97 if (std::holds_alternative<std::string>(
data))
99 if (std::holds_alternative<std::shared_ptr<StructInstance>>(
data))
101 if (std::holds_alternative<std::shared_ptr<ArrayInstance>>(
data))
139 return std::holds_alternative<std::shared_ptr<ArrayInstance>>(
data);
145 return std::get<bool>(
data);
151 return std::get<int64_t>(
data);
153 return static_cast<int64_t
>(std::get<double>(
data));
160 return std::get<double>(
data);
162 return static_cast<double>(std::get<int64_t>(
data));
169 return std::get<std::string>(
data);
175 return std::get<std::shared_ptr<ArrayInstance>>(
data);
179 const std::shared_ptr<const ArrayInstance>
asArray()
const
181 return std::get<std::shared_ptr<ArrayInstance>>(
data);
193 throw std::runtime_error(
"Cannot add these value types");
203 throw std::runtime_error(
"Cannot subtract these value types");
213 throw std::runtime_error(
"Cannot multiply these value types");
221 if (other.
asInt() == 0)
222 throw std::runtime_error(
"Division by zero");
228 throw std::runtime_error(
"Division by zero");
231 throw std::runtime_error(
"Cannot divide these value types");
239 if (other.
asInt() == 0)
240 throw std::runtime_error(
"Modulo by zero");
243 throw std::runtime_error(
"Modulo requires integer operands");
253 throw std::runtime_error(
"Cannot negate this value type");
312 if (!other.
isArray())
return false;
313 const auto &self_arr = *
asArray();
314 const auto &other_arr = *other.
asArray();
315 return self_arr == other_arr;
323 return !(*
this == other);
335 throw std::runtime_error(
"Cannot compare these value types ");
347 throw std::runtime_error(
"Cannot compare these value types ");
353 return !(*
this > other);
358 return !(*
this < other);
367 return asBool() ?
"true" :
"false";
369 return std::to_string(
asInt());
371 return std::to_string(
asFloat());
376 std::string result =
"[";
378 for (
size_t i = 0; i < arr.size(); ++i)
380 result += arr[i].toString();
381 if (i < arr.size() - 1)
396 throw std::runtime_error(
"c_str() can only be called on string values");
397 return std::get<std::string>(
data).c_str();
409 return std::holds_alternative<std::shared_ptr<StructInstance>>(
data);
414 return std::get<std::shared_ptr<StructInstance>>(
data);
417 const std::shared_ptr<const StructInstance>
asStruct()
const
419 return std::get<std::shared_ptr<StructInstance>>(
data);
429 return Value(std::make_shared<ArrayInstance>(std::move(elements)));
434 if (!std::holds_alternative<std::shared_ptr<StructInstance>>(
data))
435 throw std::runtime_error(
"getField() called on non-struct value");
436 auto s = std::get<std::shared_ptr<StructInstance>>(
data);
437 auto it = s->fields.find(name);
438 if (it == s->fields.end())
445 if (!std::holds_alternative<std::shared_ptr<StructInstance>>(
data))
446 throw std::runtime_error(
"setField() called on non-struct value");
447 auto s = std::get<std::shared_ptr<StructInstance>>(
data);
448 s->fields[name] = std::move(value);
453 if (!std::holds_alternative<std::shared_ptr<StructInstance>>(
data))
455 auto s = std::get<std::shared_ptr<StructInstance>>(
data);
456 return s->fields.find(name) != s->fields.end();
bool isTruthy() const
Helper to determine truthiness.
const char * c_str() const
Convert to C Style String.
std::shared_ptr< StructInstance > asStruct()
std::string toString() const
Convert to string for printing.
const std::shared_ptr< const StructInstance > asStruct() const
Value operator-() const
Unary negation.
double asFloat() const
Get the value as a double.
Value(std::shared_ptr< StructInstance > s)
Struct constructor.
Value(int i)
Integer constructor.
bool isNumber() const
Check if the value is a number.
std::string asString() const
Get the value as a string.
friend std::ostream & operator<<(std::ostream &os, const Value &v)
Print to output stream.
std::shared_ptr< ArrayInstance > asArray()
Get the value as an array.
Value operator/(const Value &other) const
Divide two values.
bool operator>=(const Value &other) const
Greater than or equal to comparison.
Value operator-(const Value &other) const
Subtract two values.
std::vector< Value > ArrayInstance
bool hasField(const std::string &name) const
Value(int64_t i)
Integer constructor.
void setField(const std::string &name, Value value)
bool operator<=(const Value &other) const
Less than or equal to comparison.
bool isNull() const
Check if the value is null.
int64_t asInt() const
Get the value as an integer.
bool isBool() const
Check if the value is a boolean.
Value(bool b)
Boolean constructor.
bool isFloat() const
Check if the value is a double.
static Value createStruct(const std::string &name)
bool isArray() const
Check if the value is an array.
ValueType getType() const
Get the type of the value.
const std::shared_ptr< const ArrayInstance > asArray() const
Get the value as an array (const).
Value logicalAnd(const Value &other) const
Logical AND.
bool asBool() const
Get the value as a boolean.
Value(const std::string &s)
String constructor.
bool operator<(const Value &other) const
Less than comparison.
Value operator*(const Value &other) const
Multiply two values.
bool operator>(const Value &other) const
Greater than comparison.
Value operator!() const
Logical negation.
Value(double d)
Double constructor.
bool operator==(const Value &other) const
Comparison operations.
bool operator!=(const Value &other) const
Inequality comparison.
Value operator%(const Value &other) const
Modulo two values.
std::variant< std::monostate, bool, int64_t, double, std::string, std::shared_ptr< StructInstance >, std::shared_ptr< ArrayInstance > > DataType
static Value createArray(std::vector< Value > elements={})
Value(std::shared_ptr< ArrayInstance > a)
Array constructor.
Value operator+(const Value &other) const
Add two values.
Value()
Default constructor.
Value getField(const std::string &name) const
bool isString() const
Check if the value is a string.
Value(const char *s)
String constructor.
Value logicalOr(const Value &other) const
Logical OR.
bool isInt() const
Check if the value is an integer.
The Phasor Programming Language and Runtime.
ValueType
Runtime value types for the VM.
std::unordered_map< std::string, Value > fields