package Models.Statements; import Exceptions.BaseException; import Models.Expressions.IExpression; import Models.Program.IDictionary; import Models.Program.ProgramState; import Models.Types.IType; import Models.Types.ReferenceType; import Models.Values.ReferenceValue; public class WriteHeap implements IStatement { private String variableName; private IExpression expression; public WriteHeap(String variableName, IExpression expression) { this.variableName = variableName; this.expression = expression; } public ProgramState execute(ProgramState state) throws BaseException { var symbolTable = state.getSymbolTable(); var heap = state.getHeap(); if(!symbolTable.contains(this.variableName)) { throw new BaseException("Variable " + this.variableName + " is not defined"); } if(!(symbolTable.get(this.variableName) instanceof ReferenceValue)) { throw new BaseException("Variable " + this.variableName + " is not a reference value"); } int address = ((ReferenceValue)symbolTable.get(this.variableName)).getAddress(); if(!heap.contains(address)) { throw new BaseException("Address " + address + " is not in the heap"); } var heapValue = heap.get(address); var expressionValue = this.expression.evaluate(symbolTable, heap); if(!heapValue.getType().equals(expressionValue.getType())) { throw new BaseException("Types do not match"); } heap.update(address, expressionValue); return null; } public IStatement copy() { return new WriteHeap(this.variableName, this.expression.copy()); } public String toString() { return "writeHeap(" + this.variableName + ", " + this.expression.toString() + ")"; } public IDictionary typeCheck(IDictionary typeTable) throws BaseException { var variableType = typeTable.get(this.variableName); var expressionType = this.expression.typeCheck(typeTable); if(!variableType.equals(new ReferenceType(expressionType))) { throw new BaseException("Types do not match"); } return typeTable; } }