mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-01 06:01:14 +00:00 
			
		
		
		
	Merge pull request #78389 from rune-scape/rune-match-stringnames
GDScript: Strings and StringNames match
This commit is contained in:
		
						commit
						c211c22abc
					
				
					 5 changed files with 87 additions and 39 deletions
				
			
		|  | @ -1342,7 +1342,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; | ||||
|  | @ -1350,29 +1351,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); | ||||
| 
 | ||||
| 			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 StringName <-> String 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_stringname_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.
 | ||||
| 			} else if (literal_type == Variant::STRING_NAME) { | ||||
| 				GDScriptCodeGenerator::Address type_string_addr = codegen.add_constant(Variant::STRING); | ||||
| 
 | ||||
| 				// Check String <-> StringName 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_string_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.
 | ||||
| 			} | ||||
| 
 | ||||
| 			codegen.generator->write_and_left_operand(type_equality_addr); | ||||
| 
 | ||||
|  | @ -1419,9 +1422,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; | ||||
|  | @ -1433,10 +1449,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.
 | ||||
|  | @ -1450,7 +1483,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) { | ||||
|  |  | |||
|  | @ -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") | ||||
|  | @ -1,3 +0,0 @@ | |||
| GDTEST_OK | ||||
| String matched StringName | ||||
| StringName matched String | ||||
|  | @ -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") | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde