Added namespaces to most classes, general cleanup
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -5,91 +5,87 @@
|
||||
#include "EvalValues/NumericEvalValue.hpp"
|
||||
#include "EvalValues/StringEvalValue.hpp"
|
||||
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(const BoundBinaryExpression *expression) {
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
using namespace Porygon::Binder;
|
||||
|
||||
switch (expression->GetOperation()){
|
||||
case BoundBinaryOperation ::Addition:
|
||||
return leftValue.get() -> operator+ (rightValue);
|
||||
case BoundBinaryOperation::Subtraction:
|
||||
return leftValue.get() -> operator- (rightValue);
|
||||
case BoundBinaryOperation::Multiplication:
|
||||
return leftValue.get() -> operator* (rightValue);
|
||||
case BoundBinaryOperation::Division:
|
||||
return leftValue.get() -> operator/ (rightValue);
|
||||
default:
|
||||
throw EvaluationException("Can't evaluate operation to numeric");
|
||||
namespace Porygon::Evaluation {
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerBinary(const BoundBinaryExpression *expression) {
|
||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
||||
|
||||
switch (expression->GetOperation()) {
|
||||
case BoundBinaryOperation::Addition:
|
||||
return leftValue.get()->operator+(rightValue);
|
||||
case BoundBinaryOperation::Subtraction:
|
||||
return leftValue.get()->operator-(rightValue);
|
||||
case BoundBinaryOperation::Multiplication:
|
||||
return leftValue.get()->operator*(rightValue);
|
||||
case BoundBinaryOperation::Division:
|
||||
return leftValue.get()->operator/(rightValue);
|
||||
default:
|
||||
throw EvaluationException("Can't evaluate operation to numeric");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(const BoundBinaryExpression *expression){
|
||||
switch (expression->GetOperation()){
|
||||
case BoundBinaryOperation::Equality:
|
||||
{
|
||||
auto leftValue = this -> EvaluateExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateExpression(expression->GetRight());
|
||||
bool equals = leftValue.get()->operator==(rightValue.get());
|
||||
return make_shared<BooleanEvalValue>(equals);
|
||||
}
|
||||
case BoundBinaryOperation::Inequality:
|
||||
{
|
||||
auto leftValue = this -> EvaluateExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateExpression(expression->GetRight());
|
||||
bool equals = leftValue.get()->operator!=(rightValue.get());
|
||||
return make_shared<BooleanEvalValue>(equals);
|
||||
}
|
||||
case BoundBinaryOperation ::LessThan:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator<(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation ::LessThanEquals:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator<=(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation ::GreaterThan:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator>(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation ::GreaterThanEquals:
|
||||
{
|
||||
auto leftValue = this -> EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this -> EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator>=(rightValue);
|
||||
}
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanBinary(const BoundBinaryExpression *expression) {
|
||||
switch (expression->GetOperation()) {
|
||||
case BoundBinaryOperation::Equality: {
|
||||
auto leftValue = this->EvaluateExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateExpression(expression->GetRight());
|
||||
bool equals = leftValue.get()->operator==(rightValue.get());
|
||||
return make_shared<BooleanEvalValue>(equals);
|
||||
}
|
||||
case BoundBinaryOperation::Inequality: {
|
||||
auto leftValue = this->EvaluateExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateExpression(expression->GetRight());
|
||||
bool equals = leftValue.get()->operator!=(rightValue.get());
|
||||
return make_shared<BooleanEvalValue>(equals);
|
||||
}
|
||||
case BoundBinaryOperation::LessThan: {
|
||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator<(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation::LessThanEquals: {
|
||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator<=(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation::GreaterThan: {
|
||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator>(rightValue);
|
||||
}
|
||||
case BoundBinaryOperation::GreaterThanEquals: {
|
||||
auto leftValue = this->EvaluateIntegerExpression(expression->GetLeft());
|
||||
auto rightValue = this->EvaluateIntegerExpression(expression->GetRight());
|
||||
return leftValue->operator>=(rightValue);
|
||||
}
|
||||
|
||||
case BoundBinaryOperation::LogicalAnd:
|
||||
{
|
||||
auto leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
|
||||
if (!leftValue->EvaluateBool()) return leftValue;
|
||||
auto rightValue = this -> EvaluateBoolExpression(expression->GetRight());
|
||||
return rightValue;
|
||||
case BoundBinaryOperation::LogicalAnd: {
|
||||
auto leftValue = this->EvaluateBoolExpression(expression->GetLeft());
|
||||
if (!leftValue->EvaluateBool()) return leftValue;
|
||||
auto rightValue = this->EvaluateBoolExpression(expression->GetRight());
|
||||
return rightValue;
|
||||
}
|
||||
case BoundBinaryOperation::LogicalOr: {
|
||||
auto leftValue = this->EvaluateBoolExpression(expression->GetLeft());
|
||||
if (leftValue->EvaluateBool()) return leftValue;
|
||||
auto rightValue = this->EvaluateBoolExpression(expression->GetRight());
|
||||
return rightValue;
|
||||
}
|
||||
default:
|
||||
throw EvaluationException("Can't evaluate operation to boolean");
|
||||
}
|
||||
case BoundBinaryOperation::LogicalOr:
|
||||
{
|
||||
auto leftValue = this -> EvaluateBoolExpression(expression->GetLeft());
|
||||
if (leftValue->EvaluateBool()) return leftValue;
|
||||
auto rightValue = this -> EvaluateBoolExpression(expression->GetRight());
|
||||
return rightValue;
|
||||
}
|
||||
default:
|
||||
throw EvaluationException("Can't evaluate operation to boolean");
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(const BoundBinaryExpression *expression){
|
||||
if (expression->GetOperation() != BoundBinaryOperation::Concatenation)
|
||||
throw;
|
||||
std::basic_ostringstream<char16_t > stringStream;
|
||||
auto left = this -> EvaluateStringExpression(expression->GetLeft());
|
||||
stringStream << *left->EvaluateString();
|
||||
auto right = this -> EvaluateExpression(expression->GetRight());
|
||||
stringStream << *right->EvaluateString();
|
||||
return make_shared<StringEvalValue>(stringStream.str());
|
||||
const shared_ptr<StringEvalValue> Evaluator::EvaluateStringBinary(const BoundBinaryExpression *expression) {
|
||||
if (expression->GetOperation() != BoundBinaryOperation::Concatenation)
|
||||
throw;
|
||||
std::basic_ostringstream<char16_t> stringStream;
|
||||
auto left = this->EvaluateStringExpression(expression->GetLeft());
|
||||
stringStream << *left->EvaluateString();
|
||||
auto right = this->EvaluateExpression(expression->GetRight());
|
||||
stringStream << *right->EvaluateString();
|
||||
return make_shared<StringEvalValue>(stringStream.str());
|
||||
}
|
||||
}
|
||||
@@ -3,42 +3,45 @@
|
||||
#include "StringEvalValue.hpp"
|
||||
#include <cstring>
|
||||
|
||||
extern "C" {
|
||||
TypeClass GetEvalValueTypeClass(EvalValue* v){
|
||||
namespace Porygon::Evaluation {
|
||||
|
||||
extern "C" {
|
||||
Porygon::TypeClass GetEvalValueTypeClass(EvalValue *v) {
|
||||
return v->GetTypeClass();
|
||||
}
|
||||
|
||||
int64_t EvaluateEvalValueInteger(EvalValue* v){
|
||||
int64_t EvaluateEvalValueInteger(EvalValue *v) {
|
||||
return v->EvaluateInteger();
|
||||
}
|
||||
|
||||
double EvaluateEvalValueFloat(EvalValue* v){
|
||||
double EvaluateEvalValueFloat(EvalValue *v) {
|
||||
return v->EvaluateFloat();
|
||||
}
|
||||
|
||||
bool EvaluateEvalValueBool(EvalValue* v){
|
||||
bool EvaluateEvalValueBool(EvalValue *v) {
|
||||
return v->EvaluateBool();
|
||||
}
|
||||
|
||||
const char16_t * EvaluateEvalValueString(EvalValue* v){
|
||||
return v->EvaluateString() -> c_str();
|
||||
const char16_t *EvaluateEvalValueString(EvalValue *v) {
|
||||
return v->EvaluateString()->c_str();
|
||||
}
|
||||
|
||||
EvalValue* CreateIntegerEvalValue(long l){
|
||||
EvalValue *CreateIntegerEvalValue(long l) {
|
||||
return new IntegerEvalValue(l);
|
||||
}
|
||||
|
||||
EvalValue* CreateFloatEvalValue(double d){
|
||||
EvalValue *CreateFloatEvalValue(double d) {
|
||||
return new FloatEvalValue(d);
|
||||
}
|
||||
|
||||
EvalValue* CreateBoolEvalValue(bool b){
|
||||
EvalValue *CreateBoolEvalValue(bool b) {
|
||||
return new BooleanEvalValue(b);
|
||||
}
|
||||
|
||||
EvalValue* CreateStringEvalValue(const char16_t * s){
|
||||
EvalValue *CreateStringEvalValue(const char16_t *s) {
|
||||
return new StringEvalValue(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TESTS_BUILD
|
||||
@@ -47,7 +50,7 @@ extern "C" {
|
||||
|
||||
|
||||
TEST_CASE( "Evaluate String", "[integration]" ) {
|
||||
auto script = Script::Create(u"\"foo bar\"");
|
||||
auto script = Porygon::Script::Create(u"\"foo bar\"");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
script->Evaluate();
|
||||
auto lastValue = script->GetLastValue();
|
||||
|
||||
@@ -8,77 +8,83 @@
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
class EvalValue{
|
||||
public:
|
||||
EvalValue() = default;
|
||||
virtual ~EvalValue() = default;
|
||||
virtual const TypeClass GetTypeClass() const = 0;
|
||||
namespace Porygon::Evaluation {
|
||||
class EvalValue {
|
||||
public:
|
||||
EvalValue() = default;
|
||||
|
||||
virtual const bool operator ==(EvalValue* b) const = 0;
|
||||
virtual ~EvalValue() = default;
|
||||
|
||||
virtual const bool operator !=(EvalValue*b) const{
|
||||
return ! (this->operator==(b));
|
||||
}
|
||||
virtual const TypeClass GetTypeClass() const = 0;
|
||||
|
||||
virtual const shared_ptr<EvalValue> Clone() const = 0;
|
||||
virtual const bool operator==(EvalValue *b) const = 0;
|
||||
|
||||
virtual const long EvaluateInteger() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as integer.");
|
||||
}
|
||||
virtual const double EvaluateFloat() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as float.");
|
||||
}
|
||||
virtual const bool EvaluateBool() const{
|
||||
throw EvaluationException("Can't evaluate this EvalValue as bool.");
|
||||
}
|
||||
virtual const std::u16string* EvaluateString() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as string.");
|
||||
}
|
||||
virtual const bool operator!=(EvalValue *b) const {
|
||||
return !(this->operator==(b));
|
||||
}
|
||||
|
||||
virtual const std::size_t GetHashCode() const = 0;
|
||||
virtual const shared_ptr<EvalValue> Clone() const = 0;
|
||||
|
||||
virtual const shared_ptr<EvalValue> IndexValue(EvalValue* val) const{
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
virtual const long EvaluateInteger() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as integer.");
|
||||
}
|
||||
|
||||
virtual const shared_ptr<EvalValue> IndexValue(uint32_t hash) const{
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
virtual const double EvaluateFloat() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as float.");
|
||||
}
|
||||
|
||||
virtual void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue>& value) const{
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
};
|
||||
virtual const bool EvaluateBool() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as bool.");
|
||||
}
|
||||
|
||||
class BooleanEvalValue : public EvalValue{
|
||||
const bool _value;
|
||||
public:
|
||||
explicit BooleanEvalValue(bool val)
|
||||
: _value(val)
|
||||
{
|
||||
}
|
||||
virtual const std::u16string *EvaluateString() const {
|
||||
throw EvaluationException("Can't evaluate this EvalValue as string.");
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
return make_shared<BooleanEvalValue>(_value);
|
||||
}
|
||||
virtual const std::size_t GetHashCode() const = 0;
|
||||
|
||||
const TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::Bool;
|
||||
}
|
||||
virtual const shared_ptr<EvalValue> IndexValue(EvalValue *val) const {
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
|
||||
const bool EvaluateBool() const final{
|
||||
return _value;
|
||||
}
|
||||
virtual const shared_ptr<EvalValue> IndexValue(uint32_t hash) const {
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
|
||||
const bool operator ==(EvalValue* b) const final{
|
||||
if (b->GetTypeClass() != TypeClass::Bool)
|
||||
return false;
|
||||
return this->EvaluateBool() == b->EvaluateBool();
|
||||
virtual void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const {
|
||||
throw EvaluationException("Can't index this EvalValue");
|
||||
}
|
||||
};
|
||||
|
||||
const std::size_t GetHashCode() const final{
|
||||
return _value;
|
||||
}
|
||||
};
|
||||
class BooleanEvalValue : public EvalValue {
|
||||
const bool _value;
|
||||
public:
|
||||
explicit BooleanEvalValue(bool val)
|
||||
: _value(val) {
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return make_shared<BooleanEvalValue>(_value);
|
||||
}
|
||||
|
||||
const TypeClass GetTypeClass() const final {
|
||||
return TypeClass::Bool;
|
||||
}
|
||||
|
||||
const bool EvaluateBool() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
const bool operator==(EvalValue *b) const final {
|
||||
if (b->GetTypeClass() != TypeClass::Bool)
|
||||
return false;
|
||||
return this->EvaluateBool() == b->EvaluateBool();
|
||||
};
|
||||
|
||||
const std::size_t GetHashCode() const final {
|
||||
return _value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_EVALVALUE_HPP
|
||||
|
||||
@@ -1,144 +1,146 @@
|
||||
|
||||
#include "NumericEvalValue.hpp"
|
||||
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator+(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() + b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() + b->GetIntegerValue());
|
||||
namespace Porygon::Evaluation {
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator+(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() + b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() + b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() + b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator-(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() - b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() - b->GetIntegerValue());
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator-(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() - b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() - b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() - b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator*(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() * b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() * b->GetIntegerValue());
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator*(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() * b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() * b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() * b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator/(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() / b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() / b->GetIntegerValue());
|
||||
const shared_ptr<NumericEvalValue> NumericEvalValue::operator/(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<FloatEvalValue>(this->GetFloatValue() / b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<FloatEvalValue>(this->GetIntegerValue() / b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<IntegerEvalValue>(this->GetIntegerValue() / b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool NumericEvalValue::operator==(EvalValue *b) const {
|
||||
if (b->GetTypeClass() != TypeClass::Number)
|
||||
return false;
|
||||
auto numVal = (NumericEvalValue*)b;
|
||||
if (this->IsFloat() != numVal->IsFloat())
|
||||
return false;
|
||||
const bool NumericEvalValue::operator==(EvalValue *b) const {
|
||||
if (b->GetTypeClass() != TypeClass::Number)
|
||||
return false;
|
||||
auto numVal = (NumericEvalValue *) b;
|
||||
if (this->IsFloat() != numVal->IsFloat())
|
||||
return false;
|
||||
|
||||
if (this->IsFloat()){
|
||||
return this->EvaluateFloat() == numVal->EvaluateFloat();
|
||||
} else{
|
||||
return this->EvaluateInteger() == numVal->EvaluateInteger();
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator<(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() < b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() < b->GetIntegerValue());
|
||||
if (this->IsFloat()) {
|
||||
return this->EvaluateFloat() == numVal->EvaluateFloat();
|
||||
} else {
|
||||
return this->EvaluateInteger() == numVal->EvaluateInteger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator<=(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <= b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() <= b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() <= b->GetIntegerValue());
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator<(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() < b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() < b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() < b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator>(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() > b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() > b->GetIntegerValue());
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator<=(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() <= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() <= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() <= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator>=(const shared_ptr<NumericEvalValue>& b) const {
|
||||
if (this->IsFloat()){
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()){
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() >= b->GetFloatValue());
|
||||
} else{
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() >= b->GetIntegerValue());
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator>(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() > b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() > b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() > b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> NumericEvalValue::operator>=(const shared_ptr<NumericEvalValue> &b) const {
|
||||
if (this->IsFloat()) {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetFloatValue() >= b->GetIntegerValue());
|
||||
}
|
||||
} else {
|
||||
if (b->IsFloat()) {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() >= b->GetFloatValue());
|
||||
} else {
|
||||
return make_shared<BooleanEvalValue>(this->GetIntegerValue() >= b->GetIntegerValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,76 +4,98 @@
|
||||
|
||||
#include <sstream>
|
||||
#include "EvalValue.hpp"
|
||||
namespace Porygon::Evaluation {
|
||||
class NumericEvalValue : public EvalValue {
|
||||
|
||||
class NumericEvalValue : public EvalValue{
|
||||
virtual const long GetIntegerValue() const = 0;
|
||||
|
||||
virtual const long GetIntegerValue() const = 0;
|
||||
virtual const double GetFloatValue() const = 0;
|
||||
virtual const double GetFloatValue() const = 0;
|
||||
|
||||
public:
|
||||
virtual const bool IsFloat() const = 0;
|
||||
public:
|
||||
virtual const bool IsFloat() const = 0;
|
||||
|
||||
const TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::Number;
|
||||
}
|
||||
const TypeClass GetTypeClass() const final {
|
||||
return TypeClass::Number;
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> operator +(const shared_ptr<NumericEvalValue>& b) const;
|
||||
const shared_ptr<NumericEvalValue> operator -(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const shared_ptr<NumericEvalValue> operator *(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const shared_ptr<NumericEvalValue> operator /(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const shared_ptr<BooleanEvalValue> operator <(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const shared_ptr<BooleanEvalValue> operator <=(const shared_ptr<NumericEvalValue>& b)const ;
|
||||
const shared_ptr<BooleanEvalValue> operator >(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const shared_ptr<BooleanEvalValue> operator >=(const shared_ptr<NumericEvalValue>& b) const ;
|
||||
const bool operator ==(EvalValue* b) const final;
|
||||
};
|
||||
const shared_ptr<NumericEvalValue> operator+(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
class IntegerEvalValue : public NumericEvalValue{
|
||||
const long _value;
|
||||
const long GetIntegerValue() const final{return _value;}
|
||||
const double GetFloatValue() const final{ throw EvaluationException("Attempting to retrieve float from int eval value."); }
|
||||
public:
|
||||
explicit IntegerEvalValue(long value) :_value(value){
|
||||
}
|
||||
const bool IsFloat() const final{
|
||||
return false;
|
||||
}
|
||||
const shared_ptr<NumericEvalValue> operator-(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const long EvaluateInteger() const final{
|
||||
return _value;
|
||||
}
|
||||
const shared_ptr<NumericEvalValue> operator*(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
return make_shared<IntegerEvalValue>(_value);
|
||||
}
|
||||
const shared_ptr<NumericEvalValue> operator/(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const std::size_t GetHashCode() const final{
|
||||
return std::hash<long>{}(_value);
|
||||
}
|
||||
};
|
||||
const shared_ptr<BooleanEvalValue> operator<(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
class FloatEvalValue : public NumericEvalValue{
|
||||
const double _value;
|
||||
const long GetIntegerValue() const final{ throw EvaluationException("Attempting to retrieve float from int eval value."); }
|
||||
const double GetFloatValue() const final{return _value;}
|
||||
public:
|
||||
explicit FloatEvalValue(double value) :_value(value){
|
||||
}
|
||||
const bool IsFloat() const final{
|
||||
return true;
|
||||
}
|
||||
const shared_ptr<BooleanEvalValue> operator<=(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const double EvaluateFloat() const final{
|
||||
return _value;
|
||||
}
|
||||
const shared_ptr<BooleanEvalValue> operator>(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
return make_shared<FloatEvalValue>(_value);
|
||||
}
|
||||
const shared_ptr<BooleanEvalValue> operator>=(const shared_ptr<NumericEvalValue> &b) const;
|
||||
|
||||
const std::size_t GetHashCode() const final{
|
||||
return std::hash<double >{}(_value);
|
||||
}
|
||||
};
|
||||
const bool operator==(EvalValue *b) const final;
|
||||
};
|
||||
|
||||
class IntegerEvalValue : public NumericEvalValue {
|
||||
const long _value;
|
||||
|
||||
const long GetIntegerValue() const final { return _value; }
|
||||
|
||||
const double GetFloatValue() const final {
|
||||
throw EvaluationException("Attempting to retrieve float from int eval value.");
|
||||
}
|
||||
|
||||
public:
|
||||
explicit IntegerEvalValue(long value) : _value(value) {
|
||||
}
|
||||
|
||||
const bool IsFloat() const final {
|
||||
return false;
|
||||
}
|
||||
|
||||
const long EvaluateInteger() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return make_shared<IntegerEvalValue>(_value);
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final {
|
||||
return std::hash<long>{}(_value);
|
||||
}
|
||||
};
|
||||
|
||||
class FloatEvalValue : public NumericEvalValue {
|
||||
const double _value;
|
||||
|
||||
const long GetIntegerValue() const final {
|
||||
throw EvaluationException("Attempting to retrieve float from int eval value.");
|
||||
}
|
||||
|
||||
const double GetFloatValue() const final { return _value; }
|
||||
|
||||
public:
|
||||
explicit FloatEvalValue(double value) : _value(value) {
|
||||
}
|
||||
|
||||
const bool IsFloat() const final {
|
||||
return true;
|
||||
}
|
||||
|
||||
const double EvaluateFloat() const final {
|
||||
return _value;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return make_shared<FloatEvalValue>(_value);
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final {
|
||||
return std::hash<double>{}(_value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_NUMERICEVALVALUE_HPP
|
||||
|
||||
@@ -11,63 +11,65 @@
|
||||
#include "../Evaluator.hpp"
|
||||
#include "../EvaluationScope/EvaluationScope.hpp"
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
class ScriptFunctionEvalValue : public EvalValue {
|
||||
const std::shared_ptr<BoundBlockStatement> _innerBlock;
|
||||
const std::shared_ptr<FunctionScriptType> _type;
|
||||
const std::shared_ptr<EvaluationScope> _scope;
|
||||
const std::size_t _hash;
|
||||
|
||||
class ScriptFunctionEvalValue : public EvalValue{
|
||||
const std::shared_ptr<BoundBlockStatement> _innerBlock;
|
||||
const std::shared_ptr<FunctionScriptType> _type;
|
||||
const std::shared_ptr<EvaluationScope> _scope;
|
||||
const std::size_t _hash;
|
||||
explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock, std::shared_ptr<EvaluationScope> scope,
|
||||
std::shared_ptr<FunctionScriptType> type, size_t hash)
|
||||
: _type(std::move(type)),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)),
|
||||
_hash(hash)
|
||||
{
|
||||
}
|
||||
explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock,
|
||||
std::shared_ptr<EvaluationScope> scope,
|
||||
std::shared_ptr<FunctionScriptType> type, size_t hash)
|
||||
: _type(std::move(type)),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)),
|
||||
_hash(hash) {
|
||||
}
|
||||
|
||||
public:
|
||||
explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock, std::shared_ptr<EvaluationScope> scope,
|
||||
std::shared_ptr<FunctionScriptType> type)
|
||||
: _type(std::move(type)),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)),
|
||||
_hash(rand())
|
||||
{
|
||||
}
|
||||
public:
|
||||
explicit ScriptFunctionEvalValue(std::shared_ptr<BoundBlockStatement> innerBlock,
|
||||
std::shared_ptr<EvaluationScope> scope,
|
||||
std::shared_ptr<FunctionScriptType> type)
|
||||
: _type(std::move(type)),
|
||||
_innerBlock(std::move(innerBlock)),
|
||||
_scope(std::move(scope)),
|
||||
_hash(rand()) {
|
||||
}
|
||||
|
||||
const std::shared_ptr<ScriptType> GetType() const{
|
||||
return _type;
|
||||
}
|
||||
const std::shared_ptr<ScriptType> GetType() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
const TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::Function;
|
||||
}
|
||||
const TypeClass GetTypeClass() const final {
|
||||
return TypeClass::Function;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
// We don't run make_shared here as it can't call private constructors
|
||||
return shared_ptr<ScriptFunctionEvalValue>(new ScriptFunctionEvalValue(_innerBlock, _scope, _type, _hash));
|
||||
}
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
// We don't run make_shared here as it can't call private constructors
|
||||
return shared_ptr<ScriptFunctionEvalValue>(new ScriptFunctionEvalValue(_innerBlock, _scope, _type, _hash));
|
||||
}
|
||||
|
||||
|
||||
const bool operator ==(EvalValue* b) const final{
|
||||
if (b->GetTypeClass() != TypeClass::Function)
|
||||
return false;
|
||||
return this->_hash == ((ScriptFunctionEvalValue*)b)->_hash;
|
||||
const bool operator==(EvalValue *b) const final {
|
||||
if (b->GetTypeClass() != TypeClass::Function)
|
||||
return false;
|
||||
return this->_hash == ((ScriptFunctionEvalValue *) b)->_hash;
|
||||
};
|
||||
|
||||
const std::shared_ptr<BoundBlockStatement> &GetInnerBlock() const {
|
||||
return _innerBlock;
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final {
|
||||
return _hash;
|
||||
}
|
||||
|
||||
const std::shared_ptr<EvaluationScope> &GetScope() const {
|
||||
return _scope;
|
||||
}
|
||||
};
|
||||
|
||||
const std::shared_ptr<BoundBlockStatement>& GetInnerBlock() const{
|
||||
return _innerBlock;
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final{
|
||||
return _hash;
|
||||
}
|
||||
|
||||
const std::shared_ptr<EvaluationScope>& GetScope() const{
|
||||
return _scope;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PORYGONLANG_SCRIPTFUNCTIONEVALVALUE_HPP
|
||||
|
||||
@@ -8,43 +8,44 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class StringEvalValue : public EvalValue{
|
||||
u16string _value;
|
||||
size_t _hash;
|
||||
public:
|
||||
explicit StringEvalValue(u16string s){
|
||||
_value = move(s);
|
||||
_hash = HashedString::ConstHash (_value.c_str());
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
const TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::String;
|
||||
}
|
||||
const TypeClass GetTypeClass() const final {
|
||||
return TypeClass::String;
|
||||
}
|
||||
|
||||
const bool operator ==(EvalValue* b) const final{
|
||||
if (b->GetTypeClass() != TypeClass::String)
|
||||
return false;
|
||||
return this->_hash == b->GetHashCode();
|
||||
const bool operator==(EvalValue *b) const final {
|
||||
if (b->GetTypeClass() != TypeClass::String)
|
||||
return false;
|
||||
return this->_hash == b->GetHashCode();
|
||||
};
|
||||
|
||||
const u16string *EvaluateString() const final {
|
||||
return &_value;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return make_shared<StringEvalValue>(_value);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
|
||||
// Porygon is 1-indexed, so we convert to that.
|
||||
auto l = val->EvaluateInteger() - 1;
|
||||
return make_shared<StringEvalValue>(u16string(1, _value[l]));
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final {
|
||||
return _hash;
|
||||
}
|
||||
};
|
||||
|
||||
const u16string* EvaluateString() const final{
|
||||
return &_value;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
return make_shared<StringEvalValue>(_value);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue* val) const final{
|
||||
// Porygon is 1-indexed, so we convert to that.
|
||||
auto l = val->EvaluateInteger() - 1;
|
||||
return make_shared<StringEvalValue>(u16string(1, _value[l]));
|
||||
}
|
||||
|
||||
const std::size_t GetHashCode() const final{
|
||||
return _hash;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_STRINGEVALVALUE_HPP
|
||||
|
||||
@@ -6,55 +6,57 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class TableEvalValue : public EvalValue {
|
||||
shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> _table;
|
||||
size_t _hash;
|
||||
namespace Porygon::Evaluation {
|
||||
class TableEvalValue : public EvalValue {
|
||||
shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> _table;
|
||||
size_t _hash;
|
||||
|
||||
explicit TableEvalValue(shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> table, size_t hash){
|
||||
_table = std::move(table);
|
||||
_hash = hash;
|
||||
}
|
||||
public:
|
||||
explicit TableEvalValue(shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> table){
|
||||
_table = std::move(table);
|
||||
_hash = rand();
|
||||
}
|
||||
explicit TableEvalValue(shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> table, size_t hash) {
|
||||
_table = std::move(table);
|
||||
_hash = hash;
|
||||
}
|
||||
|
||||
const TypeClass GetTypeClass() const final{
|
||||
return TypeClass ::Table;
|
||||
}
|
||||
public:
|
||||
explicit TableEvalValue(shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>> table) {
|
||||
_table = std::move(table);
|
||||
_hash = rand();
|
||||
}
|
||||
|
||||
const size_t GetHashCode() const final{
|
||||
return _hash;
|
||||
}
|
||||
const TypeClass GetTypeClass() const final {
|
||||
return TypeClass::Table;
|
||||
}
|
||||
|
||||
const bool operator ==(EvalValue* b) const final{
|
||||
return this -> _hash == b->GetHashCode();
|
||||
}
|
||||
const size_t GetHashCode() const final {
|
||||
return _hash;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Clone() const final{
|
||||
return shared_ptr<EvalValue>(new TableEvalValue(_table, _hash));
|
||||
}
|
||||
const bool operator==(EvalValue *b) const final {
|
||||
return this->_hash == b->GetHashCode();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue* val) const final{
|
||||
auto hash = val->GetHashCode();
|
||||
return this -> _table->at(hash);
|
||||
}
|
||||
const shared_ptr<EvalValue> Clone() const final {
|
||||
return shared_ptr<EvalValue>(new TableEvalValue(_table, _hash));
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final{
|
||||
return this -> _table->at(hash);
|
||||
}
|
||||
const shared_ptr<EvalValue> IndexValue(EvalValue *val) const final {
|
||||
auto hash = val->GetHashCode();
|
||||
return this->_table->at(hash);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> IndexValue(const char* val) const {
|
||||
auto hash = HashedString::ConstHash(val);
|
||||
return this -> _table -> at(hash);
|
||||
}
|
||||
const shared_ptr<EvalValue> IndexValue(uint32_t hash) const final {
|
||||
return this->_table->at(hash);
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue>& value) const final{
|
||||
auto hash = key->GetHashCode();
|
||||
this -> _table->at(hash) = value;
|
||||
}
|
||||
};
|
||||
const shared_ptr<EvalValue> IndexValue(const char *val) const {
|
||||
auto hash = Utilities::HashedString::ConstHash(val);
|
||||
return this->_table->at(hash);
|
||||
}
|
||||
|
||||
void SetIndexValue(EvalValue *key, const shared_ptr<EvalValue> &value) const final {
|
||||
auto hash = key->GetHashCode();
|
||||
this->_table->at(hash) = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_TABLEEVALVALUE_HPP
|
||||
|
||||
@@ -7,18 +7,20 @@
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
class EvaluationException : public std::exception {
|
||||
string _message;
|
||||
public:
|
||||
explicit EvaluationException(string message){
|
||||
_message = std::move(message);
|
||||
}
|
||||
namespace Porygon::Evaluation {
|
||||
class EvaluationException : public std::exception {
|
||||
string _message;
|
||||
public:
|
||||
explicit EvaluationException(string message) {
|
||||
_message = std::move(message);
|
||||
}
|
||||
|
||||
const string defaultErrorText = "An evaluation exception occurred: ";
|
||||
const char* what() const noexcept final{
|
||||
return (defaultErrorText + _message).c_str();
|
||||
}
|
||||
};
|
||||
const string defaultErrorText = "An evaluation exception occurred: ";
|
||||
|
||||
const char *what() const noexcept final {
|
||||
return (defaultErrorText + _message).c_str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //PORYGONLANG_EVALUATIONEXCEPTION_HPP
|
||||
|
||||
@@ -2,34 +2,37 @@
|
||||
#include "EvaluationScope.hpp"
|
||||
#include <memory>
|
||||
|
||||
EvaluationScope::EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>> *scriptVariables, int localVariableCount) {
|
||||
_scriptScope = scriptVariables;
|
||||
_localScope = unordered_map<uint64_t, shared_ptr<EvalValue>>(localVariableCount);
|
||||
}
|
||||
namespace Porygon::Evaluation {
|
||||
EvaluationScope::EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>> *scriptVariables,
|
||||
int localVariableCount) {
|
||||
_scriptScope = scriptVariables;
|
||||
_localScope = unordered_map<uint64_t, shared_ptr<EvalValue>>(localVariableCount);
|
||||
}
|
||||
|
||||
void EvaluationScope::CreateVariable(const BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
|
||||
if (key->GetScopeId() == 0){
|
||||
_scriptScope -> at(key->GetIdentifier()) = value;
|
||||
} else{
|
||||
auto insert = _localScope.insert({key->GetHash(), value});
|
||||
if (!insert.second){
|
||||
void EvaluationScope::CreateVariable(const BoundVariableKey *key, const shared_ptr<EvalValue> &value) {
|
||||
if (key->GetScopeId() == 0) {
|
||||
_scriptScope->at(key->GetIdentifier()) = value;
|
||||
} else {
|
||||
auto insert = _localScope.insert({key->GetHash(), value});
|
||||
if (!insert.second) {
|
||||
_localScope[key->GetHash()] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EvaluationScope::SetVariable(const BoundVariableKey *key, const shared_ptr<EvalValue> &value) {
|
||||
if (key->GetScopeId() == 0) {
|
||||
_scriptScope->at(key->GetIdentifier()) = value;
|
||||
} else {
|
||||
_localScope[key->GetHash()] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EvaluationScope::SetVariable(const BoundVariableKey* key, const shared_ptr<EvalValue> &value) {
|
||||
if (key->GetScopeId() == 0){
|
||||
_scriptScope -> at(key->GetIdentifier()) = value;
|
||||
} else{
|
||||
_localScope[key->GetHash()] = value;
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<EvalValue> EvaluationScope::GetVariable(const BoundVariableKey* key) {
|
||||
if (key->GetScopeId() == 0){
|
||||
return _scriptScope -> at(key->GetIdentifier());
|
||||
} else{
|
||||
return _localScope[key->GetHash()];
|
||||
shared_ptr<EvalValue> EvaluationScope::GetVariable(const BoundVariableKey *key) {
|
||||
if (key->GetScopeId() == 0) {
|
||||
return _scriptScope->at(key->GetIdentifier());
|
||||
} else {
|
||||
return _localScope[key->GetHash()];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,18 +5,24 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "../EvalValues/EvalValue.hpp"
|
||||
using namespace Porygon::Binder;
|
||||
|
||||
class EvaluationScope {
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>>* _scriptScope;
|
||||
unordered_map<uint64_t, shared_ptr<EvalValue>> _localScope;
|
||||
public:
|
||||
explicit EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>>* scriptVariables, int deepestScope);
|
||||
~EvaluationScope() = default;
|
||||
namespace Porygon::Evaluation {
|
||||
class EvaluationScope {
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>> *_scriptScope;
|
||||
unordered_map<uint64_t, shared_ptr<EvalValue>> _localScope;
|
||||
public:
|
||||
explicit EvaluationScope(unordered_map<uint32_t, shared_ptr<EvalValue>> *scriptVariables, int deepestScope);
|
||||
|
||||
void CreateVariable(const BoundVariableKey* key, const shared_ptr<EvalValue>& value);
|
||||
void SetVariable(const BoundVariableKey* key, const shared_ptr<EvalValue>& value);
|
||||
shared_ptr<EvalValue> GetVariable(const BoundVariableKey* key);
|
||||
};
|
||||
~EvaluationScope() = default;
|
||||
|
||||
void CreateVariable(const BoundVariableKey *key, const shared_ptr<EvalValue> &value);
|
||||
|
||||
void SetVariable(const BoundVariableKey *key, const shared_ptr<EvalValue> &value);
|
||||
|
||||
shared_ptr<EvalValue> GetVariable(const BoundVariableKey *key);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //PORYGONLANG_EVALUATIONSCOPE_HPP
|
||||
|
||||
@@ -11,317 +11,369 @@
|
||||
#include "../TableScriptType.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace Porygon::Binder;
|
||||
|
||||
EvalValue* Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
||||
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptData->_scriptVariables, statement->GetLocalVariableCount());
|
||||
EvaluateBlockStatement(statement);
|
||||
return this -> _returnValue.get();
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateStatement(const BoundStatement *statement) {
|
||||
if (this->_hasReturned)
|
||||
return;
|
||||
switch (statement->GetKind()){
|
||||
case BoundStatementKind ::Script: throw; // Should never happen
|
||||
case BoundStatementKind ::Block: return this->EvaluateBlockStatement((BoundBlockStatement *) statement);
|
||||
case BoundStatementKind ::Expression: return this -> EvaluateExpressionStatement((BoundExpressionStatement*)statement);
|
||||
case BoundStatementKind ::Assignment: return this -> EvaluateAssignmentStatement((BoundAssignmentStatement*)statement);
|
||||
case BoundStatementKind::IndexAssignment:
|
||||
return this -> EvaluateIndexAssignmentStatement((BoundIndexAssignmentStatement*)statement);
|
||||
case BoundStatementKind ::FunctionDeclaration: return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement*)statement);
|
||||
case BoundStatementKind::Return: return this -> EvaluateReturnStatement((BoundReturnStatement*)statement);
|
||||
case BoundStatementKind::Conditional: return this -> EvaluateConditionalStatement((BoundConditionalStatement*)statement);
|
||||
|
||||
case BoundStatementKind::Bad:
|
||||
throw;
|
||||
namespace Porygon::Evaluation {
|
||||
EvalValue *Evaluator::Evaluate(const BoundScriptStatement *statement) {
|
||||
this->_evaluationScope = make_shared<EvaluationScope>(this->_scriptVariables,
|
||||
statement->GetLocalVariableCount());
|
||||
EvaluateBlockStatement(statement);
|
||||
return this->_returnValue.get();
|
||||
}
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateBlockStatement(const BoundBlockStatement *statement) {
|
||||
for (auto s: *statement->GetStatements()){
|
||||
this -> EvaluateStatement(s);
|
||||
void Evaluator::EvaluateStatement(const BoundStatement *statement) {
|
||||
if (this->_hasReturned)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
switch (statement->GetKind()) {
|
||||
case BoundStatementKind::Script:
|
||||
throw; // Should never happen
|
||||
case BoundStatementKind::Block:
|
||||
return this->EvaluateBlockStatement((BoundBlockStatement *) statement);
|
||||
case BoundStatementKind::Expression:
|
||||
return this->EvaluateExpressionStatement((BoundExpressionStatement *) statement);
|
||||
case BoundStatementKind::Assignment:
|
||||
return this->EvaluateAssignmentStatement((BoundAssignmentStatement *) statement);
|
||||
case BoundStatementKind::IndexAssignment:
|
||||
return this->EvaluateIndexAssignmentStatement((BoundIndexAssignmentStatement *) statement);
|
||||
case BoundStatementKind::FunctionDeclaration:
|
||||
return this->EvaluateFunctionDeclarationStatement((BoundFunctionDeclarationStatement *) statement);
|
||||
case BoundStatementKind::Return:
|
||||
return this->EvaluateReturnStatement((BoundReturnStatement *) statement);
|
||||
case BoundStatementKind::Conditional:
|
||||
return this->EvaluateConditionalStatement((BoundConditionalStatement *) statement);
|
||||
|
||||
void Evaluator::EvaluateExpressionStatement(const BoundExpressionStatement *statement) {
|
||||
// Save new value
|
||||
this->_lastValue = this -> EvaluateExpression(statement->GetExpression());
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateAssignmentStatement(const BoundAssignmentStatement *statement) {
|
||||
auto value = this -> EvaluateExpression(statement->GetExpression());
|
||||
auto key = statement->GetKey();
|
||||
if (key->IsCreation()){
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else{
|
||||
this->_evaluationScope->SetVariable(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement *statement) {
|
||||
auto indexExpression = statement -> GetIndexExpression();
|
||||
auto value = this -> EvaluateExpression(statement -> GetValueExpression());
|
||||
auto index = ((BoundIndexExpression*)indexExpression);
|
||||
auto table = this -> EvaluateExpression(index -> GetIndexableExpression());
|
||||
auto key = this -> EvaluateExpression(index->GetIndexExpression());
|
||||
table -> SetIndexValue(key.get(), value);
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
|
||||
auto type = statement->GetType();
|
||||
auto key = statement->GetKey();
|
||||
auto block = statement->GetBlock();
|
||||
auto value = make_shared<ScriptFunctionEvalValue>(block, this->_evaluationScope, type);
|
||||
if (key->IsCreation()){
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else{
|
||||
this->_evaluationScope->SetVariable(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateReturnStatement(const BoundReturnStatement* statement){
|
||||
auto expression = statement->GetExpression();
|
||||
if (expression == nullptr){
|
||||
this->_hasReturned = true;
|
||||
return;
|
||||
}
|
||||
auto value = this -> EvaluateExpression(expression);
|
||||
this->_hasReturned = true;
|
||||
this -> _returnValue = value;
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) {
|
||||
auto condition = statement->GetCondition();
|
||||
if (EvaluateBoolExpression(condition) -> EvaluateBool()){
|
||||
this -> EvaluateStatement(statement->GetBlock());
|
||||
} else{
|
||||
auto elseStatement = statement -> GetElseStatement();
|
||||
if (elseStatement != nullptr){
|
||||
this->EvaluateStatement(elseStatement);
|
||||
case BoundStatementKind::Bad:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
||||
auto type = expression -> GetType();
|
||||
switch (type->GetClass()){
|
||||
case TypeClass ::Number: return this -> EvaluateIntegerExpression(expression);
|
||||
case TypeClass ::Bool: return this -> EvaluateBoolExpression(expression);
|
||||
case TypeClass ::String: return this -> EvaluateStringExpression(expression);
|
||||
case TypeClass ::Function: return this->EvaluateFunctionExpression(expression);
|
||||
case TypeClass ::Nil: return this->EvaluateNilExpression(expression);
|
||||
case TypeClass ::Table: return this-> EvaluateTableExpression(expression);
|
||||
case TypeClass ::UserData: return this -> EvaluateUserDataExpression(expression);
|
||||
default: throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::GetVariable(const BoundVariableExpression *expression){
|
||||
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
|
||||
if (variable == nullptr){
|
||||
throw EvaluationException("Variable not found");
|
||||
}
|
||||
return variable->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()){
|
||||
case BoundExpressionKind ::LiteralInteger: return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression*)expression)->GetValue());
|
||||
case BoundExpressionKind ::LiteralFloat: return make_shared<FloatEvalValue>(((BoundLiteralFloatExpression*)expression)->GetValue());
|
||||
case BoundExpressionKind::Unary: return this -> EvaluateIntegerUnary((BoundUnaryExpression*)expression);
|
||||
case BoundExpressionKind ::Binary: return this -> EvaluateIntegerBinary((BoundBinaryExpression*)expression);
|
||||
case BoundExpressionKind::Variable: return dynamic_pointer_cast<NumericEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
|
||||
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind ::Index: return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind ::PeriodIndex: return dynamic_pointer_cast<NumericEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind ::LiteralString:
|
||||
case BoundExpressionKind ::LiteralBool:
|
||||
case BoundExpressionKind ::Bad:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind ::LiteralBool: return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression*)expression)->GetValue());
|
||||
case BoundExpressionKind::Unary: return this -> EvaluateBooleanUnary((BoundUnaryExpression*)expression);
|
||||
case BoundExpressionKind::Binary: return this -> EvaluateBooleanBinary((BoundBinaryExpression*)expression);
|
||||
case BoundExpressionKind::Variable: return dynamic_pointer_cast<BooleanEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
|
||||
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind ::Index: return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind ::PeriodIndex: return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind::Bad:
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
case BoundExpressionKind::LiteralString:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind ::LiteralString:
|
||||
return make_shared<StringEvalValue>(((BoundLiteralStringExpression*)expression)->GetValue());
|
||||
case BoundExpressionKind::Binary:
|
||||
return this -> EvaluateStringBinary((BoundBinaryExpression*)expression);
|
||||
case BoundExpressionKind::Variable: return dynamic_pointer_cast<StringEvalValue>(this->GetVariable((BoundVariableExpression*)expression));
|
||||
case BoundExpressionKind ::FunctionCall: return dynamic_pointer_cast<StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind ::Index: return dynamic_pointer_cast<StringEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind ::PeriodIndex: return dynamic_pointer_cast<StringEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind::Bad:
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
case BoundExpressionKind::Unary:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression *expression){
|
||||
switch (expression->GetKind()){
|
||||
case BoundExpressionKind ::Variable: return this->GetVariable((BoundVariableExpression*)expression);
|
||||
case BoundExpressionKind ::Index: return this->EvaluateIndexExpression(expression);
|
||||
case BoundExpressionKind ::PeriodIndex: return this->EvaluatePeriodIndexExpression(expression);
|
||||
default: throw;
|
||||
}
|
||||
}
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression *expression){
|
||||
switch (expression->GetKind()){
|
||||
case BoundExpressionKind ::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression *expression){
|
||||
switch (expression->GetKind()){
|
||||
case BoundExpressionKind ::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
case BoundExpressionKind ::Variable: return this->GetVariable((BoundVariableExpression*)expression);
|
||||
case BoundExpressionKind ::Index: return this->EvaluateIndexExpression(expression);
|
||||
case BoundExpressionKind ::NumericalTable: return this-> EvaluateNumericTableExpression(expression);
|
||||
case BoundExpressionKind ::Table: return this -> EvaluateComplexTableExpression(expression);
|
||||
case BoundExpressionKind ::PeriodIndex: return this->EvaluatePeriodIndexExpression(expression);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression){
|
||||
auto functionCall = (BoundFunctionCallExpression*)expression;
|
||||
auto function = dynamic_pointer_cast<ScriptFunctionEvalValue>(this->EvaluateExpression(functionCall->GetFunctionExpression()));
|
||||
|
||||
auto boundParameters = functionCall->GetParameters();
|
||||
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters->size());
|
||||
for (int i = 0; i < boundParameters->size(); i++){
|
||||
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
|
||||
void Evaluator::EvaluateBlockStatement(const BoundBlockStatement *statement) {
|
||||
for (auto s: *statement->GetStatements()) {
|
||||
this->EvaluateStatement(s);
|
||||
if (this->_hasReturned)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto parameterKeys = type->GetParameterKeys();
|
||||
auto originalScope = this->_evaluationScope;
|
||||
this->_evaluationScope = function->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
void Evaluator::EvaluateExpressionStatement(const BoundExpressionStatement *statement) {
|
||||
// Save new value
|
||||
this->_lastValue = this->EvaluateExpression(statement->GetExpression());
|
||||
}
|
||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
|
||||
this->_hasReturned = false;
|
||||
auto r = this -> _returnValue;
|
||||
this -> _returnValue = nullptr;
|
||||
return r;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters) {
|
||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto parameterKeys = type->GetParameterKeys();
|
||||
|
||||
auto originalScope = this->_evaluationScope;
|
||||
this->_evaluationScope = function->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++){
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
void Evaluator::EvaluateAssignmentStatement(const BoundAssignmentStatement *statement) {
|
||||
auto value = this->EvaluateExpression(statement->GetExpression());
|
||||
auto key = statement->GetKey();
|
||||
if (key->IsCreation()) {
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else {
|
||||
this->_evaluationScope->SetVariable(key, value);
|
||||
}
|
||||
}
|
||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
this->_hasReturned = false;
|
||||
auto r = this -> _returnValue;
|
||||
this -> _returnValue = nullptr;
|
||||
return r;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
|
||||
auto indexExpression = (BoundIndexExpression*)expression;
|
||||
auto index = this -> EvaluateExpression(indexExpression->GetIndexExpression());
|
||||
auto indexable = this -> EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||
return indexable -> IndexValue(index.get()) -> Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
||||
auto indexExpression = (BoundPeriodIndexExpression*)expression;
|
||||
auto index = indexExpression -> GetIndex().GetHash();
|
||||
auto indexable = this -> EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||
return indexable -> IndexValue(index) -> Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundNumericalTableExpression*)expression;
|
||||
auto valueExpressions = tableExpression->GetExpressions();
|
||||
auto values = new unordered_map<uint32_t, shared_ptr<EvalValue>>(valueExpressions->size());
|
||||
for (int i = 0; i < valueExpressions->size(); i++){
|
||||
auto val = this -> EvaluateExpression(valueExpressions -> at(i));
|
||||
values -> insert({i + 1, val});
|
||||
void Evaluator::EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement *statement) {
|
||||
auto indexExpression = statement->GetIndexExpression();
|
||||
auto value = this->EvaluateExpression(statement->GetValueExpression());
|
||||
auto index = ((BoundIndexExpression *) indexExpression);
|
||||
auto table = this->EvaluateExpression(index->GetIndexableExpression());
|
||||
auto key = this->EvaluateExpression(index->GetIndexExpression());
|
||||
table->SetIndexValue(key.get(), value);
|
||||
}
|
||||
auto valuesPointer = shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>>(values);
|
||||
return make_shared<TableEvalValue>(valuesPointer);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundTableExpression*)expression;
|
||||
auto type = dynamic_pointer_cast<TableScriptType>(tableExpression->GetType());
|
||||
auto declaredVars = type -> GetValues();
|
||||
auto variables = make_shared<unordered_map<uint32_t, shared_ptr<EvalValue>>>(declaredVars->size());
|
||||
for (auto i : *declaredVars){
|
||||
variables->insert({i.first, nullptr});
|
||||
void Evaluator::EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement) {
|
||||
auto type = statement->GetType();
|
||||
auto key = statement->GetKey();
|
||||
auto block = statement->GetBlock();
|
||||
auto value = make_shared<ScriptFunctionEvalValue>(block, this->_evaluationScope, type);
|
||||
if (key->IsCreation()) {
|
||||
this->_evaluationScope->CreateVariable(key, value);
|
||||
} else {
|
||||
this->_evaluationScope->SetVariable(key, value);
|
||||
}
|
||||
}
|
||||
auto evaluator = make_shared<EvaluationScope>(variables.get(), type -> GetLocalVariableCount());
|
||||
auto currentEvaluator = this -> _evaluationScope;
|
||||
this -> _evaluationScope = evaluator;
|
||||
this->EvaluateBlockStatement(tableExpression->GetBlock());
|
||||
this -> _evaluationScope = currentEvaluator;
|
||||
return make_shared<TableEvalValue>(variables);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()){
|
||||
case BoundExpressionKind ::Variable: return this->GetVariable((BoundVariableExpression*)expression);
|
||||
case BoundExpressionKind ::Index: return this -> EvaluateIndexExpression(expression);
|
||||
default: throw;
|
||||
void Evaluator::EvaluateReturnStatement(const BoundReturnStatement *statement) {
|
||||
auto expression = statement->GetExpression();
|
||||
if (expression == nullptr) {
|
||||
this->_hasReturned = true;
|
||||
return;
|
||||
}
|
||||
auto value = this->EvaluateExpression(expression);
|
||||
this->_hasReturned = true;
|
||||
this->_returnValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
void Evaluator::EvaluateConditionalStatement(const BoundConditionalStatement *statement) {
|
||||
auto condition = statement->GetCondition();
|
||||
if (EvaluateBoolExpression(condition)->EvaluateBool()) {
|
||||
this->EvaluateStatement(statement->GetBlock());
|
||||
} else {
|
||||
auto elseStatement = statement->GetElseStatement();
|
||||
if (elseStatement != nullptr) {
|
||||
this->EvaluateStatement(elseStatement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateExpression(const BoundExpression *expression) {
|
||||
auto type = expression->GetType();
|
||||
switch (type->GetClass()) {
|
||||
case TypeClass::Number:
|
||||
return this->EvaluateIntegerExpression(expression);
|
||||
case TypeClass::Bool:
|
||||
return this->EvaluateBoolExpression(expression);
|
||||
case TypeClass::String:
|
||||
return this->EvaluateStringExpression(expression);
|
||||
case TypeClass::Function:
|
||||
return this->EvaluateFunctionExpression(expression);
|
||||
case TypeClass::Nil:
|
||||
return this->EvaluateNilExpression(expression);
|
||||
case TypeClass::Table:
|
||||
return this->EvaluateTableExpression(expression);
|
||||
case TypeClass::UserData:
|
||||
return this->EvaluateUserDataExpression(expression);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::GetVariable(const BoundVariableExpression *expression) {
|
||||
auto variable = this->_evaluationScope->GetVariable(expression->GetKey());
|
||||
if (variable == nullptr) {
|
||||
throw EvaluationException("Variable not found");
|
||||
}
|
||||
return variable->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
return make_shared<IntegerEvalValue>(((BoundLiteralIntegerExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
return make_shared<FloatEvalValue>(((BoundLiteralFloatExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::Unary:
|
||||
return this->EvaluateIntegerUnary((BoundUnaryExpression *) expression);
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateIntegerBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(
|
||||
this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<NumericEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind::LiteralString:
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
case BoundExpressionKind::Bad:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBoolExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
return make_shared<BooleanEvalValue>(((BoundLiteralBoolExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::Unary:
|
||||
return this->EvaluateBooleanUnary((BoundUnaryExpression *) expression);
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateBooleanBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(
|
||||
this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<BooleanEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind::Bad:
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
case BoundExpressionKind::LiteralString:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<StringEvalValue> Evaluator::EvaluateStringExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::LiteralString:
|
||||
return make_shared<StringEvalValue>(((BoundLiteralStringExpression *) expression)->GetValue());
|
||||
case BoundExpressionKind::Binary:
|
||||
return this->EvaluateStringBinary((BoundBinaryExpression *) expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->GetVariable((BoundVariableExpression *) expression));
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluateFunctionCallExpression(expression));
|
||||
case BoundExpressionKind::Index:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluateIndexExpression(expression));
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return dynamic_pointer_cast<StringEvalValue>(this->EvaluatePeriodIndexExpression(expression));
|
||||
|
||||
case BoundExpressionKind::Bad:
|
||||
case BoundExpressionKind::LiteralInteger:
|
||||
case BoundExpressionKind::LiteralFloat:
|
||||
case BoundExpressionKind::LiteralBool:
|
||||
case BoundExpressionKind::Unary:
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
case BoundExpressionKind::Table:
|
||||
throw;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::Variable:
|
||||
return this->GetVariable((BoundVariableExpression *) expression);
|
||||
case BoundExpressionKind::Index:
|
||||
return this->EvaluateIndexExpression(expression);
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return this->EvaluatePeriodIndexExpression(expression);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNilExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateTableExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::FunctionCall:
|
||||
return this->EvaluateFunctionCallExpression(expression);
|
||||
case BoundExpressionKind::Variable:
|
||||
return this->GetVariable((BoundVariableExpression *) expression);
|
||||
case BoundExpressionKind::Index:
|
||||
return this->EvaluateIndexExpression(expression);
|
||||
case BoundExpressionKind::NumericalTable:
|
||||
return this->EvaluateNumericTableExpression(expression);
|
||||
case BoundExpressionKind::Table:
|
||||
return this->EvaluateComplexTableExpression(expression);
|
||||
case BoundExpressionKind::PeriodIndex:
|
||||
return this->EvaluatePeriodIndexExpression(expression);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunctionCallExpression(const BoundExpression *expression) {
|
||||
auto functionCall = (BoundFunctionCallExpression *) expression;
|
||||
auto function = dynamic_pointer_cast<ScriptFunctionEvalValue>(
|
||||
this->EvaluateExpression(functionCall->GetFunctionExpression()));
|
||||
|
||||
auto boundParameters = functionCall->GetParameters();
|
||||
auto parameters = vector<shared_ptr<EvalValue>>(boundParameters->size());
|
||||
for (int i = 0; i < boundParameters->size(); i++) {
|
||||
parameters[i] = this->EvaluateExpression(boundParameters->at(i));
|
||||
}
|
||||
|
||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto parameterKeys = type->GetParameterKeys();
|
||||
auto originalScope = this->_evaluationScope;
|
||||
this->_evaluationScope = function->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
}
|
||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
|
||||
this->_hasReturned = false;
|
||||
auto r = this->_returnValue;
|
||||
this->_returnValue = nullptr;
|
||||
return r;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters) {
|
||||
auto type = std::dynamic_pointer_cast<FunctionScriptType>(function->GetType());
|
||||
auto parameterTypes = type->GetParameterTypes();
|
||||
auto parameterKeys = type->GetParameterKeys();
|
||||
|
||||
auto originalScope = this->_evaluationScope;
|
||||
this->_evaluationScope = function->GetScope();
|
||||
|
||||
for (int i = 0; i < parameterTypes.size() && i < parameterKeys.size() && i < parameters.size(); i++) {
|
||||
auto parameter = parameters[i];
|
||||
auto key = parameterKeys.at(i);
|
||||
this->_evaluationScope->CreateVariable(key.get(), parameter->Clone());
|
||||
}
|
||||
this->EvaluateBlockStatement(function->GetInnerBlock().get());
|
||||
this->_evaluationScope = originalScope;
|
||||
this->_hasReturned = false;
|
||||
auto r = this->_returnValue;
|
||||
this->_returnValue = nullptr;
|
||||
return r;
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateIndexExpression(const BoundExpression *expression) {
|
||||
auto indexExpression = (BoundIndexExpression *) expression;
|
||||
auto index = this->EvaluateExpression(indexExpression->GetIndexExpression());
|
||||
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||
return indexable->IndexValue(index.get())->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluatePeriodIndexExpression(const BoundExpression *expression) {
|
||||
auto indexExpression = (BoundPeriodIndexExpression *) expression;
|
||||
auto index = indexExpression->GetIndex().GetHash();
|
||||
auto indexable = this->EvaluateExpression(indexExpression->GetIndexableExpression());
|
||||
return indexable->IndexValue(index)->Clone();
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateNumericTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundNumericalTableExpression *) expression;
|
||||
auto valueExpressions = tableExpression->GetExpressions();
|
||||
auto values = new unordered_map<uint32_t, shared_ptr<EvalValue>>(valueExpressions->size());
|
||||
for (int i = 0; i < valueExpressions->size(); i++) {
|
||||
auto val = this->EvaluateExpression(valueExpressions->at(i));
|
||||
values->insert({i + 1, val});
|
||||
}
|
||||
auto valuesPointer = shared_ptr<unordered_map<uint32_t, shared_ptr<EvalValue>>>(values);
|
||||
return make_shared<TableEvalValue>(valuesPointer);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateComplexTableExpression(const BoundExpression *expression) {
|
||||
auto tableExpression = (BoundTableExpression *) expression;
|
||||
auto type = dynamic_pointer_cast<TableScriptType>(tableExpression->GetType());
|
||||
auto declaredVars = type->GetValues();
|
||||
auto variables = make_shared<unordered_map<uint32_t, shared_ptr<EvalValue>>>(declaredVars->size());
|
||||
for (auto i : *declaredVars) {
|
||||
variables->insert({i.first, nullptr});
|
||||
}
|
||||
auto evaluator = make_shared<EvaluationScope>(variables.get(), type->GetLocalVariableCount());
|
||||
auto currentEvaluator = this->_evaluationScope;
|
||||
this->_evaluationScope = evaluator;
|
||||
this->EvaluateBlockStatement(tableExpression->GetBlock());
|
||||
this->_evaluationScope = currentEvaluator;
|
||||
return make_shared<TableEvalValue>(variables);
|
||||
}
|
||||
|
||||
const shared_ptr<EvalValue> Evaluator::EvaluateUserDataExpression(const BoundExpression *expression) {
|
||||
switch (expression->GetKind()) {
|
||||
case BoundExpressionKind::Variable:
|
||||
return this->GetVariable((BoundVariableExpression *) expression);
|
||||
case BoundExpressionKind::Index:
|
||||
return this->EvaluateIndexExpression(expression);
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <string>
|
||||
#include "../Binder/BoundStatements/BoundStatement.hpp"
|
||||
#include "../Script.hpp"
|
||||
#include "EvalValues/EvalValue.hpp"
|
||||
#include "EvalValues/NumericEvalValue.hpp"
|
||||
#include "EvalValues/StringEvalValue.hpp"
|
||||
@@ -14,62 +13,65 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Evaluator {
|
||||
shared_ptr<EvalValue> _returnValue;
|
||||
bool _hasReturned;
|
||||
shared_ptr<EvalValue> _lastValue;
|
||||
namespace Porygon::Evaluation{
|
||||
class Evaluator {
|
||||
shared_ptr<EvalValue> _returnValue;
|
||||
unordered_map<uint32_t, shared_ptr<EvalValue>>* _scriptVariables;
|
||||
bool _hasReturned;
|
||||
shared_ptr<EvalValue> _lastValue;
|
||||
|
||||
Script* _scriptData;
|
||||
shared_ptr<EvaluationScope> _evaluationScope;
|
||||
//Porygon::Script* _scriptData;
|
||||
shared_ptr<EvaluationScope> _evaluationScope;
|
||||
|
||||
void EvaluateStatement(const BoundStatement* statement);
|
||||
void EvaluateBlockStatement(const BoundBlockStatement *statement);
|
||||
void EvaluateExpressionStatement(const BoundExpressionStatement* statement);
|
||||
void EvaluateAssignmentStatement(const BoundAssignmentStatement* statement);
|
||||
void EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement* statement);
|
||||
void EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement);
|
||||
void EvaluateReturnStatement(const BoundReturnStatement *statement);
|
||||
void EvaluateConditionalStatement(const BoundConditionalStatement *statement);
|
||||
void EvaluateStatement(const BoundStatement* statement);
|
||||
void EvaluateBlockStatement(const BoundBlockStatement *statement);
|
||||
void EvaluateExpressionStatement(const BoundExpressionStatement* statement);
|
||||
void EvaluateAssignmentStatement(const BoundAssignmentStatement* statement);
|
||||
void EvaluateIndexAssignmentStatement(const BoundIndexAssignmentStatement* statement);
|
||||
void EvaluateFunctionDeclarationStatement(const BoundFunctionDeclarationStatement *statement);
|
||||
void EvaluateReturnStatement(const BoundReturnStatement *statement);
|
||||
void EvaluateConditionalStatement(const BoundConditionalStatement *statement);
|
||||
|
||||
const shared_ptr<EvalValue> EvaluateExpression(const BoundExpression *expression);
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerExpression(const BoundExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBoolExpression(const BoundExpression *expression);
|
||||
const shared_ptr<StringEvalValue> EvaluateStringExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateFunctionExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateNilExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateTableExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateExpression(const BoundExpression *expression);
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerExpression(const BoundExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBoolExpression(const BoundExpression *expression);
|
||||
const shared_ptr<StringEvalValue> EvaluateStringExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateFunctionExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateNilExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateTableExpression(const BoundExpression *expression);
|
||||
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerBinary(const BoundBinaryExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBooleanBinary(const BoundBinaryExpression *expression);
|
||||
const shared_ptr<StringEvalValue> EvaluateStringBinary(const BoundBinaryExpression *expression);
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerBinary(const BoundBinaryExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBooleanBinary(const BoundBinaryExpression *expression);
|
||||
const shared_ptr<StringEvalValue> EvaluateStringBinary(const BoundBinaryExpression *expression);
|
||||
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerUnary(const BoundUnaryExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBooleanUnary(const BoundUnaryExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateFunctionCallExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateIndexExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluatePeriodIndexExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateNumericTableExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateComplexTableExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateUserDataExpression(const BoundExpression *expression);
|
||||
const shared_ptr<NumericEvalValue> EvaluateIntegerUnary(const BoundUnaryExpression *expression);
|
||||
const shared_ptr<BooleanEvalValue> EvaluateBooleanUnary(const BoundUnaryExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateFunctionCallExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateIndexExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluatePeriodIndexExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateNumericTableExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateComplexTableExpression(const BoundExpression *expression);
|
||||
const shared_ptr<EvalValue> EvaluateUserDataExpression(const BoundExpression *expression);
|
||||
|
||||
const shared_ptr<EvalValue> GetVariable(const BoundVariableExpression *expression);
|
||||
public:
|
||||
explicit Evaluator(Script* script){
|
||||
_scriptData = script;
|
||||
_hasReturned = false;
|
||||
_returnValue = nullptr;
|
||||
_evaluationScope = nullptr;
|
||||
}
|
||||
const shared_ptr<EvalValue> GetVariable(const BoundVariableExpression *expression);
|
||||
public:
|
||||
explicit Evaluator(unordered_map<uint32_t, shared_ptr<EvalValue>>* scriptVariables){
|
||||
_scriptVariables = scriptVariables;
|
||||
_hasReturned = false;
|
||||
_returnValue = nullptr;
|
||||
_evaluationScope = nullptr;
|
||||
}
|
||||
|
||||
EvalValue* Evaluate(const BoundScriptStatement* statement);
|
||||
const shared_ptr<EvalValue> EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters);
|
||||
EvalValue* Evaluate(const BoundScriptStatement* statement);
|
||||
const shared_ptr<EvalValue> EvaluateFunction(const ScriptFunctionEvalValue *function,
|
||||
const vector<EvalValue *> ¶meters);
|
||||
|
||||
EvalValue* GetLastValue(){
|
||||
return _lastValue.get();
|
||||
}
|
||||
EvalValue* GetLastValue(){
|
||||
return _lastValue.get();
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,33 +4,33 @@
|
||||
#include "EvaluationException.hpp"
|
||||
#include "../Script.hpp"
|
||||
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(const BoundUnaryExpression *expression) {
|
||||
switch (expression->GetOperation()){
|
||||
case BoundUnaryOperation::Negation:
|
||||
{
|
||||
auto operandValue = EvaluateIntegerExpression(expression->GetOperand());
|
||||
if (operandValue->IsFloat()){
|
||||
double f = operandValue->EvaluateFloat();
|
||||
return make_shared<FloatEvalValue>(-f);
|
||||
} else{
|
||||
long l = operandValue->EvaluateInteger();
|
||||
return make_shared<IntegerEvalValue>(-l);
|
||||
namespace Porygon::Evaluation {
|
||||
const shared_ptr<NumericEvalValue> Evaluator::EvaluateIntegerUnary(const BoundUnaryExpression *expression) {
|
||||
switch (expression->GetOperation()) {
|
||||
case BoundUnaryOperation::Negation: {
|
||||
auto operandValue = EvaluateIntegerExpression(expression->GetOperand());
|
||||
if (operandValue->IsFloat()) {
|
||||
double f = operandValue->EvaluateFloat();
|
||||
return make_shared<FloatEvalValue>(-f);
|
||||
} else {
|
||||
long l = operandValue->EvaluateInteger();
|
||||
return make_shared<IntegerEvalValue>(-l);
|
||||
}
|
||||
}
|
||||
case BoundUnaryOperation::LogicalNegation:
|
||||
throw;
|
||||
}
|
||||
case BoundUnaryOperation::LogicalNegation:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanUnary(const BoundUnaryExpression *expression) {
|
||||
switch (expression->GetOperation()){
|
||||
case BoundUnaryOperation::LogicalNegation:
|
||||
{
|
||||
auto val = EvaluateBoolExpression(expression->GetOperand());
|
||||
bool b = val->EvaluateBool();
|
||||
return make_shared<BooleanEvalValue>(!b);
|
||||
const shared_ptr<BooleanEvalValue> Evaluator::EvaluateBooleanUnary(const BoundUnaryExpression *expression) {
|
||||
switch (expression->GetOperation()) {
|
||||
case BoundUnaryOperation::LogicalNegation: {
|
||||
auto val = EvaluateBoolExpression(expression->GetOperand());
|
||||
bool b = val->EvaluateBool();
|
||||
return make_shared<BooleanEvalValue>(!b);
|
||||
}
|
||||
case BoundUnaryOperation::Negation:
|
||||
throw;
|
||||
}
|
||||
case BoundUnaryOperation::Negation:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user