slcom/slangc/model/expressions/AssignmentExpression.sauce

124 lines
3.9 KiB
Plaintext

package slangc.model.expressions;
import slangc.api.BytecodeInstructionWriter;
import slangc.api.Reporter;
import slangc.bytecode.TypeSignature;
import slangc.model.ExpressionModel;
import slangc.model.ExpressionOwner;
import slangc.model.ExpressionResult;
import slangc.model.InnerTypeScope;
import slangc.model.MemberModel;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class AssignmentExpression extends ExpressionModel implements ExpressionOwner {
ExpressionModel leftHandSide;
String operator;
ExpressionModel rightHandSide;
public AssignmentExpression(ExpressionOwner owner, Node source) {
super(owner, source);
leftHandSide = ExpressionModel.construct(this, ((Branch)source).getSubnode(0));
operator = BinaryExpression.getOpName(((Branch)source).getSubnode(1));
operator = operator.sub(0, operator.ints().length-1);
rightHandSide = ExpressionModel.construct(this, ((Branch)source).getSubnode(2));
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Assignment expression (" + getSource().getNodeType() + ")");
dumpResolved(reporter, indent + incr, incr);
leftHandSide.dump(reporter, indent + incr, incr);
rightHandSide.dump(reporter, indent + incr, incr);
}
@Override
public TypeModel getExpectedResult(ExpressionModel e) {
if (e == rightHandSide && leftHandSide.isResolved()) {
return leftHandSide.getResult().getValueType();
} else {
return null;
}
}
@Override
protected ExpressionResult resolveResult() {
return new ExpressionResult.TypedValue(leftHandSide.getResult().getValueType());
}
@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
@Override
public ExpressionModel[] getSubexpressions() {
return new ExpressionModel[] {leftHandSide, rightHandSide};
}
@Override
public TypeSignature innerGenerate(BytecodeInstructionWriter w) {
TypeSignature storing = null;
if (usesOperator()) {
getLeftHandSide().generate(w);
getRightHandSide().generate(w);
if (leftHandSide.getResult() == null || rightHandSide.getResult() == null) {
w.genError("Bad assignment");
return null;
} else {
storing = BinaryExpression.generateALUOp(w, leftHandSide.getResult().getValueTypeWithNullType(getSystem().getDefaultBaseType()), getOperator(), rightHandSide.getResult().getValueTypeWithNullType(getSystem().getDefaultBaseType())).getTypeSignature();
}
} else {
storing = getRightHandSide().generate(w);
}
if (!storing.mappableEquals(leftHandSide.getResult().getValueType().getTypeSignature())) {
w.genConvert(storing, leftHandSide.getResult().getValueType().getTypeSignature());
storing = leftHandSide.getResult().getValueType().getTypeSignature();
}
getLeftHandSide().generateStore(w, storing);
return getLeftHandSide().generate(w);
/* TODO: Optimised += and co
TypeSignature contextType = leftHandSide.generateAssignContext(w);
if (usesOperator()) {
w.genDup(contextType);
leftHandSide.generateAssignLoad(w);
rightHandSide.generate(w);
BinaryExpression.generateALUOp(leftHandSide.getResult().getValueType(), getOperator(), rightHandSide.getResult().getValueType());
}
w.genError("TODO: innerGenerate for " + Type.of(this));
return null;
*/
}
/** Returns the operator used in this assignment (will be an empty string if no operator used). */
public String getOperator() {
return operator;
}
public boolean usesOperator() {
return !operator.equals("");
}
public ExpressionModel getLeftHandSide() {
return leftHandSide;
}
public ExpressionModel getRightHandSide() {
return rightHandSide;
}
}