Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src / value.hpp
diff options
context:
space:
mode:
Commit72d9bbcc3154142af79fb686d9dc7e4d1fa1badb (patch)
Author
 dtrendafilov <trendafilov.dn@gmail.com>
2018-11-29 09:13:12 +0200
Committer
 GitHub <noreply@github.com>
2018-11-29 09:13:12 +0200
Files3cea4377cba9370f3f2248557f82831d617d89d1 /spasm/src/value.hpp
IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.tar
IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.tar.gz
IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.zip
Parentcdfd42d72030a031e5c5d810fcd53441902b5cff (diff)
Feature/strings (#75)
* The assembler supports string opcode * disabled the string test until implmented * strings can be printed
1 files changed, 78 insertions, 83 deletions
-rw-r--r--spasm/src/value.hpp161
diff --git a/spasm/src/value.hpp b/spasm/src/value.hpp
index 6569721..d86c0ef 100644
--- a/spasm/src/value.hpp
+++ b/spasm/src/value.hpp
@@ -1,81 +1,66 @@
#pragma once
#include <cassert>
+#include "string.hpp"
namespace Spasm
{
- enum class ValueType
- {
- Number,
- Null,
- Undefined,
- Boolean,
- String,
- Array,
- Object,
- Function,
- };
+enum class ValueType
+{
+ Number,
+ Null,
+ Undefined,
+ Boolean,
+ String,
+ Array,
+ Object,
+ Function,
+};
- static_assert(int(ValueType::Function) < 8, "Too many types");
+static_assert(int(ValueType::Function) < 8, "Too many types");
struct Value
{
- Value()
- {
- m_value.as_double = 0.0;
- }
-
- explicit Value(double v)
- {
- m_value.as_double = v;
- }
+ Value() { m_value.as_double = 0.0; }
- explicit Value(bool v)
- : Value(ValueType::Boolean, (size_t)v)
+ explicit Value(double v) { m_value.as_double = v; }
- {
- }
+ explicit Value(bool v) : Value(ValueType::Boolean, (size_t)v) {}
- Value(ValueType tag, size_t payload)
- {
- assert(tag != ValueType::Number && "Zero tag is plain double");
- assert(!(payload >> 48) && "Use only pointers to the heap.");
- m_value.as_pointer.pointer = payload;
- m_value.as_pointer.tag = size_t(tag);
- m_value.as_pointer.nan = 0x1fff;
- }
-
- Value(ValueType tag, void* pointer)
- : Value(tag, (size_t)pointer)
+ Value(ValueType tag, size_t payload)
{
+ assert(tag != ValueType::Number && "Zero tag is plain double");
+ assert(!(payload >> 48) && "Use only pointers to the heap.");
+ m_value.as_pointer.pointer = payload;
+ m_value.as_pointer.tag = size_t(tag);
+ m_value.as_pointer.nan = 0x1fff;
}
+ Value(ValueType tag, void* pointer) : Value(tag, (size_t)pointer) {}
+
struct NanPointer
{
- size_t pointer:48;
- size_t tag:3;
- size_t nan:13;
+ size_t pointer : 48;
+ size_t tag : 3;
+ size_t nan : 13;
};
struct CheckType
{
- size_t payload: 48;
- size_t check:16;
+ size_t payload : 48;
+ size_t check : 16;
};
union {
double as_double;
NanPointer as_pointer;
CheckType to_check;
- size_t as_int64;
+ size_t as_int64;
} m_value;
static_assert(sizeof(size_t) == 8, "unsupported arch");
static_assert(sizeof(double) == 8, "unsupported arch");
- bool is_double() const
- {
- return m_value.to_check.check <= 0xFFF8;
- }
+ bool is_double() const { return m_value.to_check.check <= 0xFFF8; }
double get_double() const
{
@@ -83,99 +68,109 @@ struct Value
return m_value.as_double;
}
- ValueType get_type() const {
- return is_double()? ValueType::Number : ValueType(m_value.as_pointer.tag);
+ ValueType get_type() const
+ {
+ return is_double() ? ValueType::Number
+ : ValueType(m_value.as_pointer.tag);
}
- void* get_pointer() const {
- return (void*)(size_t) m_value.as_pointer.pointer;
+ void* get_pointer() const
+ {
+ return (void*)(size_t)m_value.as_pointer.pointer;
}
- bool get_boolean() const {
- assert(get_type() == ValueType::Boolean);
- return m_value.as_pointer.pointer != 0;
- }
-
- explicit operator bool() const {
- // NaN will be true. Assume that is ok.
- return (get_type() != ValueType::Boolean && m_value.as_int64 != 0) || get_boolean();
- }
+ bool get_boolean() const
+ {
+ assert(get_type() == ValueType::Boolean);
+ return m_value.as_pointer.pointer != 0;
+ }
+ explicit operator bool() const
+ {
+ // NaN will be true. Assume that is ok.
+ return (get_type() != ValueType::Boolean && m_value.as_int64 != 0) ||
+ get_boolean();
+ }
};
inline std::istream& operator>>(std::istream& input, Value& value)
{
- return input >> value.m_value.as_double;
+ return input >> value.m_value.as_double;
}
inline std::ostream& operator<<(std::ostream& output, const Value& value)
{
- switch (value.get_type())
- {
- case ValueType::Number:
- return output << value.m_value.as_double;
- case ValueType::Boolean:
- return output << bool(value);
- default:
- break;
- }
- return output;
+ switch (value.get_type())
+ {
+ case ValueType::Number:
+ return output << value.m_value.as_double;
+ case ValueType::Boolean:
+ return output << bool(value);
+ case ValueType::String:
+ {
+ const auto s = static_cast<const SpasmImpl::SPStringValue*>(
+ value.get_pointer());
+ return output << s->GetValue();
+ }
+ default:
+ break;
+ }
+ return output;
}
inline Value operator+(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() + rhs.get_double());
+ return Value(lhs.get_double() + rhs.get_double());
}
inline Value operator-(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() - rhs.get_double());
+ return Value(lhs.get_double() - rhs.get_double());
}
inline Value operator*(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() * rhs.get_double());
+ return Value(lhs.get_double() * rhs.get_double());
}
inline Value operator/(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() / rhs.get_double());
+ return Value(lhs.get_double() / rhs.get_double());
}
inline Value operator%(const Value& lhs, const Value& rhs)
{
- return Value(double(int64_t(lhs.get_double()) % int64_t(rhs.get_double())));
+ return Value(double(int64_t(lhs.get_double()) % int64_t(rhs.get_double())));
}
-
inline Value operator<(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() < rhs.get_double());
+ return Value(lhs.get_double() < rhs.get_double());
}
inline Value operator>(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() > rhs.get_double());
+ return Value(lhs.get_double() > rhs.get_double());
}
inline Value operator<=(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() <= rhs.get_double());
+ return Value(lhs.get_double() <= rhs.get_double());
}
inline Value operator>=(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() >= rhs.get_double());
+ return Value(lhs.get_double() >= rhs.get_double());
}
inline Value operator==(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() == rhs.get_double());
+ return Value(lhs.get_double() == rhs.get_double());
}
inline Value operator!=(const Value& lhs, const Value& rhs)
{
- return Value(lhs.get_double() != rhs.get_double());
+ return Value(lhs.get_double() != rhs.get_double());
}
-} \ No newline at end of file
+} // namespace Spasm \ No newline at end of file