blob: 4c49791922200ecdeca5a59eb31286dfca59a8b1 [file]
/*
* Copyright 2020 The casbin Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <cvaluate/EvaluationStage.h>
#include <cvaluate/Exception.h>
namespace Cvaluate {
TokenAvaiableData AddStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) || IsString(right)) {
return GetTokenValueString(left) + GetTokenValueString(right);
}
return GetTokenValueNumeric(left) + GetTokenValueNumeric(right);
}
TokenAvaiableData SubtractStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return GetTokenValueNumeric(left) - GetTokenValueNumeric(right);
}
TokenAvaiableData MultiplyStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return GetTokenValueNumeric(left) * GetTokenValueNumeric(right);
}
TokenAvaiableData DivideStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return GetTokenValueNumeric(left) / GetTokenValueNumeric(right);
}
TokenAvaiableData ExponentStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return (float)pow(GetTokenValueNumeric(left), GetTokenValueNumeric(right));
}
TokenAvaiableData ModulusStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return (float)((int)GetTokenValueNumeric(left) % (int)GetTokenValueNumeric(right));
}
TokenAvaiableData GteStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) >= GetTokenValueString(right);
}
return GetTokenValueNumeric(left) >= GetTokenValueNumeric(right);
}
TokenAvaiableData GtStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) > GetTokenValueString(right);
}
return GetTokenValueNumeric(left) > GetTokenValueNumeric(right);
}
TokenAvaiableData LteStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) <= GetTokenValueString(right);
}
return GetTokenValueNumeric(left) <= GetTokenValueNumeric(right);
}
TokenAvaiableData LtStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) < GetTokenValueString(right);
}
return GetTokenValueNumeric(left) < GetTokenValueNumeric(right);
}
TokenAvaiableData EqualStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) == GetTokenValueString(right);
}
if (IsNumeric(left) && IsNumeric(right)) {
return GetTokenValueNumeric(left) == GetTokenValueNumeric(right);
}
if (IsBool(left) && IsBool(right)) {
return GetTokenValueBool(left) == GetTokenValueBool(right);
}
return left == right;
}
TokenAvaiableData NotEqualStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
if (IsString(left) && IsString(right)) {
return GetTokenValueString(left) != GetTokenValueString(right);
}
if (IsNumeric(left) && IsNumeric(right)) {
return GetTokenValueNumeric(left) != GetTokenValueNumeric(right);
}
if (IsBool(left) && IsBool(right)) {
return GetTokenValueBool(left) != GetTokenValueBool(right);
}
return left != right;
}
TokenAvaiableData AndStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return GetTokenValueBool(left) && GetTokenValueBool(right);
}
TokenAvaiableData OrStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return GetTokenValueBool(left) || GetTokenValueBool(right);
}
TokenAvaiableData NegateStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return -GetTokenValueNumeric(right);
}
TokenAvaiableData InvertStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return !GetTokenValueBool(right);
}
TokenAvaiableData BitwiseNotStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("BitwiseNotStage Not Implement");
}
TokenAvaiableData TernaryIfStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("TernaryIfStage Not Implement");
}
TokenAvaiableData TernaryElseStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("TernaryElseStage Not Implement");
}
TokenAvaiableData RegexStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("RegexStage Not Implement");
}
TokenAvaiableData NotRegexStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("NotRegexStage Not Implement");
}
TokenAvaiableData BitwiseOrStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("BitwiseOrStage Not Implement");
}
TokenAvaiableData BitwiseAndStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("BitwiseAndStage Not Implement");
}
TokenAvaiableData BitwiseXORStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("BitwiseXORStage Not Implement");
}
TokenAvaiableData LeftShiftStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("LeftShiftStage Not Implement");
}
TokenAvaiableData RightShiftStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("RightShiftStage Not Implement");
}
TokenAvaiableData NoopStageRight(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
return right;
}
TokenAvaiableData InStage(TokenAvaiableData, TokenAvaiableData, Parameters) {
throw CvaluateException("InStage Not Implement");
}
TokenAvaiableData SeparatorStage(TokenAvaiableData left, TokenAvaiableData right, Parameters) {
TokenAvaiableData ans;
if (left.is_object()) {
ans = left;
ans.push_back(right);
} else {
ans.push_back(left);
ans.push_back(right);
}
return ans;
}
EvaluationOperator MakeParameterStage(std::string parameter_name) {
auto func = [] (TokenAvaiableData value, TokenAvaiableData, Parameters parameter, std::string name) -> TokenAvaiableData {
if(parameter.find(name) == parameter.end()) {
throw CvaluateException("Cant' find varibale name in parameter");
} else {
return parameter[name];
}
};
auto ret = std::bind(func, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, parameter_name);
return ret;
}
EvaluationOperator MakeLiteralStage(TokenAvaiableData value) {
auto func = [] (TokenAvaiableData value, TokenAvaiableData, Parameters) -> TokenAvaiableData {
return value;
};
auto ret = std::bind(func, value, std::placeholders::_2, std::placeholders::_3);
return ret;
}
EvaluationOperator MakeFunctionStage(ExpressionFunction function) {
auto func = [] (TokenAvaiableData, TokenAvaiableData right, Parameters, ExpressionFunction function) -> TokenAvaiableData {
return function(right);
};
auto ret = std::bind(func, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, function);
return ret;
}
EvaluationOperator MakeAccessorStage(TokenAvaiableData value) {
auto func = [] (TokenAvaiableData, TokenAvaiableData, Parameters parameters, TokenAvaiableData& data) -> TokenAvaiableData {
if (data.empty()) {
throw CvaluateException("Cant' find varibale name in given strings");
}
std::vector<std::string> name_strings = data;
auto variable_name = name_strings[0];
if (parameters.find(variable_name) == parameters.end()) {
throw CvaluateException("Cant' find varibale name in parameters");
}
nlohmann::json j = parameters[variable_name];
for (size_t i = 1; i < name_strings.size(); i++) {
auto field_name = name_strings[i];
j = j[field_name];
}
return j;
};
auto ret = std::bind(func, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, value);
return ret;
}
bool IsString(TokenAvaiableData& value) {
return value.is_string();
}
bool IsBool(TokenAvaiableData& value) {
return value.is_boolean();
}
bool IsNumeric(TokenAvaiableData& value) {
return IsFloat(value) || IsInt(value);
}
bool IsFloat(TokenAvaiableData& value) {
return value.is_number_float();
}
bool IsInt(TokenAvaiableData& value) {
return value.is_number_integer();
}
bool IsArray(TokenAvaiableData& value) {
return value.is_object();
}
bool AdditionTypeCheck(TokenAvaiableData& left, TokenAvaiableData& right) {
if (IsNumeric(left) && IsNumeric(right)) {
return true;
}
if (!IsString(left) && !IsString(right)) {
return false;
}
return true;
}
bool ComparatorTypeCheck(TokenAvaiableData& left, TokenAvaiableData& right) {
if (IsNumeric(left) && IsNumeric(right)) {
return true;
}
if (IsString(left) && IsString(right)) {
return true;
}
return false;
}
bool IsRegexOrString(TokenAvaiableData& value) {
return IsString(value);
}
void EvaluationStage::SwapWith(std::shared_ptr<EvaluationStage> other) {
auto temp = *other;
other->SetToNonStage(*this);
this->SetToNonStage(temp);
}
void EvaluationStage::SetToNonStage(EvaluationStage other) {
this->symbol_ = other.symbol_;
this->operator_ = other.operator_;
this->left_type_check_ = other.left_type_check_;
this->right_type_check_ = other.right_type_check_;
this->type_check_ = other.type_check_;
}
} // Cvaluate