#include "value.h" #include #include namespace domain { std::string Value::string() { switch (type) { case INT: return std::to_string(intValue); case BOOL: return boolValue ? "true" : "false"; case STRING: return stringValue; case NIL: return "null"; case UNDEFINED: return "undefined"; case ADDRESS_SPACE: return "AddressSpace::" + addressSpace->getName(); case WIRE_REFERENCE: return "Wire::" + reference; case ADDRESS_SPACE_REFERENCE: return "AddressSpace::" + reference; case ATTRIBUTE_REFERENCE: return "Attribute::" + reference; case MEMORY_REFERENCE: if (memoryReference.has_value()) { return "Memory::" + *memoryReference; } else { return "Memory::null"; } default: return "unknown"; } } Value::ValueType Value::getType() { return type; } bool Value::isType(Value::ValueType _type) { return type == _type; } std::string Value::getTypename() { switch (type) { case Value::BOOL: return "bool"; case Value::INT: return "int"; case Value::STRING: return "string"; case Value::ADDRESS_SPACE: case Value::ADDRESS_SPACE_REFERENCE: return "address space"; case Value::WIRE_REFERENCE: return "wire reference"; case Value::ATTRIBUTE_REFERENCE: return "attribute"; case Value::NIL: return "null"; case Value::MEMORY: case Value::MEMORY_REFERENCE: return "memory"; case Value::UNDEFINED: return "undefined"; } return "unknown"; } long long Value::asInt() { if (isType(Value::INT)) { return intValue; } throw std::runtime_error("expected 'int' but value contains '" + getTypename() + "'"); } std::string Value::asString() { if (isType(Value::STRING)) { return stringValue; } throw std::runtime_error("expected 'string' but value contains '" + getTypename() + "'"); } bool Value::asBool() { if (isType(Value::BOOL)) { return boolValue; } throw std::runtime_error("expected 'bool' but value contains '" + getTypename() + "'"); } AddressSpace Value::asAddressSpace() { if (isType(Value::ADDRESS_SPACE)) { return *addressSpace; } throw std::runtime_error("expected 'address space' but value contains '" + getTypename() + "'"); } std::string Value::asReference() { if (isType(Value::WIRE_REFERENCE) || isType(Value::ADDRESS_SPACE_REFERENCE) || isType(Value::ATTRIBUTE_REFERENCE) || isType(Value::UNDEFINED)) { return reference; } throw std::runtime_error("expected 'reference' but value contains '" + getTypename() + "'"); } std::optional Value::asMemoryReference() { return memoryReference; } domain::ComponentInstance *Value::asMemory() { return memory; } void Value::setInt(long long value) { if (isType(Value::INT)) { this->intValue = value; } else { throw std::runtime_error("expected to set 'int' but value contains '" + getTypename() + "'"); } } void Value::setString(std::string value) { if (isType(Value::STRING)) { this->stringValue = value; } else { throw std::runtime_error("expected to set 'string' but value contains '" + getTypename() + "'"); } } void Value::setBool(bool value) { if (isType(Value::BOOL)) { this->boolValue = value; } else { throw std::runtime_error("expected to set 'bool' but value contains '" + getTypename() + "'"); } } void Value::setReference(std::string value) { if (isType(Value::WIRE_REFERENCE)) { this->reference = value; } else { throw std::runtime_error("expected to set 'wire' but value contains '" + getTypename() + "'"); } } Value Value::fromInt(long long value) { Value val; val.type = Value::INT; val.intValue = value; return val; } Value Value::fromString(std::string value) { Value val; val.type = Value::STRING; val.stringValue = value; return val; } Value Value::fromBool(bool value) { Value val; val.type = Value::BOOL; val.boolValue = value; return val; } Value Value::fromAddressSpace(AddressSpace addressSpace) { Value val; val.type = Value::ADDRESS_SPACE; val.addressSpace = addressSpace; return val; } Value Value::fromReference(std::string value, Value::ValueType type) { Value val; val.type = type; val.reference = value; return val; } Value Value::fromNull() { Value val; val.type = Value::NIL; return val; } Value Value::fromMemoryReference(std::optional value) { Value val; val.type = MEMORY_REFERENCE; val.memoryReference = value; return val; } std::string Value::stringify() { switch (type) { case INT: return std::to_string(intValue); case BOOL: return boolValue ? "true" : "false"; case STRING: return "\"" + stringValue + "\""; case NIL: return "null"; case WIRE_REFERENCE: case ADDRESS_SPACE_REFERENCE: case ATTRIBUTE_REFERENCE: return reference; case MEMORY_REFERENCE: if (memoryReference.has_value()) { return memoryReference.value(); } else { return "null"; } default: throw std::runtime_error("unknown type couldn't stringify '" + getTypename() + "'"); } } Value Value::ofType(Value::ValueType type) { Value val; val.type = type; return val; } bool Value::equals(Value value) { if (value.getType() == type) { switch (type) { case INT: return value.asInt() == intValue; case STRING: return value.asString() == stringValue; case NIL: case UNDEFINED: return true; case WIRE_REFERENCE: case ATTRIBUTE_REFERENCE: case ADDRESS_SPACE_REFERENCE: return value.asReference() == reference; case MEMORY_REFERENCE: return value.asMemoryReference() == memoryReference; case MEMORY: return value.asMemory() == memory; case BOOL: return value.asBool() == boolValue; default: return false; } } return false; } } // namespace domain