mirror of
https://github.com/godotengine/godot
synced 2024-10-06 13:40:19 +00:00
GDScript: Fix member assignment with operation
It was wrongly updating the assigned value with the result of the operation.
This commit is contained in:
parent
adc9500e54
commit
84956fee4b
|
@ -1019,25 +1019,32 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
|
||||||
}
|
}
|
||||||
} else if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER && _is_class_member_property(codegen, static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name)) {
|
} else if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER && _is_class_member_property(codegen, static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name)) {
|
||||||
// Assignment to member property.
|
// Assignment to member property.
|
||||||
GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value);
|
GDScriptCodeGenerator::Address assigned_value = _parse_expression(codegen, r_error, assignment->assigned_value);
|
||||||
if (r_error) {
|
if (r_error) {
|
||||||
return GDScriptCodeGenerator::Address();
|
return GDScriptCodeGenerator::Address();
|
||||||
}
|
}
|
||||||
GDScriptCodeGenerator::Address assign_temp = assigned;
|
|
||||||
|
GDScriptCodeGenerator::Address to_assign = assigned_value;
|
||||||
|
bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE;
|
||||||
|
|
||||||
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
|
StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name;
|
||||||
|
|
||||||
if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
|
if (has_operation) {
|
||||||
|
GDScriptCodeGenerator::Address op_result = codegen.add_temporary();
|
||||||
GDScriptCodeGenerator::Address member = codegen.add_temporary();
|
GDScriptCodeGenerator::Address member = codegen.add_temporary();
|
||||||
gen->write_get_member(member, name);
|
gen->write_get_member(member, name);
|
||||||
gen->write_binary_operator(assigned, assignment->variant_op, member, assigned);
|
gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value);
|
||||||
gen->pop_temporary();
|
gen->pop_temporary(); // Pop member temp.
|
||||||
|
to_assign = op_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gen->write_set_member(assigned, name);
|
gen->write_set_member(to_assign, name);
|
||||||
|
|
||||||
if (assign_temp.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
if (to_assign.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
||||||
gen->pop_temporary();
|
gen->pop_temporary(); // Pop the assigned expression or the temp result if it has operation.
|
||||||
|
}
|
||||||
|
if (has_operation && assigned_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
|
||||||
|
gen->pop_temporary(); // Pop the assigned expression if not done before.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Regular assignment.
|
// Regular assignment.
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
func test():
|
||||||
|
process_priority = 10
|
||||||
|
var change = 20
|
||||||
|
|
||||||
|
print(process_priority)
|
||||||
|
print(change)
|
||||||
|
|
||||||
|
process_priority += change
|
||||||
|
|
||||||
|
print(process_priority)
|
||||||
|
print(change)
|
|
@ -0,0 +1,5 @@
|
||||||
|
GDTEST_OK
|
||||||
|
10
|
||||||
|
20
|
||||||
|
30
|
||||||
|
20
|
Loading…
Reference in a new issue