package slangc.model.expressions; import slangc.api.BytecodeInstructionWriter; import slangc.api.Reporter; import slangc.bytecode.TypeSignature; import slangc.model.ArrayTypeModel; import slangc.model.ExpressionModel; import slangc.model.ExpressionOwner; import slangc.model.ExpressionResult; import slangc.model.TypeModel; import slangc.parser.Branch; import slangc.parser.ErrorType; import slangc.parser.Node; public class ArrayIndexExpression extends ExpressionModel implements ExpressionOwner { private ExpressionModel leftHandSide; private ExpressionModel indexExpression; public ArrayIndexExpression(ExpressionOwner owner, Node source) { super(owner, source); leftHandSide = ExpressionModel.construct(this, ((Branch)source).getSubnode(0)); indexExpression = ExpressionModel.construct(this, ((Branch)source).getSubnode(2)); } @Override public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> Array index expression:"); dumpResolved(reporter, indent + incr, incr); leftHandSide.dump(reporter, indent + incr, incr); indexExpression.dump(reporter, indent + incr, incr); } @Override public TypeModel getExpectedResult(ExpressionModel e) { // TODO Auto-generated method stub return null; } public ExpressionModel getLeftHandSide() { return leftHandSide; } public ExpressionModel getIndexExpression() { return indexExpression; } @Override public ExpressionModel[] getSubexpressions() { return new ExpressionModel[] {leftHandSide, indexExpression}; } @Override protected ExpressionResult resolveResult() { if (leftHandSide.getResult().resolvesToValueOrNull() && leftHandSide.getResult().getKind() != ExpressionResult.Kind.NULL) { TypeModel lhsType = leftHandSide.getResult().getValueType(); if (lhsType instanceof ArrayTypeModel) { ArrayTypeModel arrayType = (ArrayTypeModel)lhsType; return new ExpressionResult.PointsToStorageSlot(arrayType); } else { getSource().annotate(ErrorType.INTERNAL_ERROR, "Left hand side of an array index expression should be an array type, got " + lhsType + " instead"); return ExpressionResult.INVALID; } } else { getSource().annotate(ErrorType.INTERNAL_ERROR, "Couldn't make sense of left-hand-side of array index expression expecting a typeName but got " + leftHandSide.getResult()); return ExpressionResult.INVALID; } } @Override public TypeSignature innerGenerate(BytecodeInstructionWriter w) { getLeftHandSide().generate(w); getIndexExpression().generate(w); w.genArrayLoad(getResult().getValueType().getTypeSignature()); return getResult().getValueType().getTypeSignature(); } @Override public void generateStore(BytecodeInstructionWriter w, TypeSignature storing) { getLeftHandSide().generate(w); getIndexExpression().generate(w); w.genArrayStore(getResult().getValueType().getTypeSignature()); } public TypeModel resolveType(Node n) { return super.resolveType(n); // TODO: Better support for interfaces } }