School Commit Init

This commit is contained in:
2024-08-31 12:07:21 +03:00
commit 0b130ee18c
2801 changed files with 4720552 additions and 0 deletions
@@ -0,0 +1,54 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Expressions.IExpression;
import Models.Program.IDictionary;
import Models.Program.IHeap;
import Models.Program.ProgramState;
import Models.Types.IType;
import Models.Values.IValue;
public class AssignmentStatement implements IStatement {
private String variableName;
private IExpression expression;
public AssignmentStatement(String variableName, IExpression expression) {
this.variableName = variableName;
this.expression = expression;
}
public String toString() {
return variableName + " = " + expression.toString();
}
public IStatement copy() {
return new AssignmentStatement(variableName, expression.copy());
}
public ProgramState execute(ProgramState state) throws BaseException {
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
IHeap heap = state.getHeap();
if(symbolTable.contains(variableName)) {
IValue value = expression.evaluate(symbolTable, heap);
IType variableType = (symbolTable.get(variableName)).getType();
if(value.getType().equals(variableType)) {
symbolTable.update(variableName, value);
} else {
throw new BaseException("Declared type of variable " + variableName + " and type of the assigned expression do not match!");
}
} else {
throw new BaseException("Variable " + variableName + " is not defined!");
}
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
IType variableType = typeTable.get(variableName);
IType expressionType = expression.typeCheck(typeTable);
if(variableType.equals(expressionType)) {
return typeTable;
} else {
throw new BaseException("Declared type of variable " + variableName + " and type of the assigned expression do not match!");
}
}
}
@@ -0,0 +1,52 @@
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.StringType;
import Models.Values.StringValue;
public class CloseReadFileStatement implements IStatement{
private IExpression expression;
public CloseReadFileStatement(IExpression expression){
this.expression = expression;
}
public IStatement copy(){
return new CloseReadFileStatement(this.expression.copy());
}
public String toString(){
return "closeRFile(" + this.expression.toString() + ")";
}
public ProgramState execute(ProgramState programState) throws BaseException{
var value = this.expression.evaluate(programState.getSymbolTable(), programState.getHeap());
if(!value.getType().equals(new StringType())){
throw new BaseException("CloseReadFileStatement: Expression is not of type StringType");
}
if(!programState.getFileTable().contains((StringValue)value)){
throw new BaseException("CloseReadFileStatement: File is not open");
}
var bufferedReader = programState.getFileTable().get((StringValue)value);
try{
bufferedReader.close();
}
catch(Exception exception){
throw new BaseException("CloseReadFileStatement: File could not be closed");
}
programState.getFileTable().remove((StringValue)value);
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
var expressionType = this.expression.typeCheck(typeTable);
if(!expressionType.equals(new StringType())){
throw new BaseException("CloseReadFileStatement: Expression is not of type StringType");
}
return typeTable;
}
}
@@ -0,0 +1,40 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Program.IDictionary;
import Models.Program.IStack;
import Models.Program.ProgramState;
import Models.Types.IType;
public class CompoundStatement implements IStatement {
//region Fields
private IStatement first;
private IStatement second;
//endregion
//region Exposed Methods
public CompoundStatement(IStatement first, IStatement second){
this.first = first;
this.second = second;
}
public String toString(){
return "(" + first.toString() + ";" + second.toString() + ")";
}
public IStatement copy(){
return new CompoundStatement(first.copy(), second.copy());
}
public ProgramState execute(ProgramState state){
IStack<IStatement> stack = state.getStack();
stack.push(second);
stack.push(first);
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
return second.typeCheck(first.typeCheck(typeTable));
}
//endregion
}
@@ -0,0 +1,33 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Program.GenericStack;
import Models.Program.IDictionary;
import Models.Program.ProgramState;
import Models.Types.IType;
public class ForkStatement implements IStatement {
private IStatement statement;
public ForkStatement(IStatement statement) {
this.statement = statement;
}
public ProgramState execute(ProgramState state) throws BaseException {
ProgramState forkedProgramState = new ProgramState(new GenericStack<IStatement>(), state.getSymbolTable().copy(), state.getOutput(), state.getFileTable(), state.getHeap(), this.statement);
return forkedProgramState;
}
public IStatement copy() {
return new ForkStatement(this.statement.copy());
}
public String toString() {
return "fork(" + this.statement.toString() + ")";
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
this.statement.typeCheck(typeTable.copy());
return typeTable;
}
}
@@ -0,0 +1,12 @@
package Models.Statements;
import Models.Program.IDictionary;
import Models.Program.ProgramState;
import Models.Types.IType;
import Exceptions.BaseException;
public interface IStatement{
public ProgramState execute(ProgramState state) throws BaseException;
public IStatement copy();
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException;
}
@@ -0,0 +1,60 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Expressions.IExpression;
import Models.Program.IDictionary;
import Models.Program.IHeap;
import Models.Program.ProgramState;
import Models.Types.BooleanType;
import Models.Types.IType;
import Models.Values.BooleanValue;
import Models.Values.IValue;
public class IfStatement implements IStatement {
private IStatement thenStatement;
private IStatement elseStatement;
private IExpression condition;
public IfStatement(IExpression condition, IStatement thenStatement, IStatement elseStatement) {
this.condition = condition;
this.thenStatement = thenStatement;
this.elseStatement = elseStatement;
}
public String toString() {
return "(if(" + condition.toString() + ") then(" + thenStatement.toString() + ") else(" + elseStatement.toString() + "))";
}
public IStatement copy() {
return new IfStatement(condition.copy(), thenStatement.copy(), elseStatement.copy());
}
public ProgramState execute(ProgramState state) throws BaseException {
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
IHeap heap = state.getHeap();
IValue conditionValue = condition.evaluate(symbolTable, heap);
if (conditionValue.getType().equals(new BooleanType())) {
boolean conditionBool = ((BooleanValue)conditionValue).getValue();
if (conditionBool) {
thenStatement.execute(state);
} else {
elseStatement.execute(state);
}
} else {
throw new BaseException("Condition is not a boolean!");
}
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
IType conditionType = condition.typeCheck(typeTable);
if (conditionType.equals(new BooleanType())) {
thenStatement.typeCheck(typeTable.copy());
elseStatement.typeCheck(typeTable.copy());
return typeTable;
} else {
throw new BaseException("Condition is not a boolean!");
}
}
}
@@ -0,0 +1,52 @@
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<String, IType> typeCheck(IDictionary<String, IType> 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;
}
}
@@ -0,0 +1,23 @@
package Models.Statements;
import Models.Program.IDictionary;
import Models.Program.ProgramState;
import Models.Types.IType;
public class NopStatement implements IStatement {
public String toString() {
return "";
}
public IStatement copy() {
return new NopStatement();
}
public ProgramState execute(ProgramState state) {
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) {
return typeTable;
}
}
@@ -0,0 +1,57 @@
package Models.Statements;
import java.io.BufferedReader;
import java.io.FileReader;
import Exceptions.BaseException;
import Models.Expressions.IExpression;
import Models.Program.IDictionary;
import Models.Program.ProgramState;
import Models.Types.IType;
import Models.Types.StringType;
import Models.Values.StringValue;
public class OpenReadFileStatement implements IStatement {
private IExpression expression;
public OpenReadFileStatement(IExpression expression){
this.expression = expression;
}
public ProgramState execute(ProgramState programState) throws BaseException{
var value = this.expression.evaluate(programState.getSymbolTable(), programState.getHeap());
if(!value.getType().equals(new StringType())){
throw new BaseException("OpenReadFileStatement: Expression is not of type StringType");
}
var stringValue = (StringValue)value;
if(programState.getFileTable().contains(stringValue)){
throw new BaseException("OpenReadFileStatement: File is already open");
}
BufferedReader bufferedReader;
try{
bufferedReader = new BufferedReader(new FileReader(stringValue.getValue()));
}
catch(Exception exception){
throw new BaseException("OpenReadFileStatement: File does not exist");
}
programState.getFileTable().add(stringValue, bufferedReader);
return null;
}
public IStatement copy(){
return new OpenReadFileStatement(this.expression.copy());
}
public String toString(){
return "openRFile(" + this.expression.toString() + ")";
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
var expressionType = this.expression.typeCheck(typeTable);
if(!expressionType.equals(new StringType())){
throw new BaseException("OpenReadFileStatement: Expression is not of type StringType");
}
return typeTable;
}
}
@@ -0,0 +1,39 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Expressions.IExpression;
import Models.Program.IDictionary;
import Models.Program.IQueue;
import Models.Program.ProgramState;
import Models.Types.IType;
import Models.Values.IValue;
public class PrintStatement implements IStatement {
//region Fields
private IExpression expression;
//endregion
//region Exposed Methods
public PrintStatement(IExpression expression){
this.expression = expression;
}
public String toString(){
return "print(" + expression.toString() + ")";
}
public IStatement copy(){
return new PrintStatement(expression.copy());
}
public ProgramState execute(ProgramState state) throws BaseException{
IQueue<IValue> output = state.getOutput();
output.enqueue(expression.evaluate(state.getSymbolTable(), state.getHeap() ));
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
expression.typeCheck(typeTable);
return typeTable;
}
//endregion
}
@@ -0,0 +1,74 @@
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.IntegerType;
import Models.Types.StringType;
import Models.Values.IntegerValue;
import Models.Values.StringValue;
public class ReadFileStatement implements IStatement{
private IExpression expression;
private String variableName;
public ReadFileStatement(IExpression expression, String variableName){
this.expression = expression;
this.variableName = variableName;
}
public IStatement copy(){
return new ReadFileStatement(this.expression.copy(), this.variableName);
}
public String toString(){
return "readFile(" + this.expression.toString() + ", " + this.variableName + ")";
}
public ProgramState execute(ProgramState programState) throws BaseException{
var symbolTable = programState.getSymbolTable();
var fileTable = programState.getFileTable();
var heap = programState.getHeap();
if(!symbolTable.contains(this.variableName)){
throw new BaseException("ReadFileStatement: Variable is not defined");
}
var value = symbolTable.get(this.variableName);
if(!value.getType().equals(new IntegerType())){
throw new BaseException("ReadFileStatement: Variable is not of type IntegerType");
}
var expressionValue = this.expression.evaluate(symbolTable, heap);
if(!expressionValue.getType().equals(new StringType())){
throw new BaseException("ReadFileStatement: Expression is not of type StringType");
}
if(!fileTable.contains((StringValue)expressionValue)){
throw new BaseException("ReadFileStatement: File is not open");
}
var bufferedReader = fileTable.get((StringValue)expressionValue);
try{
var line = bufferedReader.readLine();
if(line == null){
line = "0";
}
symbolTable.update(this.variableName, new IntegerValue(Integer.parseInt(line)));
}
catch(Exception exception){
throw new BaseException("ReadFileStatement: File is empty");
}
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
var expressionType = this.expression.typeCheck(typeTable);
if(!expressionType.equals(new StringType())){
throw new BaseException("ReadFileStatement: Expression is not of type StringType");
}
var variableType = typeTable.get(this.variableName);
if(!variableType.equals(new IntegerType())){
throw new BaseException("ReadFileStatement: Variable is not of type IntegerType");
}
return typeTable;
}
}
@@ -0,0 +1,41 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Program.IDictionary;
import Models.Program.ProgramState;
import Models.Types.IType;
import Models.Values.IValue;
public class VariableDeclarationStatement implements IStatement {
private String variableName;
private IType variableType;
public VariableDeclarationStatement(String variableName, IType variableType) {
this.variableName = variableName;
this.variableType = variableType;
}
public String toString() {
return variableType.toString() + " " + variableName;
}
public IStatement copy() {
return new VariableDeclarationStatement(variableName, variableType);
}
public ProgramState execute(ProgramState state) throws BaseException {
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
if(!symbolTable.contains(variableName)) {
symbolTable.add(variableName, variableType.defaultValue());
} else {
throw new BaseException("Variable " + variableName + " is already defined!");
}
return null;
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
typeTable.add(variableName, variableType);
return typeTable;
}
}
@@ -0,0 +1,58 @@
package Models.Statements;
import Exceptions.BaseException;
import Models.Expressions.IExpression;
import Models.Program.IDictionary;
import Models.Program.IHeap;
import Models.Program.IStack;
import Models.Program.ProgramState;
import Models.Types.BooleanType;
import Models.Types.IType;
import Models.Values.IValue;
import Models.Values.BooleanValue;
public class WhileStatement implements IStatement {
private IStatement statement;
private IExpression expression;
public WhileStatement(IStatement statement, IExpression expression) {
this.statement = statement;
this.expression = expression;
}
public ProgramState execute(ProgramState state) throws BaseException {
IStack<IStatement> stack = state.getStack();
IHeap heap = state.getHeap();
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
IValue condition = expression.evaluate(symbolTable, heap);
if (!condition.getType().equals(new BooleanType())) {
throw new BaseException("Condition is not a boolean.");
}
if (((BooleanValue) condition).getValue()) {
stack.push(this);
stack.push(statement);
}
return null;
}
public String toString() {
return "while(" + expression.toString() + ") {" + statement.toString() + "}";
}
public IStatement copy() {
return new WhileStatement(statement.copy(), expression.copy());
}
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
IType expressionType = expression.typeCheck(typeTable);
if (expressionType.equals(new BooleanType())) {
statement.typeCheck(typeTable.copy());
return typeTable;
} else {
throw new BaseException("Condition is not a boolean!");
}
}
}
@@ -0,0 +1,58 @@
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<String, IType> typeCheck(IDictionary<String, IType> 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;
}
}