Support for explicit casting
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
1d72e2eccd
commit
e939920e5c
|
@ -1,5 +1,5 @@
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include "Binder.hpp"
|
#include "Binder.hpp"
|
||||||
#include "../ScriptTypes/TableScriptType.hpp"
|
#include "../ScriptTypes/TableScriptType.hpp"
|
||||||
#include "BoundExpressions/BoundTableExpression.hpp"
|
#include "BoundExpressions/BoundTableExpression.hpp"
|
||||||
|
@ -87,7 +87,8 @@ namespace Porygon::Binder {
|
||||||
auto key = assignment.GetKey();
|
auto key = assignment.GetKey();
|
||||||
return new BoundAssignmentStatement(key, boundExpression);
|
return new BoundAssignmentStatement(key, boundExpression);
|
||||||
} else {
|
} else {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +143,8 @@ namespace Porygon::Binder {
|
||||||
auto var = parameters->at(i);
|
auto var = parameters->at(i);
|
||||||
auto parsedType = ParseTypeIdentifier(var->GetType());
|
auto parsedType = ParseTypeIdentifier(var->GetType());
|
||||||
if (parsedType == nullptr) {
|
if (parsedType == nullptr) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTypeName, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidTypeName,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -168,7 +170,8 @@ namespace Porygon::Binder {
|
||||||
auto var = this->_scope->GetVariable(scope, identifier);
|
auto var = this->_scope->GetVariable(scope, identifier);
|
||||||
auto varType = var->GetType();
|
auto varType = var->GetType();
|
||||||
if (varType->GetClass() != TypeClass::Function) {
|
if (varType->GetClass() != TypeClass::Function) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
}
|
}
|
||||||
type = dynamic_pointer_cast<const GenericFunctionScriptType>(varType);
|
type = dynamic_pointer_cast<const GenericFunctionScriptType>(varType);
|
||||||
|
@ -179,7 +182,8 @@ namespace Porygon::Binder {
|
||||||
type->RegisterFunctionOption(option);
|
type->RegisterFunctionOption(option);
|
||||||
auto assignment = this->_scope->AssignVariable(identifier, type);
|
auto assignment = this->_scope->AssignVariable(identifier, type);
|
||||||
if (assignment.GetResult() != VariableAssignmentResult::Ok) {
|
if (assignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -200,8 +204,10 @@ namespace Porygon::Binder {
|
||||||
} else {
|
} else {
|
||||||
currentReturnType = this->_currentFunction->GetReturnType();
|
currentReturnType = this->_currentFunction->GetReturnType();
|
||||||
}
|
}
|
||||||
if (expression == nullptr && (currentReturnType != nullptr && currentReturnType -> GetClass() != TypeClass::Nil)) {
|
if (expression == nullptr &&
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidReturnType, statement->GetStartPosition(),
|
(currentReturnType != nullptr && currentReturnType->GetClass() != TypeClass::Nil)) {
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidReturnType,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
} else if (expression == nullptr) {
|
} else if (expression == nullptr) {
|
||||||
|
@ -219,7 +225,8 @@ namespace Porygon::Binder {
|
||||||
return new BoundReturnStatement(boundExpression);
|
return new BoundReturnStatement(boundExpression);
|
||||||
}
|
}
|
||||||
if (currentReturnType.get()->operator!=(expresionType.get())) {
|
if (currentReturnType.get()->operator!=(expresionType.get())) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidReturnType, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidReturnType,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -230,7 +237,8 @@ namespace Porygon::Binder {
|
||||||
auto conditionalStatement = (ParsedConditionalStatement *) statement;
|
auto conditionalStatement = (ParsedConditionalStatement *) statement;
|
||||||
auto boundCondition = this->BindExpression(conditionalStatement->GetCondition());
|
auto boundCondition = this->BindExpression(conditionalStatement->GetCondition());
|
||||||
if (boundCondition->GetType()->GetClass() != TypeClass::Bool) {
|
if (boundCondition->GetType()->GetClass() != TypeClass::Bool) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ConditionNotABool, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ConditionNotABool,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -253,17 +261,20 @@ namespace Porygon::Binder {
|
||||||
step = this->BindExpression(parsedStep);
|
step = this->BindExpression(parsedStep);
|
||||||
}
|
}
|
||||||
if (start->GetType()->GetClass() != TypeClass::Number) {
|
if (start->GetType()->GetClass() != TypeClass::Number) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, start->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber,
|
||||||
|
start->GetStartPosition(),
|
||||||
start->GetLength());
|
start->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
if (end->GetType()->GetClass() != TypeClass::Number) {
|
if (end->GetType()->GetClass() != TypeClass::Number) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, end->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber,
|
||||||
|
end->GetStartPosition(),
|
||||||
end->GetLength());
|
end->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
if (step != nullptr && step->GetType()->GetClass() != TypeClass::Number) {
|
if (step != nullptr && step->GetType()->GetClass() != TypeClass::Number) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber, step->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NumericalForArgumentNotANumber,
|
||||||
|
step->GetStartPosition(),
|
||||||
step->GetLength());
|
step->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -271,7 +282,8 @@ namespace Porygon::Binder {
|
||||||
this->_scope->GoInnerScope();
|
this->_scope->GoInnerScope();
|
||||||
auto variableKey = this->_scope->CreateExplicitLocal(identifier, make_shared<NumericScriptType>(true, false));
|
auto variableKey = this->_scope->CreateExplicitLocal(identifier, make_shared<NumericScriptType>(true, false));
|
||||||
if (variableKey.GetResult() != VariableAssignmentResult::Ok) {
|
if (variableKey.GetResult() != VariableAssignmentResult::Ok) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -285,7 +297,8 @@ namespace Porygon::Binder {
|
||||||
auto boundIterator = BindExpression(genericFor->GetIteratorExpression());
|
auto boundIterator = BindExpression(genericFor->GetIteratorExpression());
|
||||||
const auto &itType = boundIterator->GetType();
|
const auto &itType = boundIterator->GetType();
|
||||||
if (!itType->CanBeIterated()) {
|
if (!itType->CanBeIterated()) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantIterateExpression, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantIterateExpression,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -294,7 +307,8 @@ namespace Porygon::Binder {
|
||||||
this->_scope->GoInnerScope();
|
this->_scope->GoInnerScope();
|
||||||
auto keyVariableAssignment = this->_scope->CreateExplicitLocal(keyIdentifier, keyType);
|
auto keyVariableAssignment = this->_scope->CreateExplicitLocal(keyIdentifier, keyType);
|
||||||
if (keyVariableAssignment.GetResult() != VariableAssignmentResult::Ok) {
|
if (keyVariableAssignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -307,7 +321,8 @@ namespace Porygon::Binder {
|
||||||
auto valueType = itType->GetIndexedType(keyType.get());
|
auto valueType = itType->GetIndexedType(keyType.get());
|
||||||
auto valueVariableAssignment = this->_scope->CreateExplicitLocal(valueIdentifier, valueType);
|
auto valueVariableAssignment = this->_scope->CreateExplicitLocal(valueIdentifier, valueType);
|
||||||
if (valueVariableAssignment.GetResult() != VariableAssignmentResult::Ok) {
|
if (valueVariableAssignment.GetResult() != VariableAssignmentResult::Ok) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::CantAssignVariable,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -324,7 +339,8 @@ namespace Porygon::Binder {
|
||||||
auto whileStatement = (ParsedWhileStatement *) statement;
|
auto whileStatement = (ParsedWhileStatement *) statement;
|
||||||
auto boundCondition = this->BindExpression(whileStatement->GetCondition());
|
auto boundCondition = this->BindExpression(whileStatement->GetCondition());
|
||||||
if (boundCondition->GetType()->GetClass() != TypeClass::Bool) {
|
if (boundCondition->GetType()->GetClass() != TypeClass::Bool) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ConditionNotABool, statement->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::ConditionNotABool,
|
||||||
|
statement->GetStartPosition(),
|
||||||
statement->GetLength());
|
statement->GetLength());
|
||||||
return new BoundBadStatement();
|
return new BoundBadStatement();
|
||||||
}
|
}
|
||||||
|
@ -382,7 +398,8 @@ namespace Porygon::Binder {
|
||||||
auto key = expression->GetValue();
|
auto key = expression->GetValue();
|
||||||
auto scope = this->_scope->Exists(key);
|
auto scope = this->_scope->Exists(key);
|
||||||
if (scope == -1) {
|
if (scope == -1) {
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::VariableNotFound, expression->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::VariableNotFound,
|
||||||
|
expression->GetStartPosition(),
|
||||||
expression->GetLength());
|
expression->GetLength());
|
||||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
@ -526,7 +543,8 @@ namespace Porygon::Binder {
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoBinaryOperationFound, expression->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoBinaryOperationFound,
|
||||||
|
expression->GetStartPosition(),
|
||||||
expression->GetLength());
|
expression->GetLength());
|
||||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
@ -561,7 +579,8 @@ namespace Porygon::Binder {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoUnaryOperationFound, expression->GetStartPosition(),
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::NoUnaryOperationFound,
|
||||||
|
expression->GetStartPosition(),
|
||||||
expression->GetLength());
|
expression->GetLength());
|
||||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
|
|
||||||
|
@ -571,8 +590,11 @@ namespace Porygon::Binder {
|
||||||
auto func = expression->GetFunction();
|
auto func = expression->GetFunction();
|
||||||
if (func->GetKind() == ParsedExpressionKind::Variable) {
|
if (func->GetKind() == ParsedExpressionKind::Variable) {
|
||||||
auto variable = dynamic_cast<const VariableExpression *>(func);
|
auto variable = dynamic_cast<const VariableExpression *>(func);
|
||||||
if (variable->GetValue().GetHash() == HashedString::ConstHash("require")){
|
auto hash = variable->GetValue().GetHash();
|
||||||
|
if (hash == HashedString::ConstHash("require")) {
|
||||||
return this->BindRequire(expression);
|
return this->BindRequire(expression);
|
||||||
|
} else if (hash == HashedString::ConstHash("cast")) {
|
||||||
|
return this->BindCast(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto functionExpression = BindExpression(func);
|
auto functionExpression = BindExpression(func);
|
||||||
|
@ -598,7 +620,8 @@ namespace Porygon::Binder {
|
||||||
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
return new BoundBadExpression(expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BoundFunctionCallExpression(functionExpression, boundParameters, functionOption, functionOption->GetReturnType(),
|
return new BoundFunctionCallExpression(functionExpression, boundParameters, functionOption,
|
||||||
|
functionOption->GetReturnType(),
|
||||||
expression->GetStartPosition(), expression->GetLength());
|
expression->GetStartPosition(), expression->GetLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,6 +663,43 @@ namespace Porygon::Binder {
|
||||||
return new BoundRequireExpression(module, exp->GetStartPosition(), exp->GetLength());
|
return new BoundRequireExpression(module, exp->GetStartPosition(), exp->GetLength());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BoundExpression *Binder::BindCast(const FunctionCallExpression* exp){
|
||||||
|
auto parameters = exp->GetParameters();
|
||||||
|
if (parameters->size() != 2) {
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||||
|
exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp->GetLength());
|
||||||
|
}
|
||||||
|
auto toCastParameter = this ->BindExpression(parameters->at(0));
|
||||||
|
const auto& toCastParameterType = toCastParameter->GetType();
|
||||||
|
|
||||||
|
auto destinationTypeParameter = parameters -> at(1);
|
||||||
|
if (destinationTypeParameter ->GetKind() != ParsedExpressionKind::Variable){
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidFunctionParameters,
|
||||||
|
exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp->GetLength());
|
||||||
|
}
|
||||||
|
auto destinationTypeContent = dynamic_cast<const VariableExpression*>(destinationTypeParameter)->GetValue();
|
||||||
|
auto destinationType = ParseTypeIdentifier(&destinationTypeContent);
|
||||||
|
auto castResult = toCastParameterType->CastableTo(destinationType, true);
|
||||||
|
if (castResult == CastResult::InvalidCast){
|
||||||
|
this->_scriptData->Diagnostics->LogError(Diagnostics::DiagnosticCode::InvalidCast, exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
return new BoundBadExpression(exp->GetStartPosition(), exp->GetLength());
|
||||||
|
}
|
||||||
|
else if (castResult == CastResult::DataLoss){
|
||||||
|
this->_scriptData->Diagnostics->LogWarning(Diagnostics::DiagnosticCode::DataLossOnCast, exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
}
|
||||||
|
else if (castResult == CastResult::UncheckedCast){
|
||||||
|
this->_scriptData->Diagnostics->LogInfo(Diagnostics::DiagnosticCode::UnvalidatedCast, exp->GetStartPosition(),
|
||||||
|
exp->GetLength());
|
||||||
|
}
|
||||||
|
return new BoundCastExpression(toCastParameter, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
|
BoundExpression *Binder::BindIndexExpression(const IndexExpression *expression, bool setter) {
|
||||||
auto indexer = this->BindExpression(expression->GetIndexer());
|
auto indexer = this->BindExpression(expression->GetIndexer());
|
||||||
auto index = this->BindExpression(expression->GetIndex());
|
auto index = this->BindExpression(expression->GetIndex());
|
||||||
|
|
|
@ -42,6 +42,7 @@ namespace Porygon::Binder {
|
||||||
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
BoundExpression *BindUnaryOperator(const UnaryExpression *expression);
|
||||||
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
BoundExpression *BindFunctionCall(const FunctionCallExpression *expression);
|
||||||
BoundExpression *BindRequire(const FunctionCallExpression *exp);
|
BoundExpression *BindRequire(const FunctionCallExpression *exp);
|
||||||
|
BoundExpression *BindCast(const FunctionCallExpression *exp);
|
||||||
BoundExpression *BindIndexExpression(const IndexExpression *expression, bool setter);
|
BoundExpression *BindIndexExpression(const IndexExpression *expression, bool setter);
|
||||||
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
BoundExpression *BindNumericalTableExpression(const ParsedNumericalTableExpression *expression);
|
||||||
BoundExpression *BindTableExpression(const ParsedTableExpression *expression);
|
BoundExpression *BindTableExpression(const ParsedTableExpression *expression);
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace Porygon::Binder {
|
||||||
NumericalTable,
|
NumericalTable,
|
||||||
Table,
|
Table,
|
||||||
Require,
|
Require,
|
||||||
ImplicitCast,
|
Cast,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoundExpression {
|
class BoundExpression {
|
||||||
|
@ -333,10 +333,10 @@ namespace Porygon::Binder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoundImplicitCastExpression : public BoundExpression {
|
class BoundCastExpression : public BoundExpression {
|
||||||
const BoundExpression* _expression;
|
const BoundExpression* _expression;
|
||||||
public:
|
public:
|
||||||
BoundImplicitCastExpression(BoundExpression* expression, shared_ptr<const ScriptType> castType)
|
BoundCastExpression(BoundExpression* expression, shared_ptr<const ScriptType> castType)
|
||||||
: BoundExpression(expression->GetStartPosition(), expression->GetLength(), castType),
|
: BoundExpression(expression->GetStartPosition(), expression->GetLength(), castType),
|
||||||
_expression(expression)
|
_expression(expression)
|
||||||
{}
|
{}
|
||||||
|
@ -345,13 +345,13 @@ namespace Porygon::Binder {
|
||||||
return _expression;
|
return _expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
~BoundImplicitCastExpression() final {
|
~BoundCastExpression() final {
|
||||||
delete _expression;
|
delete _expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
inline BoundExpressionKind GetKind() const final {
|
inline BoundExpressionKind GetKind() const final {
|
||||||
return BoundExpressionKind::ImplicitCast;
|
return BoundExpressionKind::Cast;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,13 @@ namespace Porygon::Diagnostics {
|
||||||
CantIterateExpression,
|
CantIterateExpression,
|
||||||
InvalidFunctionParameters,
|
InvalidFunctionParameters,
|
||||||
ModuleDoesntExist,
|
ModuleDoesntExist,
|
||||||
|
InvalidCast,
|
||||||
|
|
||||||
// Bind warnings
|
// Bind warnings
|
||||||
DataLossOnImplicitCast,
|
DataLossOnCast,
|
||||||
|
|
||||||
|
// Bind info
|
||||||
|
UnvalidatedCast,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
#endif //PORYGONLANG_DIAGNOSTICCODE_HPP
|
||||||
|
|
|
@ -257,7 +257,7 @@ 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:
|
case BoundExpressionKind::Cast:
|
||||||
return this -> EvaluateImplicitCastExpression(expression);
|
return this -> EvaluateImplicitCastExpression(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ namespace Porygon::Evaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
EvalValuePointer Evaluator::EvaluateImplicitCastExpression(const BoundExpression *pExpression) {
|
EvalValuePointer Evaluator::EvaluateImplicitCastExpression(const BoundExpression *pExpression) {
|
||||||
auto iCExpression = dynamic_cast<const BoundImplicitCastExpression*>(pExpression);
|
auto iCExpression = dynamic_cast<const BoundCastExpression*>(pExpression);
|
||||||
auto val = EvaluateExpression(iCExpression->GetExpression());
|
auto val = EvaluateExpression(iCExpression->GetExpression());
|
||||||
return val->Cast(iCExpression->GetType());
|
return val->Cast(iCExpression->GetType());
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
|
|
||||||
namespace Porygon{
|
namespace Porygon{
|
||||||
enum class CastResult{
|
enum class CastResult{
|
||||||
Success,
|
ValidCast,
|
||||||
Failure,
|
InvalidCast,
|
||||||
|
UncheckedCast,
|
||||||
DataLoss,
|
DataLoss,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,15 +47,15 @@ namespace Porygon {
|
||||||
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::InvalidCast){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (castResult == CastResult::DataLoss){
|
if (castResult == CastResult::DataLoss){
|
||||||
diagnostics->LogWarning(Diagnostics::DiagnosticCode::DataLossOnImplicitCast, parameter->GetStartPosition(),
|
diagnostics->LogWarning(Diagnostics::DiagnosticCode::DataLossOnCast, parameter->GetStartPosition(),
|
||||||
parameter->GetLength());
|
parameter->GetLength());
|
||||||
}
|
}
|
||||||
parameters->at(i) = new Binder::BoundImplicitCastExpression(parameter, _parameterTypes[i]);
|
parameters->at(i) = new Binder::BoundCastExpression(parameter, _parameterTypes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,9 @@ namespace Porygon{
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const{
|
[[nodiscard]] virtual CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const{
|
||||||
return CastResult::Failure;
|
if (explicitCast)
|
||||||
|
return CastResult::InvalidCast;
|
||||||
|
return CastResult::InvalidCast;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,12 +122,12 @@ namespace Porygon{
|
||||||
[[nodiscard]] CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const final{
|
[[nodiscard]] CastResult CastableTo(const shared_ptr<const ScriptType>& castType, bool explicitCast) const final{
|
||||||
if (!explicitCast){
|
if (!explicitCast){
|
||||||
if (castType->GetClass() != TypeClass::Number )
|
if (castType->GetClass() != TypeClass::Number )
|
||||||
return CastResult::Failure;
|
return CastResult::InvalidCast;
|
||||||
auto bNum = dynamic_pointer_cast<const NumericScriptType>(castType);
|
auto bNum = dynamic_pointer_cast<const NumericScriptType>(castType);
|
||||||
if (bNum->IsFloat() && !IsFloat()) return CastResult::Success;
|
if (bNum->IsFloat() && !IsFloat()) return CastResult::ValidCast;
|
||||||
if (!bNum->IsFloat() && IsFloat()) return CastResult::DataLoss;
|
if (!bNum->IsFloat() && IsFloat()) return CastResult::DataLoss;
|
||||||
}
|
}
|
||||||
return CastResult::Success;
|
return ScriptType::CastableTo(castType, explicitCast);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue