Implements exponent and modulus operators
This commit is contained in:
parent
de39464b33
commit
30d82085cc
|
@ -540,6 +540,31 @@ namespace Porygon::Binder {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case BinaryOperatorKind::Exponent:
|
||||
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Exponent,
|
||||
NumericScriptType::AwareFloat,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
break;
|
||||
case BinaryOperatorKind::Modulus:
|
||||
if (boundLeftType->GetClass() == TypeClass::Number && boundRightType->GetClass() == TypeClass::Number) {
|
||||
auto leftNumeric = std::dynamic_pointer_cast<const NumericScriptType>(boundLeftType);
|
||||
auto rightNumeric = std::dynamic_pointer_cast<const NumericScriptType>(boundRightType);
|
||||
if (leftNumeric->IsAwareOfFloat() && rightNumeric->IsAwareOfFloat()) {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight,
|
||||
BoundBinaryOperation::Modulus,
|
||||
NumericScriptType::ResolveType(true,
|
||||
leftNumeric->IsFloat() ||
|
||||
rightNumeric->IsFloat()),
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
} else {
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Modulus,
|
||||
NumericScriptType::Unaware,
|
||||
expression->GetStartPosition(), expression->GetLength());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BinaryOperatorKind::Equality:
|
||||
return new BoundBinaryExpression(boundLeft, boundRight, BoundBinaryOperation::Equality,
|
||||
ScriptType::BoolType,
|
||||
|
|
|
@ -279,11 +279,13 @@ namespace Porygon::Binder {
|
|||
|
||||
static std::string GetOperationString(BoundBinaryOperation op){
|
||||
switch (op){
|
||||
|
||||
case BoundBinaryOperation::Addition: return "addition";
|
||||
case BoundBinaryOperation::Subtraction: return "subtraction";
|
||||
case BoundBinaryOperation::Multiplication: return "multiplication";
|
||||
case BoundBinaryOperation::Division: return "division";
|
||||
case BoundBinaryOperation::Modulus: return "modulus";
|
||||
case BoundBinaryOperation::Exponent: return "exponent";
|
||||
|
||||
case BoundBinaryOperation::Equality: return "equality";
|
||||
case BoundBinaryOperation::Inequality: return "inequality";
|
||||
case BoundBinaryOperation::LessThan: return "lessThan";
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace Porygon::Binder {
|
|||
Subtraction = 1,
|
||||
Multiplication = 2,
|
||||
Division = 3,
|
||||
Modulus = 13,
|
||||
Exponent = 14,
|
||||
Equality = 4,
|
||||
Inequality = 5,
|
||||
LessThan = 6,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include "NumericEvalValue.hpp"
|
||||
#include <cmath>
|
||||
|
||||
namespace Porygon::Evaluation {
|
||||
EvalValue *NumericEvalValue::BinaryOperation(Binder::BoundBinaryOperation operation, const EvalValue *b) const {
|
||||
|
@ -14,6 +15,8 @@ namespace Porygon::Evaluation {
|
|||
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
||||
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
||||
case Binder::BoundBinaryOperation::Exponent: return new NumericEvalValue(std::pow(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Modulus: return new NumericEvalValue(std::fmod(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
||||
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
||||
|
@ -31,6 +34,8 @@ namespace Porygon::Evaluation {
|
|||
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
||||
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
||||
case Binder::BoundBinaryOperation::Exponent: return new NumericEvalValue(std::pow(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Modulus: return new NumericEvalValue(std::fmod(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
||||
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
||||
|
@ -44,13 +49,15 @@ namespace Porygon::Evaluation {
|
|||
else{
|
||||
int64_t v1 = std::get<int64_t >(_intValue);
|
||||
if (right->_isFloat){
|
||||
double v2 =std::get<double>(right->_floatValue);;
|
||||
double v2 =std::get<double>(right->_floatValue);
|
||||
switch (operation){
|
||||
|
||||
case Binder::BoundBinaryOperation::Addition: return new NumericEvalValue(v1 + v2);
|
||||
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
||||
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
||||
case Binder::BoundBinaryOperation::Exponent: return new NumericEvalValue(std::pow(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Modulus: return new NumericEvalValue(std::fmod(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
||||
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
||||
|
@ -67,6 +74,8 @@ namespace Porygon::Evaluation {
|
|||
case Binder::BoundBinaryOperation::Subtraction: return new NumericEvalValue(v1 - v2);
|
||||
case Binder::BoundBinaryOperation::Multiplication: return new NumericEvalValue(v1 * v2);
|
||||
case Binder::BoundBinaryOperation::Division: return new NumericEvalValue(v1 / v2);
|
||||
case Binder::BoundBinaryOperation::Exponent: return new NumericEvalValue(std::pow(v1, v2));
|
||||
case Binder::BoundBinaryOperation::Modulus: return new NumericEvalValue(v1 % v2);
|
||||
case Binder::BoundBinaryOperation::Equality: return new BooleanEvalValue(v1 == v2);
|
||||
case Binder::BoundBinaryOperation::Inequality: return new BooleanEvalValue(v1 != v2);
|
||||
case Binder::BoundBinaryOperation::LessThan: return new BooleanEvalValue(v1 < v2);
|
||||
|
@ -101,7 +110,7 @@ namespace Porygon::Evaluation {
|
|||
size_t NumericEvalValue::GetHashCode() const {
|
||||
if (_isFloat)
|
||||
return std::get<double >(_floatValue);
|
||||
return std::get<int64_t >(_intValue);;
|
||||
return std::get<int64_t >(_intValue);
|
||||
}
|
||||
|
||||
bool NumericEvalValue::operator==(const EvalValue *b) const {
|
||||
|
@ -117,7 +126,7 @@ namespace Porygon::Evaluation {
|
|||
}
|
||||
|
||||
int64_t NumericEvalValue::EvaluateInteger() const {
|
||||
return std::get<int64_t >(_intValue);;
|
||||
return std::get<int64_t >(_intValue);
|
||||
}
|
||||
|
||||
double NumericEvalValue::EvaluateFloat() const {
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace Porygon::Parser {
|
|||
Subtraction,
|
||||
Multiplication,
|
||||
Division,
|
||||
Exponent,
|
||||
Modulus,
|
||||
|
||||
// Equality
|
||||
Equality,
|
||||
|
|
|
@ -111,6 +111,10 @@ namespace Porygon::Parser {
|
|||
return new SimpleToken(TokenKind::BadToken, this->_position - 1, 1);
|
||||
case '#':
|
||||
return new SimpleToken(TokenKind::HashToken, this->_position - 1, 1);
|
||||
case '^':
|
||||
return new SimpleToken(TokenKind::RoofToken, this->_position - 1, 1);
|
||||
case '%':
|
||||
return new SimpleToken(TokenKind::PercentToken, this->_position - 1, 1);
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
|
|
|
@ -414,6 +414,10 @@ namespace Porygon::Parser {
|
|||
return BinaryOperatorKind::Multiplication;
|
||||
case TokenKind::SlashToken:
|
||||
return BinaryOperatorKind::Division;
|
||||
case TokenKind::RoofToken:
|
||||
return BinaryOperatorKind ::Exponent;
|
||||
case TokenKind::PercentToken:
|
||||
return BinaryOperatorKind ::Modulus;
|
||||
|
||||
// Equality operators
|
||||
case TokenKind::EqualityToken:
|
||||
|
@ -450,6 +454,11 @@ namespace Porygon::Parser {
|
|||
return OperatorPrecedence::Multiplication;
|
||||
case TokenKind::SlashToken:
|
||||
return OperatorPrecedence::Multiplication;
|
||||
case TokenKind::RoofToken:
|
||||
return OperatorPrecedence ::Multiplication;
|
||||
case TokenKind::PercentToken:
|
||||
return OperatorPrecedence ::Multiplication;
|
||||
|
||||
|
||||
// Equality
|
||||
case TokenKind::EqualityToken:
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace Porygon::Parser {
|
|||
Greater,
|
||||
GreaterEquals,
|
||||
HashToken,
|
||||
RoofToken,
|
||||
PercentToken,
|
||||
|
||||
OpenParenthesis,
|
||||
CloseParenthesis,
|
||||
|
|
|
@ -47,6 +47,22 @@ TEST_CASE( "Integer Division", "[integration]" ) {
|
|||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Integer Exponent", "[integration]" ) {
|
||||
auto script = Script::Create("return 9 ^ 3");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto result = script->Evaluate();
|
||||
REQUIRE(result->EvaluateFloat() == 729);
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Integer Modulus", "[integration]" ) {
|
||||
auto script = Script::Create("return 9 % 2");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto result = script->Evaluate();
|
||||
REQUIRE(result->EvaluateInteger() == 1);
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Float Addition", "[integration]" ) {
|
||||
auto script = Script::Create("1.2 + 5.34");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
|
@ -75,4 +91,21 @@ TEST_CASE( "Float Division", "[integration]" ) {
|
|||
REQUIRE(result->EvaluateFloat() == Approx(10.7305524239));
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Float Exponent", "[integration]" ) {
|
||||
auto script = Script::Create("95.18 ^ 2.0");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto result = script->Evaluate();
|
||||
REQUIRE(result->EvaluateFloat() == Approx(9059.2324));
|
||||
delete script;
|
||||
}
|
||||
|
||||
TEST_CASE( "Float Modulus", "[integration]" ) {
|
||||
auto script = Script::Create("return 9.2 % 2.0");
|
||||
REQUIRE(!script->Diagnostics -> HasErrors());
|
||||
auto result = script->Evaluate();
|
||||
REQUIRE(result->EvaluateFloat() == Approx(1.2));
|
||||
delete script;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue