165 lines
5.1 KiB
C++
165 lines
5.1 KiB
C++
|
|
#ifndef PORYGONLANG_EVALVALUE_HPP
|
|
#define PORYGONLANG_EVALVALUE_HPP
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <memory>
|
|
#include "../../ScriptTypes/ScriptType.hpp"
|
|
#include "../EvaluationException.hpp"
|
|
namespace Porygon::Evaluation{
|
|
class EvalValue;
|
|
class Iterator;
|
|
}
|
|
#include "../Iterator/Iterator.hpp"
|
|
#include "../../Binder/BoundOperators.hpp"
|
|
|
|
|
|
namespace Porygon::Evaluation {
|
|
class EvalValue {
|
|
public:
|
|
EvalValue() = default;
|
|
|
|
virtual ~EvalValue() = default;
|
|
|
|
[[nodiscard]]
|
|
virtual TypeClass GetTypeClass() const = 0;
|
|
|
|
[[nodiscard]]
|
|
virtual bool operator==(const EvalValue *b) const = 0;
|
|
|
|
[[nodiscard]]
|
|
virtual bool operator!=(const EvalValue *b) const {
|
|
return !(this->operator==(b));
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual EvalValue* Clone() const = 0;
|
|
|
|
[[nodiscard]]
|
|
virtual int64_t EvaluateInteger() const {
|
|
throw EvaluationException("Can't evaluate this EvalValue as integer.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual double EvaluateFloat() const {
|
|
throw EvaluationException("Can't evaluate this EvalValue as float.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual bool EvaluateBool() const {
|
|
throw EvaluationException("Can't evaluate this EvalValue as bool.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual std::u16string EvaluateString() const {
|
|
throw EvaluationException("Can't evaluate this EvalValue as string.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual std::size_t GetHashCode() const = 0;
|
|
|
|
[[nodiscard]]
|
|
virtual const EvalValue* IndexValue(const EvalValue *val) const {
|
|
std::stringstream err;
|
|
err << "Can't index this EvalValue: " << ToString() << " with key: " << val->ToString();
|
|
throw EvaluationException(err.str());
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual const EvalValue* IndexValue(const Utilities::HashedString* hash) const {
|
|
std::stringstream err;
|
|
err << "Can't index this EvalValue: " << ToString() << " with key hash: " << hash->GetDebugString();
|
|
throw EvaluationException(err.str());
|
|
}
|
|
|
|
virtual void SetIndexValue(const EvalValue *key, const EvalValue* value) const {
|
|
std::stringstream err;
|
|
err << "Can't index this EvalValue: " << ToString() << " with key: " << value->ToString();
|
|
throw EvaluationException(err.str());
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual Iterator * GetKeyIterator() const{
|
|
throw EvaluationException("Can't iterate over this EvalValue");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const{
|
|
throw EvaluationException("Binary operations are not implemented for this type.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const{
|
|
throw EvaluationException("Unary operations are not implemented for this type.");
|
|
}
|
|
|
|
[[nodiscard]]
|
|
virtual EvalValue* Cast(shared_ptr<const ScriptType> castType) const{
|
|
throw new EvaluationException("Casting to invalid type.");
|
|
}
|
|
|
|
virtual std::string ToString() const{
|
|
std::stringstream s;
|
|
s << "Type: " << ScriptType::ToString(this->GetTypeClass());
|
|
return s.str();
|
|
}
|
|
};
|
|
|
|
class BooleanEvalValue : public EvalValue {
|
|
const bool _value;
|
|
public:
|
|
explicit BooleanEvalValue(bool val)
|
|
: _value(val) {
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline EvalValue* Clone() const final {
|
|
return new BooleanEvalValue(_value);
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline TypeClass GetTypeClass() const final {
|
|
return TypeClass::Bool;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline bool EvaluateBool() const final {
|
|
return _value;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
bool operator==(const EvalValue *b) const final {
|
|
if (b->GetTypeClass() != TypeClass::Bool)
|
|
return false;
|
|
return this->EvaluateBool() == b->EvaluateBool();
|
|
};
|
|
|
|
[[nodiscard]]
|
|
inline std::size_t GetHashCode() const final {
|
|
return _value;
|
|
}
|
|
|
|
[[nodiscard]]
|
|
inline EvalValue* BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue* b) const final{
|
|
auto bVal = b -> EvaluateBool();
|
|
switch (operation){
|
|
case Binder::BoundBinaryOperation::LogicalAnd: return new BooleanEvalValue(_value && bVal);
|
|
case Binder::BoundBinaryOperation::LogicalOr: return new BooleanEvalValue(_value || bVal);
|
|
default:
|
|
throw;
|
|
}
|
|
}
|
|
|
|
[[nodiscard]]
|
|
EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const final{
|
|
switch (operation){
|
|
case Binder::BoundUnaryOperation::LogicalNegation: return new BooleanEvalValue(!_value);
|
|
default: throw;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#endif //PORYGONLANG_EVALVALUE_HPP
|