GDScript: Fix member assignment with operation

It was wrongly updating the assigned value with the result of the
operation.
This commit is contained in:
George Marques 2021-09-21 16:23:42 -03:00
parent adc9500e54
commit 84956fee4b
No known key found for this signature in database
GPG key ID: 046BD46A3201E43D
3 changed files with 33 additions and 8 deletions

View file

@ -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.

View file

@ -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)

View file

@ -0,0 +1,5 @@
GDTEST_OK
10
20
30
20