in src/Trinity.TSL/Trinity.TSL.Parser/SyntaxNode.cpp [326:394]
bool NFieldType::is_assignable_from(NFieldType* that)
{
if (!NFieldType_Compare(this, that))
return true;
if (!this->is_nullable() && that->is_nullable())
return false;
if (this->is_nullable() && !that->is_nullable())
{
// mark this temporarily as non-optional
this->field->unset_optional();
bool non_optional_this_assignable_from_that = this->is_assignable_from(that);
// mark this back as optional
this->field->set_optional();
return non_optional_this_assignable_from_that;
}
/* For arrays with same rank & same element type, we say they are compatible. */
if (this->is_array_same_rank_same_element_type(that))
return true;
if (this->is_list() && that->is_list())
return (0 == NFieldType_Compare(this->listElementType, that->listElementType));
if (this->is_enum() && that->is_enum())
return this->referencedNEnum == that->referencedNEnum;
if (this->is_struct() && that->is_struct())
return this->referencedNStruct == that->referencedNStruct;
if (!(this->is_atom() && that->is_atom()))
return false;
/* Here we have this->is_atom() and that->is_atom */
if (this->is_string() && that->is_string())
return true;
if (this->is_integral() && that->is_integral())
{
return
(this->type_size() > that->type_size() && (this->is_signed() || !that->is_signed()))
||
(this->type_size() == that->type_size()
&&
this->is_signed() == that->is_signed());
}
if (this->is_bool() && that->is_bool())
return true;
if (this->is_floating_point() && that->is_integral())
return true;
if (this->is_floating_point() && that->is_floating_point())
{
if (this->is_decimal() /* && !that->is_decimal() */)
return false;
return this->type_size() > that->type_size();
}
/* anything else, we say this is not assignable from that. */
return false;
}