summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/gdscript/gdscript_compiler.cpp77
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.gd14
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.out3
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.gd28
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.out4
5 files changed, 87 insertions, 39 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 327e24ef11..ba859a9f9b 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1272,7 +1272,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
}
// Get literal type into constant map.
- GDScriptCodeGenerator::Address literal_type_addr = codegen.add_constant((int)p_pattern->literal->value.get_type());
+ Variant::Type literal_type = p_pattern->literal->value.get_type();
+ GDScriptCodeGenerator::Address literal_type_addr = codegen.add_constant(literal_type);
// Equality is always a boolean.
GDScriptDataType equality_type;
@@ -1280,29 +1281,31 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
equality_type.kind = GDScriptDataType::BUILTIN;
equality_type.builtin_type = Variant::BOOL;
- GDScriptCodeGenerator::Address type_string_addr = codegen.add_constant(Variant::STRING);
- GDScriptCodeGenerator::Address type_string_name_addr = codegen.add_constant(Variant::STRING_NAME);
-
// Check type equality.
GDScriptCodeGenerator::Address type_equality_addr = codegen.add_temporary(equality_type);
codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_EQUAL, p_type_addr, literal_type_addr);
- // Check if StringName <-> String comparison is possible.
- GDScriptCodeGenerator::Address type_comp_addr_1 = codegen.add_temporary(equality_type);
- GDScriptCodeGenerator::Address type_comp_addr_2 = codegen.add_temporary(equality_type);
+ if (literal_type == Variant::STRING) {
+ GDScriptCodeGenerator::Address type_stringname_addr = codegen.add_constant(Variant::STRING_NAME);
+
+ // Check StringName <-> String type equality.
+ GDScriptCodeGenerator::Address tmp_comp_addr = codegen.add_temporary(equality_type);
+
+ codegen.generator->write_binary_operator(tmp_comp_addr, Variant::OP_EQUAL, p_type_addr, type_stringname_addr);
+ codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_OR, type_equality_addr, tmp_comp_addr);
+
+ codegen.generator->pop_temporary(); // Remove tmp_comp_addr from stack.
+ } else if (literal_type == Variant::STRING_NAME) {
+ GDScriptCodeGenerator::Address type_string_addr = codegen.add_constant(Variant::STRING);
- codegen.generator->write_binary_operator(type_comp_addr_1, Variant::OP_EQUAL, p_type_addr, type_string_addr);
- codegen.generator->write_binary_operator(type_comp_addr_2, Variant::OP_EQUAL, literal_type_addr, type_string_name_addr);
- codegen.generator->write_binary_operator(type_comp_addr_1, Variant::OP_AND, type_comp_addr_1, type_comp_addr_2);
- codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_OR, type_equality_addr, type_comp_addr_1);
+ // Check String <-> StringName type equality.
+ GDScriptCodeGenerator::Address tmp_comp_addr = codegen.add_temporary(equality_type);
- codegen.generator->write_binary_operator(type_comp_addr_1, Variant::OP_EQUAL, p_type_addr, type_string_name_addr);
- codegen.generator->write_binary_operator(type_comp_addr_2, Variant::OP_EQUAL, literal_type_addr, type_string_addr);
- codegen.generator->write_binary_operator(type_comp_addr_1, Variant::OP_AND, type_comp_addr_1, type_comp_addr_2);
- codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_OR, type_equality_addr, type_comp_addr_1);
+ codegen.generator->write_binary_operator(tmp_comp_addr, Variant::OP_EQUAL, p_type_addr, type_string_addr);
+ codegen.generator->write_binary_operator(type_equality_addr, Variant::OP_OR, type_equality_addr, tmp_comp_addr);
- codegen.generator->pop_temporary(); // Remove type_comp_addr_2 from stack.
- codegen.generator->pop_temporary(); // Remove type_comp_addr_1 from stack.
+ codegen.generator->pop_temporary(); // Remove tmp_comp_addr from stack.
+ }
codegen.generator->write_and_left_operand(type_equality_addr);
@@ -1349,9 +1352,22 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
} else if (!p_is_first) {
codegen.generator->write_or_left_operand(p_previous_test);
}
+
+ GDScriptCodeGenerator::Address type_string_addr = codegen.add_constant(Variant::STRING);
+ GDScriptCodeGenerator::Address type_stringname_addr = codegen.add_constant(Variant::STRING_NAME);
+
+ // Equality is always a boolean.
+ GDScriptDataType equality_type;
+ equality_type.has_type = true;
+ equality_type.kind = GDScriptDataType::BUILTIN;
+ equality_type.builtin_type = Variant::BOOL;
+
// Create the result temps first since it's the last to go away.
- GDScriptCodeGenerator::Address result_addr = codegen.add_temporary();
- GDScriptCodeGenerator::Address equality_test_addr = codegen.add_temporary();
+ GDScriptCodeGenerator::Address result_addr = codegen.add_temporary(equality_type);
+ GDScriptCodeGenerator::Address equality_test_addr = codegen.add_temporary(equality_type);
+ GDScriptCodeGenerator::Address stringy_comp_addr = codegen.add_temporary(equality_type);
+ GDScriptCodeGenerator::Address stringy_comp_addr_2 = codegen.add_temporary(equality_type);
+ GDScriptCodeGenerator::Address expr_type_addr = codegen.add_temporary();
// Evaluate expression.
GDScriptCodeGenerator::Address expr_addr;
@@ -1363,10 +1379,27 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
// Evaluate expression type.
Vector<GDScriptCodeGenerator::Address> typeof_args;
typeof_args.push_back(expr_addr);
- codegen.generator->write_call_utility(result_addr, "typeof", typeof_args);
+ codegen.generator->write_call_utility(expr_type_addr, "typeof", typeof_args);
// Check type equality.
- codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_type_addr, result_addr);
+ codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_type_addr, expr_type_addr);
+
+ // Check for String <-> StringName comparison.
+ codegen.generator->write_binary_operator(stringy_comp_addr, Variant::OP_EQUAL, p_type_addr, type_string_addr);
+ codegen.generator->write_binary_operator(stringy_comp_addr_2, Variant::OP_EQUAL, expr_type_addr, type_stringname_addr);
+ codegen.generator->write_binary_operator(stringy_comp_addr, Variant::OP_AND, stringy_comp_addr, stringy_comp_addr_2);
+ codegen.generator->write_binary_operator(result_addr, Variant::OP_OR, result_addr, stringy_comp_addr);
+
+ // Check for StringName <-> String comparison.
+ codegen.generator->write_binary_operator(stringy_comp_addr, Variant::OP_EQUAL, p_type_addr, type_stringname_addr);
+ codegen.generator->write_binary_operator(stringy_comp_addr_2, Variant::OP_EQUAL, expr_type_addr, type_string_addr);
+ codegen.generator->write_binary_operator(stringy_comp_addr, Variant::OP_AND, stringy_comp_addr, stringy_comp_addr_2);
+ codegen.generator->write_binary_operator(result_addr, Variant::OP_OR, result_addr, stringy_comp_addr);
+
+ codegen.generator->pop_temporary(); // Remove expr_type_addr from stack.
+ codegen.generator->pop_temporary(); // Remove stringy_comp_addr_2 from stack.
+ codegen.generator->pop_temporary(); // Remove stringy_comp_addr from stack.
+
codegen.generator->write_and_left_operand(result_addr);
// Check value equality.
@@ -1380,7 +1413,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c
if (expr_addr.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
- codegen.generator->pop_temporary(); // Remove type equality temporary.
+ codegen.generator->pop_temporary(); // Remove equality_test_addr from stack.
// If this isn't the first, we need to OR with the previous pattern. If it's nested, we use AND instead.
if (p_is_nested) {
diff --git a/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.gd b/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.gd
deleted file mode 100644
index 55be021a90..0000000000
--- a/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.gd
+++ /dev/null
@@ -1,14 +0,0 @@
-# https://github.com/godotengine/godot/issues/60145
-
-func test():
- match "abc":
- &"abc":
- print("String matched StringName")
- _:
- print("no match")
-
- match &"abc":
- "abc":
- print("StringName matched String")
- _:
- print("no match")
diff --git a/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.out b/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.out
deleted file mode 100644
index 9d5a18da3d..0000000000
--- a/modules/gdscript/tests/scripts/runtime/features/match_string_stringname_equivalent.out
+++ /dev/null
@@ -1,3 +0,0 @@
-GDTEST_OK
-String matched StringName
-StringName matched String
diff --git a/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.gd b/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.gd
index f8bd46523e..0dd40520b0 100644
--- a/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.gd
+++ b/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.gd
@@ -1,4 +1,8 @@
# https://github.com/godotengine/godot/issues/64171
+# https://github.com/godotengine/godot/issues/60145
+
+var s = "abc"
+var sn = &"abc"
func test():
print("Compare ==: ", "abc" == &"abc")
@@ -9,3 +13,27 @@ func test():
print("Concat: ", "abc" + &"def")
print("Concat: ", &"abc" + "def")
print("Concat: ", &"abc" + &"def")
+
+ match "abc":
+ &"abc":
+ print("String matched StringName literal")
+ _:
+ print("no Match")
+
+ match &"abc":
+ "abc":
+ print("StringName matched String literal")
+ _:
+ print("no Match")
+
+ match "abc":
+ sn:
+ print("String matched StringName")
+ _:
+ print("no match")
+
+ match &"abc":
+ s:
+ print("StringName matched String")
+ _:
+ print("no match")
diff --git a/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.out b/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.out
index 7e9c364b60..440b613099 100644
--- a/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.out
+++ b/modules/gdscript/tests/scripts/runtime/features/string_stringname_equivalent.out
@@ -6,3 +6,7 @@ Compare !=: false
Concat: abcdef
Concat: abcdef
Concat: abcdef
+String matched StringName literal
+StringName matched String literal
+String matched StringName
+StringName matched String