Fully implements math library
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2019-08-17 18:29:02 +02:00
parent 5e96250d96
commit 7675af62de
6 changed files with 558 additions and 32 deletions

View File

@@ -68,6 +68,11 @@ namespace Porygon::Evaluation {
return _value;
}
[[nodiscard]]
inline double EvaluateFloat() const final {
return static_cast<double>(_value);
}
[[nodiscard]]
inline std::u16string EvaluateString() const final{
return Utilities::StringUtils::IntToString(_value);
@@ -122,6 +127,11 @@ namespace Porygon::Evaluation {
return _value;
}
[[nodiscard]]
inline long EvaluateInteger() const final {
return static_cast<long>(_value);
}
[[nodiscard]]
inline std::u16string EvaluateString() const final{
return Utilities::StringUtils::FloatToString(_value);

View File

@@ -85,6 +85,12 @@ namespace Porygon {
return this;
}
const GenericFunctionScriptType* RegisterFunctionOption (size_t index, GenericFunctionOption * opt) const{
opt->SetOption(index);
_options->push_back(opt);
return this;
}
GenericFunctionOption* GetFunctionOption(const vector<shared_ptr<const ScriptType>>& parameters) const{
for (auto o: *_options){
if (o->IsValid(parameters)){

View File

@@ -0,0 +1,9 @@
#include "MathLibrary.hpp"
namespace Porygon::StandardLibraries{
using namespace Porygon::Evaluation;
const EvalValue* MathLibrary::_huge = new FloatEvalValue(DBL_MAX);
const EvalValue* MathLibrary::_maxInteger = new IntegerEvalValue(INT64_MAX);
const EvalValue* MathLibrary::_minInteger = new IntegerEvalValue(INT64_MIN);
const EvalValue* MathLibrary::_pi = new FloatEvalValue(M_PI);
}

View File

@@ -2,7 +2,8 @@
#define PORYGONLANG_MATHLIBRARY_HPP
#include <utility>
#include <cmath>
#include <cfloat>
#include "../Evaluator/EvalValues/EvalValue.hpp"
#include "../Evaluator/EvalValues/NumericEvalValue.hpp"
@@ -23,6 +24,7 @@ namespace Porygon::StandardLibraries {
#define FLOAT_TYPE new NumericScriptType(true, true)
#define INTEGER_TYPE new NumericScriptType(true, false)
#define BOOL_TYPE new ScriptType(TypeClass::Bool)
#define FUNCTION(fieldName) \
[](void* obj) -> const Porygon::Evaluation::EvalValue* { \
auto t = new Porygon::Evaluation::GenericFunctionEvalValue(make_shared<GenericFunctionScriptType>(), \
@@ -41,6 +43,108 @@ namespace Porygon::StandardLibraries {
}
}
static const EvalValue* _acos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::acos(parameter->EvaluateFloat()));
}
static const EvalValue* _asin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::asin(parameter->EvaluateFloat()));
}
static const EvalValue* _atan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
if (parameterCount == 1){
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::atan(parameter->EvaluateFloat()));
}
else{
auto parameter1 = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto parameter2 = dynamic_cast<const NumericEvalValue*>(parameters[1]);
return new FloatEvalValue(std::atan2(parameter1->EvaluateFloat(), parameter2->EvaluateFloat()));
}
}
static const EvalValue* _ceil(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new IntegerEvalValue(std::ceil(f));
}
static const EvalValue* _cos(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new FloatEvalValue(std::cos(f));
}
static const EvalValue* _deg(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new FloatEvalValue(f * 180 / M_PI);
}
static const EvalValue* _exp(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new FloatEvalValue(std::exp(f));
}
static const EvalValue* _floor(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new IntegerEvalValue(std::floor(f));
}
static const EvalValue* _fmod(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
auto f2 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
return new FloatEvalValue(std::fmod(f1, f2));
}
static const EvalValue* _huge;
static const EvalValue* _log(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount){
if (parameterCount == 1){
auto f = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
return new FloatEvalValue(std::log(f));
}
else{
auto f1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateFloat();
auto f2 = dynamic_cast<const NumericEvalValue*>(parameters[1])->EvaluateFloat();
return new FloatEvalValue(std::log(f2) / std::log(f1));
}
}
static const EvalValue* _maxInteger;
static const EvalValue* _minInteger;
static const EvalValue* _pi;
static const EvalValue* _rad(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
auto f = parameter->EvaluateFloat();
return new FloatEvalValue(M_PI *(f / 180));
}
static const EvalValue* _sin(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::sin(parameter->EvaluateFloat()));
}
static const EvalValue* _sqrt(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::sqrt(parameter->EvaluateFloat()));
}
static const EvalValue* _tan(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter = dynamic_cast<const NumericEvalValue*>(parameters[0]);
return new FloatEvalValue(std::tan(parameter->EvaluateFloat()));
}
static const EvalValue* _ult(void*, const ScriptOptions*, const Evaluation::EvalValue* parameters[], int parameterCount) {
auto parameter1 = dynamic_cast<const NumericEvalValue*>(parameters[0])->EvaluateInteger();
auto parameter2 = dynamic_cast<const NumericEvalValue*>(parameters[1])->EvaluateInteger();
return new BooleanEvalValue(parameter1 < parameter2);
}
static UserData::UserDataFunctionOption* CreateFunctionOption(ScriptType* returnType, std::vector<ScriptType*> params){
return UserData::UserDataFunctionOption::FromRawPointers(returnType, std::move(params));
}
@@ -49,13 +153,167 @@ namespace Porygon::StandardLibraries {
public:
static UserData::UserData* CreateUserData(){
return new UserData::UserData({
{HashedString::ConstHash("abs"),
{
HashedString::ConstHash("abs"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(CreateFunctionOption(INTEGER_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_abs))}
});
->RegisterFunctionOption(0, CreateFunctionOption(INTEGER_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_abs))
},
{
HashedString::ConstHash("acos"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_acos))
},
{
HashedString::ConstHash("asin"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_asin))
},
{
HashedString::ConstHash("atan"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, FLOAT_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, FLOAT_TYPE}))
, FUNCTION(_atan))
},
{
HashedString::ConstHash("ceil"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
, FUNCTION(_ceil))
},
{
HashedString::ConstHash("cos"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_cos))
},
{
HashedString::ConstHash("deg"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_deg))
},
{
HashedString::ConstHash("exp"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_exp))
},
{
HashedString::ConstHash("floor"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
, FUNCTION(_floor))
},
{
HashedString::ConstHash("fmod"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, FLOAT_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, FLOAT_TYPE}))
, FUNCTION(_fmod))
},
{
HashedString::ConstHash("huge"),
new UserData::UserDataField(
FLOAT_TYPE
, [](void* obj) -> const Porygon::Evaluation::EvalValue* {return _huge;}, nullptr)
},
{
HashedString::ConstHash("log"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE, FLOAT_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE, FLOAT_TYPE}))
, FUNCTION(_log))
},
{
HashedString::ConstHash("maxinteger"),
new UserData::UserDataField(
INTEGER_TYPE
, [](void* obj) -> const Porygon::Evaluation::EvalValue* {return _maxInteger;}, nullptr)
},
{
HashedString::ConstHash("mininteger"),
new UserData::UserDataField(
INTEGER_TYPE
, [](void* obj) -> const Porygon::Evaluation::EvalValue* {return _minInteger;}, nullptr)
},
{
HashedString::ConstHash("pi"),
new UserData::UserDataField(
FLOAT_TYPE
, [](void* obj) -> const Porygon::Evaluation::EvalValue* {return _pi;}, nullptr)
},
{
HashedString::ConstHash("rad"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_rad))
},
{
HashedString::ConstHash("sin"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_sin))
},
{
HashedString::ConstHash("sqrt"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_sqrt))
},
{
HashedString::ConstHash("tan"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {INTEGER_TYPE}))
->RegisterFunctionOption(0, CreateFunctionOption(FLOAT_TYPE, {FLOAT_TYPE}))
, FUNCTION(_tan))
},
{
HashedString::ConstHash("ult"),
new UserData::UserDataField(
(new GenericFunctionScriptType())
->RegisterFunctionOption(0, CreateFunctionOption(BOOL_TYPE, {INTEGER_TYPE, INTEGER_TYPE}))
, FUNCTION(_ult))
},
});
}
};
}