diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java index d10a28ec4..ff1a8b9e0 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionBinary.java @@ -269,4 +269,60 @@ public interface ProgramExpressionBinary extends ProgramExpression { getConstantBinary().setRight(new ConstantCastValue(toType, getConstantBinary().getRight())); } } + + /** Binary expression that is an indexed dereference of a pointer eg. ptr[i] or *(ptr+i). */ + class ProgramExpressionBinaryPointerDereferenceIndexed implements ProgramExpressionBinary { + /** A program value containing a {@link ConstantBinary}. */ + private ProgramValue programValue; + + public ProgramExpressionBinaryPointerDereferenceIndexed(ProgramValue programValue) { + this.programValue = programValue; + } + + public PointerDereferenceIndexed getPointerDereferenceIndexed() { + return (PointerDereferenceIndexed) programValue.get(); + } + + @Override + public RValue getLeft() { + return getPointerDereferenceIndexed().getPointer(); + } + + @Override + public OperatorBinary getOperator() { + return Operators.PLUS; + } + + @Override + public RValue getRight() { + return getPointerDereferenceIndexed().getIndex(); + } + + @Override + public void set(Value value) { + programValue.set(value); + } + + @Override + public void addLeftCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(getPointerDereferenceIndexed().getPointer() instanceof ConstantValue) { + getPointerDereferenceIndexed().setPointer(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getPointer())); + } else { + // Try to use CastValue - may later have to be supported! + getPointerDereferenceIndexed().setPointer(new CastValue(toType, getPointerDereferenceIndexed().getPointer())); + } + } + + @Override + public void addRightCast(SymbolType toType, ListIterator stmtIt, ScopeRef currentScope, ProgramScope symbols) { + if(getPointerDereferenceIndexed().getIndex() instanceof ConstantValue) { + getPointerDereferenceIndexed().setIndex(new ConstantCastValue(toType, (ConstantValue) getPointerDereferenceIndexed().getIndex())); + } else { + // Try to use CastValue - may later have to be supported! + getPointerDereferenceIndexed().setIndex(new CastValue(toType, getPointerDereferenceIndexed().getIndex())); + } + } + } + + } diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java index e525c101f..c109a3001 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramExpressionIterator.java @@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementConditionalJump; import dk.camelot64.kickc.model.values.ConstantBinary; import dk.camelot64.kickc.model.values.ConstantUnary; +import dk.camelot64.kickc.model.values.PointerDereferenceIndexed; import java.util.ListIterator; @@ -25,13 +26,16 @@ public class ProgramExpressionIterator { */ public static void execute(Program program, ProgramExpressionHandler handler) { // Iterate all symbols - ProgramValueIterator.execute(program.getScope(), (programValue, currentStmt, stmtIt, currentBlock) -> { + ProgramValueHandler programValueHandler = (programValue, currentStmt, stmtIt, currentBlock) -> { if(programValue.get() instanceof ConstantBinary) { handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryConstant(programValue), null, null, null); } else if(programValue.get() instanceof ConstantUnary) { handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryConstant(programValue), null, null, null); + } else if(programValue.get() instanceof PointerDereferenceIndexed) { + handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryPointerDereferenceIndexed(programValue), null, null, null); } - }); + }; + ProgramValueIterator.execute(program.getScope(), programValueHandler); // Iterate all blocks/statements for(ControlFlowBlock block : program.getGraph().getAllBlocks()) { @@ -53,14 +57,7 @@ public class ProgramExpressionIterator { } } // Iterate all statement values - ProgramValueIterator.execute(stmt, (programValue, currentStmt, stmtIt1, currentBlock) -> { - if(programValue.get() instanceof ConstantBinary) { - handler.execute(new ProgramExpressionBinary.ProgramExpressionBinaryConstant(programValue), stmt, stmtIt, block); - } else if(programValue.get() instanceof ConstantUnary) { - handler.execute(new ProgramExpressionUnary.ProgramExpressionUnaryConstant(programValue), stmt, stmtIt, block); - } - - }, stmtIt, block); + ProgramValueIterator.execute(stmt, programValueHandler, stmtIt, block); } } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java index 16688948f..6854e09b0 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNAddNumberTypeConversions.java @@ -30,13 +30,13 @@ public class PassNAddNumberTypeConversions extends Pass2SsaOptimization { // Convert both left and right to the found type SymbolType leftType = SymbolTypeInference.inferType(getProgram().getScope(), left); if(!leftType.equals(conversionType) && !(leftType instanceof SymbolTypePointer)) { - getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getLeft().toString() + " in " + currentStmt.toString(getProgram(), false)); - binary.addLeftCast(conversionType, stmtIt, currentBlock.getScope(), getScope()); + getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getLeft().toString() + " in " + (currentStmt==null?"":currentStmt.toString(getProgram(), false))); + binary.addLeftCast(conversionType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); } SymbolType rightType = SymbolTypeInference.inferType(getProgram().getScope(), right); if(!rightType.equals(conversionType) && !(rightType instanceof SymbolTypePointer)) { - getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getRight().toString() + " in " + currentStmt.toString(getProgram(), false)); - binary.addRightCast(conversionType, stmtIt, currentBlock.getScope(), getScope()); + getLog().append("Adding number conversion cast (" + conversionType + ") " + binary.getRight().toString() + " in " + ((currentStmt==null)?"":currentStmt.toString(getProgram(), false))); + binary.addRightCast(conversionType, stmtIt, currentBlock==null?null:currentBlock.getScope(), getScope()); } } }