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 NewStatement implements IStatement { private String variableName; private IExpression expression; public NewStatement(String variableName, IExpression expression) { this.variableName = variableName; this.expression = expression; } public IStatement copy() { return new NewStatement(this.variableName, this.expression.copy()); } public String toString() { return "new(" + this.variableName + ", " + this.expression.toString() + ")"; } public ProgramState execute(ProgramState programState) throws BaseException { var symbolTable = programState.getSymbolTable(); var heap = programState.getHeap(); if (!symbolTable.contains(this.variableName)) { throw new BaseException("NewStatement: Variable is not defined"); } var value = symbolTable.get(this.variableName); var expressionValue = this.expression.evaluate(symbolTable, heap); if (!value.getType().equals(new ReferenceType(expressionValue.getType()))) { throw new BaseException("NewStatement: Variable is not of type ReferenceType"); } var address = heap.add(expressionValue); symbolTable.update(this.variableName, new ReferenceValue(address, expressionValue.getType())); return null; } 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("NewStatement: Right hand side and Left hand side have different types"); } return typeTable; } }