Variable readerValue = s.getNewTemporaryVariable();
Variable writerValue = s.getNewTemporaryVariable();
// get attr
Operand v1 = build(opAsgnNode.getReceiverNode(), s);
s.addInstr(CallInstr.create(readerValue, new MethAddr(opAsgnNode.getVariableName()), v1, NO_ARGS, null));
// Ex: e.val ||= n
// e.val &&= n
String opName = opAsgnNode.getOperatorName();
if (opName.equals("||") || opName.equals("&&")) {
l = s.getNewLabel();
s.addInstr(BEQInstr.create(readerValue, opName.equals("||") ? manager.getTrue() : manager.getFalse(), l));
// compute value and set it
Operand v2 = build(opAsgnNode.getValueNode(), s);
s.addInstr(CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {v2}, null));
// It is readerValue = v2.
// readerValue = writerValue is incorrect because the assignment method
// might return something else other than the value being set!
s.addInstr(new CopyInstr(readerValue, v2));
s.addInstr(new LabelInstr(l));
return readerValue;
}
// Ex: e.val = e.val.f(n)
else {
// call operator
Operand v2 = build(opAsgnNode.getValueNode(), s);
Variable setValue = s.getNewTemporaryVariable();
s.addInstr(CallInstr.create(setValue, new MethAddr(opAsgnNode.getOperatorName()), readerValue, new Operand[]{v2}, null));
// set attr
s.addInstr(CallInstr.create(writerValue, new MethAddr(opAsgnNode.getVariableNameAsgn()), v1, new Operand[] {setValue}, null));
// Returning writerValue is incorrect becuase the assignment method
// might return something else other than the value being set!
return setValue;
}
}