#ifndef PORYGONLANG_STRINGEVALVALUE_HPP #define PORYGONLANG_STRINGEVALVALUE_HPP #include #include "EvalValue.hpp" #include "../../Utilities/HashedString.hpp" using namespace std; namespace Porygon::Evaluation { class StringEvalValue : public EvalValue { u16string _value; size_t _hash; public: explicit StringEvalValue(u16string s) : _value(move(s)){ _hash = Utilities::HashedString::ConstHash(_value.c_str()); } [[nodiscard]] inline TypeClass GetTypeClass() const final { return TypeClass::String; } bool operator==(const EvalValue *b) const final { if (b->GetTypeClass() != TypeClass::String) return false; return this->_hash == b->GetHashCode(); }; [[nodiscard]] inline u16string EvaluateString() const final { return _value; } [[nodiscard]] inline EvalValue* Clone() const final { return new StringEvalValue(_value); } EvalValue* IndexValue(const EvalValue *val) const final { // Porygon is 1-indexed, so we convert to that. auto l = val->EvaluateInteger() - 1; return new StringEvalValue(u16string(1, _value[l])); } [[nodiscard]] inline std::size_t GetHashCode() const final { return _hash; } [[nodiscard]] inline EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final{ if (operation != Binder::BoundBinaryOperation::Concatenation){ throw EvaluationException("Binary operation not supported for strings."); } std::basic_ostringstream stringStream; stringStream << _value; stringStream << b->EvaluateString(); return new StringEvalValue(stringStream.str()); } }; } #endif //PORYGONLANG_STRINGEVALVALUE_HPP