Better handling of casting
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
0fde3d46df
commit
1d72e2eccd
|
@ -590,7 +590,7 @@ namespace Porygon::Binder {
|
||||||
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
|
boundParameters[i] = this -> BindExpression(givenParameters->at(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto functionOption = functionType->GetFunctionOption(this->_scriptData->Diagnostics, boundParameters);
|
auto functionOption = functionType->GetFunctionOption(this->_scriptData->Diagnostics, &boundParameters);
|
||||||
if (functionOption == nullptr){
|
if (functionOption == nullptr){
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||||
expression->GetStartPosition(),
|
expression->GetStartPosition(),
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace Porygon::Binder {
|
||||||
NumericalTable,
|
NumericalTable,
|
||||||
Table,
|
Table,
|
||||||
Require,
|
Require,
|
||||||
|
ImplicitCast,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoundExpression {
|
class BoundExpression {
|
||||||
|
@ -332,6 +333,28 @@ namespace Porygon::Binder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BoundImplicitCastExpression : public BoundExpression {
|
||||||
|
const BoundExpression* _expression;
|
||||||
|
public:
|
||||||
|
BoundImplicitCastExpression(BoundExpression* expression, shared_ptr<const ScriptType> castType)
|
||||||
|
: BoundExpression(expression->GetStartPosition(), expression->GetLength(), castType),
|
||||||
|
_expression(expression)
|
||||||
|
{}
|
||||||
|
|
||||||
|
const BoundExpression* GetExpression() const{
|
||||||
|
return _expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
~BoundImplicitCastExpression() final {
|
||||||
|
delete _expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
inline BoundExpressionKind GetKind() const final {
|
||||||
|
return BoundExpressionKind::ImplicitCast;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP
|
#endif //PORYGONLANG_BOUNDEXPRESSION_HPP
|
||||||
|
|
|
@ -87,6 +87,11 @@ namespace Porygon::Evaluation {
|
||||||
virtual EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const{
|
virtual EvalValue* UnaryOperation(Binder::BoundUnaryOperation operation) const{
|
||||||
throw EvaluationException("Unary operations are not implemented for this type.");
|
throw EvaluationException("Unary operations are not implemented for this type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
virtual EvalValue* Cast(shared_ptr<const ScriptType> castType) const{
|
||||||
|
throw new EvaluationException("Casting to invalid type.");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BooleanEvalValue : public EvalValue {
|
class BooleanEvalValue : public EvalValue {
|
||||||
|
|
|
@ -176,4 +176,24 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalValue *IntegerEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
|
||||||
|
if (castType->GetClass() == TypeClass::Number){
|
||||||
|
auto num = static_pointer_cast<const NumericScriptType>(castType);
|
||||||
|
if (num->IsFloat()){
|
||||||
|
return new FloatEvalValue(GetIntegerValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EvalValue::Cast(castType);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalValue *FloatEvalValue::Cast(shared_ptr<const ScriptType> castType) const {
|
||||||
|
if (castType->GetClass() == TypeClass::Number){
|
||||||
|
auto num = static_pointer_cast<const NumericScriptType>(castType);
|
||||||
|
if (!num->IsFloat()){
|
||||||
|
return new IntegerEvalValue(GetFloatValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EvalValue::Cast(castType);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -68,11 +68,6 @@ namespace Porygon::Evaluation {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
inline double EvaluateFloat() const final {
|
|
||||||
return static_cast<double>(_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline std::u16string EvaluateString() const final{
|
inline std::u16string EvaluateString() const final{
|
||||||
return Utilities::StringUtils::IntToString(_value);
|
return Utilities::StringUtils::IntToString(_value);
|
||||||
|
@ -98,14 +93,17 @@ namespace Porygon::Evaluation {
|
||||||
default: throw;
|
default: throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatEvalValue : public NumericEvalValue {
|
class FloatEvalValue : public NumericEvalValue {
|
||||||
const double _value;
|
const double _value;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline int64_t GetIntegerValue() const final {
|
int64_t GetIntegerValue() const final {
|
||||||
return _value;
|
throw EvaluationException("Attempting to retrieve int from float eval value.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
|
@ -127,11 +125,6 @@ namespace Porygon::Evaluation {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
inline int64_t EvaluateInteger() const final {
|
|
||||||
return static_cast<int64_t >(_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline std::u16string EvaluateString() const final{
|
inline std::u16string EvaluateString() const final{
|
||||||
return Utilities::StringUtils::FloatToString(_value);
|
return Utilities::StringUtils::FloatToString(_value);
|
||||||
|
@ -196,6 +189,9 @@ namespace Porygon::Evaluation {
|
||||||
default: throw;
|
default: throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
EvalValue* Cast(shared_ptr<const ScriptType> castType) const final;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,8 @@ namespace Porygon::Evaluation {
|
||||||
return this->EvaluateComplexTableExpression(expression);
|
return this->EvaluateComplexTableExpression(expression);
|
||||||
case BoundExpressionKind::Require:
|
case BoundExpressionKind::Require:
|
||||||
return this -> EvaluateRequireExpression(expression);
|
return this -> EvaluateRequireExpression(expression);
|
||||||
|
case BoundExpressionKind::ImplicitCast:
|
||||||
|
return this -> EvaluateImplicitCastExpression(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,4 +414,10 @@ namespace Porygon::Evaluation {
|
||||||
return result.Take();
|
return result.Take();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalValuePointer Evaluator::EvaluateImplicitCastExpression(const BoundExpression *pExpression) {
|
||||||
|
auto iCExpression = dynamic_cast<const BoundImplicitCastExpression*>(pExpression);
|
||||||
|
auto val = EvaluateExpression(iCExpression->GetExpression());
|
||||||
|
return val->Cast(iCExpression->GetType());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -48,6 +48,7 @@ namespace Porygon::Evaluation{
|
||||||
EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression);
|
EvalValuePointer EvaluateComplexTableExpression(const BoundExpression *expression);
|
||||||
|
|
||||||
EvalValuePointer EvaluateRequireExpression(const BoundExpression* expression);
|
EvalValuePointer EvaluateRequireExpression(const BoundExpression* expression);
|
||||||
|
EvalValuePointer EvaluateImplicitCastExpression(const BoundExpression *pExpression);
|
||||||
|
|
||||||
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
EvalValuePointer GetVariable(const BoundVariableExpression *expression);
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -36,23 +36,26 @@ namespace Porygon {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsValid(const shared_ptr<Diagnostics::DiagnosticsHolder>& diagnostics,
|
bool IsValid(const shared_ptr<Diagnostics::DiagnosticsHolder>& diagnostics,
|
||||||
const vector<Binder::BoundExpression *>& parameters){
|
vector<Binder::BoundExpression *>* parameters){
|
||||||
if (parameters.size() != _parameterTypes.size()){
|
if (parameters->size() != _parameterTypes.size()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < parameters.size(); i++){
|
for (size_t i = 0; i < parameters->size(); i++){
|
||||||
if (_parameterTypes[i]->GetClass() == TypeClass::All)
|
if (_parameterTypes[i]->GetClass() == TypeClass::All)
|
||||||
continue;
|
continue;
|
||||||
auto parameter = parameters[i];
|
auto parameter = parameters->at(i);
|
||||||
const auto& parameterType = parameter->GetType();
|
const auto& parameterType = parameter->GetType();
|
||||||
if (parameterType->operator!=(_parameterTypes[i].get())){
|
if (parameterType->operator!=(_parameterTypes[i].get())){
|
||||||
auto castResult = parameterType->CastableTo(_parameterTypes[i], false);
|
auto castResult = parameterType->CastableTo(_parameterTypes[i], false);
|
||||||
if (castResult == CastResult::Failure){
|
if (castResult == CastResult::Failure){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (castResult == CastResult::DataLoss){
|
else{
|
||||||
diagnostics->LogWarning(Diagnostics::DiagnosticCode::DataLossOnImplicitCast, parameter->GetStartPosition(),
|
if (castResult == CastResult::DataLoss){
|
||||||
parameter->GetLength());
|
diagnostics->LogWarning(Diagnostics::DiagnosticCode::DataLossOnImplicitCast, parameter->GetStartPosition(),
|
||||||
|
parameter->GetLength());
|
||||||
|
}
|
||||||
|
parameters->at(i) = new Binder::BoundImplicitCastExpression(parameter, _parameterTypes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,8 +106,9 @@ namespace Porygon {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
GenericFunctionOption* GetFunctionOption(const shared_ptr<Diagnostics::DiagnosticsHolder>& diagnostics,
|
GenericFunctionOption* GetFunctionOption(const shared_ptr<Diagnostics::DiagnosticsHolder>& diagnostics,
|
||||||
const vector<Binder::BoundExpression *>& parameters) const{
|
vector<Binder::BoundExpression *>* parameters) const{
|
||||||
for (auto o: *_options){
|
for (auto o: *_options){
|
||||||
if (o->IsValid(diagnostics, parameters)){
|
if (o->IsValid(diagnostics, parameters)){
|
||||||
return o;
|
return o;
|
||||||
|
|
Loading…
Reference in New Issue