diff options
| Commit | 72d9bbcc3154142af79fb686d9dc7e4d1fa1badb (patch) | |
|---|---|---|
| Author | 2018-11-29 09:13:12 +0200 | |
| Committer | 2018-11-29 09:13:12 +0200 | |
| Files | 3cea4377cba9370f3f2248557f82831d617d89d1 /spasm/src/value.hpp | |
| IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.tar IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.tar.gz IPL-72d9bbcc3154142af79fb686d9dc7e4d1fa1badb.zip | ||
| Parent | cdfd42d72030a031e5c5d810fcd53441902b5cff (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.hpp | 161 |
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 |
