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 CountExpression extends ExpressionModel implements ExpressionOwner { ExpressionModel leftHandSide; String operator; public CountExpression(ExpressionOwner owner, Node source) { super(owner, source); leftHandSide = ExpressionModel.construct(this, ((Branch)source).getSubnode(0)); operator = BinaryExpression.getOpName(((Branch)source).getSubnode(1)); } @Override public void dump(Reporter reporter, String indent, String incr) { reporter.note("DUMP", indent + "> Count expression (" + getSource().getNodeType() + ")"); dumpResolved(reporter, indent + incr, incr); leftHandSide.dump(reporter, indent + incr, incr); } @Override public ExpressionModel[] getSubexpressions() { return new ExpressionModel[] {leftHandSide}; } @Override public TypeModel getExpectedResult(ExpressionModel e) { // TODO not sure if relevant here return null; } @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 protected ExpressionResult resolveResult() { if (leftHandSide.getResult().resolvesToValue()) { return new ExpressionResult.TypedValue(leftHandSide.getResult().getValueType()); } else { return ExpressionResult.INVALID; } } @Override public TypeSignature innerGenerate(BytecodeInstructionWriter w) { TypeSignature lhsType = leftHandSide.generate(w); w.genDup(lhsType); w.genConst(w.getTarget().getHeap().getConstInt32("1")); if (operator.equals("++")) { TypeModel rt = BinaryExpression.generateALUOp(w, leftHandSide.getResult().getValueType(), "+", getSystem().getDefaultInt32Type()); if (!rt.getTypeSignature().mappableEquals(leftHandSide.getResult().getValueType().getTypeSignature())) { w.genConvert(rt.getTypeSignature(), leftHandSide.getResult().getValueType().getTypeSignature()); } leftHandSide.generateStore(w, leftHandSide.getResult().getValueType().getTypeSignature()); return lhsType; } else if (operator.equals("--")) { TypeModel rt = BinaryExpression.generateALUOp(w, leftHandSide.getResult().getValueType(), "-", getSystem().getDefaultInt32Type()); if (!rt.getTypeSignature().mappableEquals(leftHandSide.getResult().getValueType().getTypeSignature())) { w.genConvert(rt.getTypeSignature(), leftHandSide.getResult().getValueType().getTypeSignature()); } leftHandSide.generateStore(w, leftHandSide.getResult().getValueType().getTypeSignature()); return lhsType; } else { w.genError("TODO: innerGenerate for " + Type.of(this) + " with '" + operator + "'"); return null; } } }