Skip to content

Commit

Permalink
added 'is null' operator
Browse files Browse the repository at this point in the history
  • Loading branch information
rune-scape committed Jun 19, 2023
1 parent b074f4f commit db97059
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
17 changes: 15 additions & 2 deletions modules/gdscript/gdscript_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4466,7 +4466,16 @@ void GDScriptAnalyzer::reduce_type_test(GDScriptParser::TypeTestNode *p_type_tes
p_type_test->is_constant = true;
p_type_test->reduced_value = false;

if (!is_type_compatible(test_type, operand_type)) {
if (test_type.kind == GDScriptParser::DataType::BUILTIN && test_type.builtin_type == Variant::NIL) {
const Variant &operand_reduced_value = p_type_test->operand->reduced_value;
if (operand_reduced_value.get_type() == Variant::NIL) {
p_type_test->reduced_value = true;
} else if (operand_reduced_value.get_type() == Variant::OBJECT && operand_reduced_value.is_null()) {
p_type_test->reduced_value = true;
} else {
p_type_test->reduced_value = false;
}
} else if (!is_type_compatible(test_type, operand_type)) {
push_error(vformat(R"(Expression is of type "%s" so it can't be of type "%s".)", operand_type.to_string(), test_type.to_string()), p_type_test->operand);
} else if (is_type_compatible(test_type, type_from_variant(p_type_test->operand->reduced_value, p_type_test->operand))) {
p_type_test->reduced_value = test_type.builtin_type != Variant::OBJECT || !p_type_test->operand->reduced_value.is_null();
Expand All @@ -4475,7 +4484,11 @@ void GDScriptAnalyzer::reduce_type_test(GDScriptParser::TypeTestNode *p_type_tes
return;
}

if (!is_type_compatible(test_type, operand_type) && !is_type_compatible(operand_type, test_type)) {
if (test_type.kind == GDScriptParser::DataType::BUILTIN && test_type.builtin_type == Variant::NIL) {
if (operand_type.kind == GDScriptParser::DataType::ENUM || (operand_type.kind == GDScriptParser::DataType::BUILTIN && operand_type.builtin_type != Variant::NIL && operand_type.builtin_type != Variant::OBJECT)) {
push_error(vformat(R"(Expression is of type "%s" so it can't be null.)", operand_type.to_string()), p_type_test->operand);
}
} else if (!is_type_compatible(test_type, operand_type) && !is_type_compatible(operand_type, test_type)) {
if (operand_type.is_hard_type()) {
push_error(vformat(R"(Expression is of type "%s" so it can't be of type "%s".)", operand_type.to_string(), test_type.to_string()), p_type_test->operand);
} else {
Expand Down
3 changes: 3 additions & 0 deletions modules/gdscript/gdscript_byte_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@ void GDScriptByteCodeGenerator::write_type_test(const Address &p_target, const A
append(get_constant_pos(element_type.script_type) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS));
append(element_type.builtin_type);
append(element_type.native_type);
} else if (p_type.builtin_type == Variant::NIL) {
GDScriptCodeGenerator::Address null_value_address(GDScriptCodeGenerator::Address::CONSTANT, add_or_get_constant(Variant()), p_type);
write_binary_operator(p_target, Variant::OP_EQUAL, p_source, null_value_address);
} else {
append_opcode(GDScriptFunction::OPCODE_TYPE_TEST_BUILTIN);
append(p_target);
Expand Down
15 changes: 14 additions & 1 deletion modules/gdscript/gdscript_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3317,7 +3317,20 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_type_test(ExpressionNode *
type_test->is_not = true;
}

type_test->test_type = parse_type();
if (check(GDScriptTokenizer::Token::LITERAL) && current.literal == Variant()) {
IdentifierNode *nil_identifier = alloc_node<IdentifierNode>();
nil_identifier->name = SNAME("Nil");
complete_extents(nil_identifier);

TypeNode *type = alloc_node<TypeNode>();
type->type_chain.push_back(nil_identifier);
complete_extents(type);

type_test->test_type = type;
} else {
type_test->test_type = parse_type();
}

complete_extents(type_test);

if (type_test->test_type == nullptr) {
Expand Down

0 comments on commit db97059

Please sign in to comment.