School Commit Init
This commit is contained in:
+104
@@ -0,0 +1,104 @@
|
||||
package Controllers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.ReferenceValue;
|
||||
import Repositories.IRepository;
|
||||
|
||||
public class Controller {
|
||||
private IRepository repository;
|
||||
private boolean displayFlag;
|
||||
private ExecutorService executor;
|
||||
|
||||
public Controller(IRepository repository, boolean displayFlag) {
|
||||
this.repository = repository;
|
||||
this.displayFlag = displayFlag;
|
||||
}
|
||||
|
||||
public List<ProgramState> removeCompletedPrograms(List<ProgramState> programStates) {
|
||||
return programStates.stream().filter(p -> p.isNotCompleted()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void oneStepForAllProgramStates(List<ProgramState> programStates) {
|
||||
programStates.forEach(programState -> {
|
||||
try{
|
||||
repository.logProgramStateExecution(programState);
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
List<Callable<ProgramState>> callList = programStates.stream().map((ProgramState p) -> (Callable<ProgramState>)(() -> {
|
||||
try{
|
||||
return p.oneStep();
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
})).filter(c -> c != null).collect(Collectors.toList());
|
||||
List<ProgramState> newProgramStates = new ArrayList<ProgramState>();
|
||||
try{
|
||||
newProgramStates = executor.invokeAll(callList).stream().map(future -> {
|
||||
try {
|
||||
return future.get();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}).filter(p -> p != null).collect(Collectors.toList());
|
||||
}
|
||||
catch(InterruptedException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
programStates.addAll(newProgramStates);
|
||||
programStates.forEach(programState -> {
|
||||
try{
|
||||
repository.logProgramStateExecution(programState);
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
repository.setProgramStates(programStates);
|
||||
}
|
||||
|
||||
public void allSteps() {
|
||||
executor = Executors.newFixedThreadPool(2);
|
||||
List<ProgramState> programStates = removeCompletedPrograms(repository.getProgramStates());
|
||||
while(programStates.size() > 0){
|
||||
programStates.get(0).getHeap().setContent(this.garbageCollector(this.getAddressesFromSymbolTable(programStates.stream().map(programState -> programState.getSymbolTable().getContent()).collect(Collectors.toList()), programStates.get(0).getHeap().getContent()), programStates.get(0).getHeap().getContent()));
|
||||
oneStepForAllProgramStates(programStates);
|
||||
programStates = removeCompletedPrograms(repository.getProgramStates());
|
||||
}
|
||||
executor.shutdownNow();
|
||||
repository.setProgramStates(programStates);
|
||||
}
|
||||
|
||||
public Hashtable<Integer, IValue> garbageCollector(Set<Integer> symbolTable, Hashtable<Integer, IValue> heap) {
|
||||
return heap.entrySet().stream().filter(e -> symbolTable.contains(e.getKey()))
|
||||
.collect(Hashtable::new, (m, e) -> m.put(e.getKey(), e.getValue()), Hashtable::putAll);
|
||||
}
|
||||
|
||||
public Set<Integer> getAddressesFromSymbolTable(List<Collection<IValue>> symbolTablesValues, Hashtable<Integer, IValue> heap) {
|
||||
return symbolTablesValues.stream().flatMap(Collection::stream).filter(v -> v instanceof ReferenceValue)
|
||||
.flatMap(v -> Stream.iterate(((ReferenceValue) v).getAddress(), Objects::nonNull, addr -> {
|
||||
var value = heap.get(addr);
|
||||
return value instanceof ReferenceValue ? ((ReferenceValue) value).getAddress() : null;
|
||||
})).distinct().collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package Exceptions;
|
||||
|
||||
public class BaseException extends Throwable {
|
||||
public BaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
import java.io.BufferedReader;
|
||||
|
||||
import Controllers.Controller;
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.ArithmeticExpression;
|
||||
import Models.Expressions.ReadHeap;
|
||||
import Models.Expressions.RelationalExpression;
|
||||
import Models.Expressions.ValueExpression;
|
||||
import Models.Expressions.VariableExpression;
|
||||
import Models.Program.GenericDictionary;
|
||||
import Models.Program.GenericQueue;
|
||||
import Models.Program.GenericStack;
|
||||
import Models.Program.Heap;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Statements.AssignmentStatement;
|
||||
import Models.Statements.CloseReadFileStatement;
|
||||
import Models.Statements.CompoundStatement;
|
||||
import Models.Statements.ForkStatement;
|
||||
import Models.Statements.IStatement;
|
||||
import Models.Statements.IfStatement;
|
||||
import Models.Statements.NewStatement;
|
||||
import Models.Statements.OpenReadFileStatement;
|
||||
import Models.Statements.PrintStatement;
|
||||
import Models.Statements.ReadFileStatement;
|
||||
import Models.Statements.VariableDeclarationStatement;
|
||||
import Models.Statements.WhileStatement;
|
||||
import Models.Statements.WriteHeap;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Types.ReferenceType;
|
||||
import Models.Types.StringType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.IntegerValue;
|
||||
import Models.Values.StringValue;
|
||||
import Repositories.IRepository;
|
||||
import Repositories.Repository;
|
||||
import Views.TextMenu;
|
||||
import Views.Commands.ExitCommand;
|
||||
import Views.Commands.RunExampleCommand;
|
||||
|
||||
public class Interpreter {
|
||||
public static void main(String[] args) throws BaseException{
|
||||
IStatement ex1= new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue((2)))), new PrintStatement(new VariableExpression(("v")))));
|
||||
ProgramState programState1 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String,IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex1);
|
||||
IRepository repository1 = new Repository("log1.txt");
|
||||
repository1.addProgramState(programState1);
|
||||
Controller controller1 = new Controller(repository1, true);
|
||||
|
||||
IStatement ex2 = new CompoundStatement( new VariableDeclarationStatement("a",new IntegerType()),
|
||||
new CompoundStatement(new VariableDeclarationStatement("b",new IntegerType()),
|
||||
new CompoundStatement(new AssignmentStatement("a", new ArithmeticExpression('+',new ValueExpression(new IntegerValue(2)),new
|
||||
ArithmeticExpression('*',new ValueExpression(new IntegerValue(3)), new ValueExpression(new IntegerValue(5))))),
|
||||
new CompoundStatement(new AssignmentStatement("b",new ArithmeticExpression('+',new VariableExpression("a"), new ValueExpression(new
|
||||
IntegerValue(1)))), new PrintStatement(new VariableExpression("b"))))));
|
||||
ProgramState programState2 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String,IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex2);
|
||||
IRepository repository2 = new Repository("log2.txt");
|
||||
repository2.addProgramState(programState2);
|
||||
Controller controller2 = new Controller(repository2, true);
|
||||
|
||||
IStatement ex3 = new CompoundStatement(new VariableDeclarationStatement("a",new BooleanType()),
|
||||
new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()),
|
||||
new CompoundStatement(new AssignmentStatement("a", new ValueExpression(new BooleanValue(true))),
|
||||
new CompoundStatement(new IfStatement(new VariableExpression("a"),new AssignmentStatement("v",new ValueExpression(new
|
||||
IntegerValue(2))), new AssignmentStatement("v", new ValueExpression(new IntegerValue(3)))), new PrintStatement(new
|
||||
VariableExpression("v"))))));
|
||||
ProgramState programState3 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String,IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex3);
|
||||
IRepository repository3 = new Repository("log3.txt");
|
||||
repository3.addProgramState(programState3);
|
||||
Controller controller3 = new Controller(repository3, true);
|
||||
|
||||
IStatement ex4 = new CompoundStatement(new VariableDeclarationStatement("varf", new StringType()), new CompoundStatement(new AssignmentStatement("varf", new ValueExpression(new StringValue("test.in"))), new CompoundStatement(new OpenReadFileStatement(new VariableExpression("varf")), new CompoundStatement(new VariableDeclarationStatement("varc", new IntegerType()), new CompoundStatement(new ReadFileStatement(new VariableExpression("varf"), "varc"), new CompoundStatement(new PrintStatement(new VariableExpression("varc")), new CompoundStatement(new ReadFileStatement(new VariableExpression("varf"), "varc"), new CompoundStatement(new PrintStatement(new VariableExpression("varc")), new CloseReadFileStatement(new VariableExpression("varf"))))))))));
|
||||
ProgramState programState4 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String,IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex4);
|
||||
IRepository repository4 = new Repository("log4.txt");
|
||||
repository4.addProgramState(programState4);
|
||||
Controller controller4 = new Controller(repository4, true);
|
||||
|
||||
IStatement ex5 = new CompoundStatement(new IfStatement(new RelationalExpression(new ValueExpression(new IntegerValue(1)), new ValueExpression(new IntegerValue(2)), "<"), new PrintStatement(new ValueExpression(new IntegerValue(1))),new PrintStatement(new ValueExpression(new IntegerValue(2)))), new PrintStatement(new ValueExpression(new IntegerValue(3))));
|
||||
ProgramState programState5 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex5);
|
||||
IRepository repository5 = new Repository("log5.txt");
|
||||
repository5.addProgramState(programState5);
|
||||
Controller controller5 = new Controller(repository5, true);
|
||||
|
||||
IStatement ex6 = new CompoundStatement(new VariableDeclarationStatement("v", new ReferenceType(new IntegerType())), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(20))), new CompoundStatement(new VariableDeclarationStatement("a", new ReferenceType(new ReferenceType(new IntegerType()))), new CompoundStatement(new NewStatement("a", new VariableExpression("v")), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(30))), new PrintStatement(new ReadHeap(new ReadHeap(new VariableExpression("a")))))))));
|
||||
ProgramState programState6 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex6);
|
||||
IRepository repository6 = new Repository("log6.txt");
|
||||
repository6.addProgramState(programState6);
|
||||
Controller controller6 = new Controller(repository6, true);
|
||||
|
||||
IStatement ex7 = new CompoundStatement(new VariableDeclarationStatement("v", new ReferenceType(new IntegerType())), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(10))), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(20))), new PrintStatement(new VariableExpression("v")))));
|
||||
ProgramState programState7 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex7);
|
||||
IRepository repository7 = new Repository("log7.txt");
|
||||
repository7.addProgramState(programState7);
|
||||
Controller controller7 = new Controller(repository7, true);
|
||||
|
||||
IStatement ex8 = new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(4))), new CompoundStatement(new WhileStatement(new CompoundStatement(new PrintStatement(new VariableExpression("v")), new AssignmentStatement("v", new ArithmeticExpression('-', new VariableExpression("v"), new ValueExpression(new IntegerValue(1))))), new RelationalExpression(new VariableExpression("v"), new ValueExpression(new IntegerValue(0)), ">")), new PrintStatement(new VariableExpression("v")))));
|
||||
ProgramState programState8 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex8);
|
||||
IRepository repository8 = new Repository("log8.txt");
|
||||
repository8.addProgramState(programState8);
|
||||
Controller controller8 = new Controller(repository8, true);
|
||||
|
||||
IStatement ex9 = new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new VariableDeclarationStatement("a", new ReferenceType(new IntegerType())), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(10))), new CompoundStatement(new NewStatement("a", new ValueExpression(new IntegerValue(22))), new CompoundStatement(new ForkStatement(new CompoundStatement(new WriteHeap("a", new ValueExpression(new IntegerValue(30))), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(32))), new CompoundStatement(new PrintStatement(new VariableExpression("v")), new PrintStatement(new ReadHeap(new VariableExpression("a"))))))), new CompoundStatement(new PrintStatement(new VariableExpression("v")), new PrintStatement(new ReadHeap(new VariableExpression("a")))))))));
|
||||
ProgramState programState9 = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),ex9);
|
||||
IRepository repository9 = new Repository("log9.txt");
|
||||
repository9.addProgramState(programState9);
|
||||
Controller controller9 = new Controller(repository9, true);
|
||||
|
||||
IStatement badTypes = new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new AssignmentStatement("v", new ValueExpression(new BooleanValue(true))));
|
||||
ProgramState badProgramState = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(),badTypes);
|
||||
try{
|
||||
IRepository badRepository = new Repository("logBad.txt");
|
||||
badRepository.addProgramState(badProgramState);
|
||||
}
|
||||
catch(BaseException exception){
|
||||
System.out.println(exception.getMessage());
|
||||
}
|
||||
TextMenu menu = new TextMenu();
|
||||
menu.addCommand(new RunExampleCommand("1", "Run example 1", controller1));
|
||||
menu.addCommand(new RunExampleCommand("2", "Run example 2", controller2));
|
||||
menu.addCommand(new RunExampleCommand("3", "Run example 3", controller3));
|
||||
menu.addCommand(new RunExampleCommand("4", "Run example 4", controller4));
|
||||
menu.addCommand(new RunExampleCommand("5", "Run example 5", controller5));
|
||||
menu.addCommand(new RunExampleCommand("6", "Run example 6", controller6));
|
||||
menu.addCommand(new RunExampleCommand("7", "Run example 7", controller7));
|
||||
menu.addCommand(new RunExampleCommand("8", "Run example 8", controller8));
|
||||
menu.addCommand(new RunExampleCommand("9", "Run example 9", controller9));
|
||||
menu.addCommand(new ExitCommand("e", "Exit"));
|
||||
menu.show();
|
||||
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Values.IntegerValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class ArithmeticExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private char operator;
|
||||
|
||||
public ArithmeticExpression(char operator,IExpression left, IExpression right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new IntegerType())) {
|
||||
int leftInt = ((IntegerValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new IntegerType())) {
|
||||
int rightInt = ((IntegerValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case '+':
|
||||
return new IntegerValue(leftInt + rightInt);
|
||||
case '-':
|
||||
return new IntegerValue(leftInt - rightInt);
|
||||
case '*':
|
||||
return new IntegerValue(leftInt * rightInt);
|
||||
case '/':
|
||||
if (rightInt == 0) {
|
||||
throw new BaseException("Division by zero!");
|
||||
}
|
||||
return new IntegerValue(leftInt / rightInt);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ArithmeticExpression(operator, left.copy(), right.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type1, type2;
|
||||
type1 = left.typeCheck(typeTable);
|
||||
type2 = right.typeCheck(typeTable);
|
||||
if (type1.equals(new IntegerType())) {
|
||||
if (type2.equals(new IntegerType())) {
|
||||
return new IntegerType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IExpression {
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException;
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException;
|
||||
public IExpression copy();
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class LogicExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private String operator;
|
||||
|
||||
public LogicExpression(IExpression left, IExpression right, String operator) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new BooleanType())) {
|
||||
boolean leftBool = ((BooleanValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new BooleanType())) {
|
||||
boolean rightBool = ((BooleanValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case "&&":
|
||||
return new BooleanValue(leftBool && rightBool);
|
||||
case "||":
|
||||
return new BooleanValue(leftBool || rightBool);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new LogicExpression(left.copy(), right.copy(), operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType leftType, rightType;
|
||||
leftType = left.typeCheck(typeTable);
|
||||
rightType = right.typeCheck(typeTable);
|
||||
if (leftType.equals(new BooleanType())) {
|
||||
if (rightType.equals(new BooleanType())) {
|
||||
return new BooleanType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class ReadHeap implements IExpression {
|
||||
private IExpression expression;
|
||||
|
||||
public ReadHeap(IExpression expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue value = this.expression.evaluate(table, heap);
|
||||
if(!(value instanceof ReferenceValue)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
int address = ((ReferenceValue)value).getAddress();
|
||||
if(!heap.contains(address)) {
|
||||
throw new BaseException("Address " + address + " is not in the heap");
|
||||
}
|
||||
return heap.get(address);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ReadHeap(this.expression.copy());
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type = this.expression.typeCheck(typeTable);
|
||||
if(!(type instanceof ReferenceType)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
return ((ReferenceType)type).getInnerType();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.IntegerValue;
|
||||
|
||||
public class RelationalExpression implements IExpression {
|
||||
private IExpression leftExpression;
|
||||
private IExpression rightExpression;
|
||||
private String operator;
|
||||
|
||||
public RelationalExpression(IExpression leftExpression, IExpression rightExpression, String operator) {
|
||||
this.leftExpression = leftExpression;
|
||||
this.rightExpression = rightExpression;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new RelationalExpression(this.leftExpression.copy(), this.rightExpression.copy(), this.operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.leftExpression.toString() + " " + this.operator + " " + this.rightExpression.toString();
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> symbolTable, IHeap heap) throws BaseException {
|
||||
var leftValue = this.leftExpression.evaluate(symbolTable, heap);
|
||||
var rightValue = this.rightExpression.evaluate(symbolTable, heap);
|
||||
if (leftValue.getType().equals(new IntegerType()) && rightValue.getType().equals(new IntegerType())) {
|
||||
var leftIntegerValue = (IntegerValue) leftValue;
|
||||
var rightIntegerValue = (IntegerValue) rightValue;
|
||||
var leftInteger = leftIntegerValue.getValue();
|
||||
var rightInteger = rightIntegerValue.getValue();
|
||||
switch (this.operator) {
|
||||
case "<":
|
||||
return new BooleanValue(leftInteger < rightInteger);
|
||||
case "<=":
|
||||
return new BooleanValue(leftInteger <= rightInteger);
|
||||
case "==":
|
||||
return new BooleanValue(leftInteger == rightInteger);
|
||||
case "!=":
|
||||
return new BooleanValue(leftInteger != rightInteger);
|
||||
case ">":
|
||||
return new BooleanValue(leftInteger > rightInteger);
|
||||
case ">=":
|
||||
return new BooleanValue(leftInteger >= rightInteger);
|
||||
default:
|
||||
throw new BaseException("RelationalExpression: Invalid operator");
|
||||
}
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Operands are not of type IntegerType");
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
var leftType = this.leftExpression.typeCheck(typeTable);
|
||||
var rightType = this.rightExpression.typeCheck(typeTable);
|
||||
if (leftType.equals(new IntegerType())) {
|
||||
if (rightType.equals(new IntegerType())) {
|
||||
return new BooleanType();
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Right operand is not of type IntegerType");
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Left operand is not of type IntegerType");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
|
||||
public class ValueExpression implements IExpression {
|
||||
private IValue value;
|
||||
|
||||
public ValueExpression(IValue value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ValueExpression(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return value.getType();
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class VariableExpression implements IExpression {
|
||||
private String name;
|
||||
|
||||
public VariableExpression(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return table.get(name);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new VariableExpression(name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return typeTable.get(name);
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package Models.Program;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class GenericDictionary<K, V> implements IDictionary<K, V> {
|
||||
private Hashtable<K, V> dictionary;
|
||||
|
||||
public GenericDictionary() {
|
||||
dictionary = new Hashtable<K, V>();
|
||||
}
|
||||
|
||||
public void add(K key, V value) throws BaseException {
|
||||
if (dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key already exists in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void update(K key, V value) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void remove(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
dictionary.remove(key);
|
||||
}
|
||||
|
||||
public V get(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
return dictionary.get(key);
|
||||
}
|
||||
|
||||
public boolean contains(K key) {
|
||||
return dictionary.containsKey(key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : dictionary.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(dictionary.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Collection<V> getContent() {
|
||||
return dictionary.values();
|
||||
}
|
||||
|
||||
public IDictionary<K, V> copy() {
|
||||
var newDictionary = new GenericDictionary<K, V>();
|
||||
for (var key : dictionary.keySet()) {
|
||||
newDictionary.dictionary.put(key, dictionary.get(key));
|
||||
}
|
||||
return newDictionary;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class GenericQueue<T> implements IQueue<T> {
|
||||
private Queue<T> queue;
|
||||
|
||||
public GenericQueue() {
|
||||
this.queue = new LinkedList<T>();
|
||||
}
|
||||
|
||||
public T dequeue() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public void enqueue(T value) {
|
||||
queue.add(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : queue) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class GenericStack<T> implements IStack<T> {
|
||||
private Deque<T> stack;
|
||||
|
||||
public GenericStack() {
|
||||
stack = new ArrayDeque<T>();
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
stack.push(value);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : stack) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class Heap implements IHeap{
|
||||
private Integer freeAddress;
|
||||
private Hashtable<Integer, IValue> heap;
|
||||
|
||||
public Heap() {
|
||||
this.freeAddress = 1;
|
||||
this.heap = new Hashtable<Integer, IValue>();
|
||||
}
|
||||
|
||||
public Integer getFreeAddress() {
|
||||
return this.freeAddress;
|
||||
}
|
||||
|
||||
public Boolean contains(Integer address) {
|
||||
return this.heap.containsKey(address);
|
||||
}
|
||||
|
||||
public Integer add(IValue value) {
|
||||
this.heap.put(this.freeAddress, value);
|
||||
this.freeAddress += 1;
|
||||
return this.freeAddress - 1;
|
||||
}
|
||||
|
||||
public void update(Integer address, IValue value) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.put(address, value);
|
||||
}
|
||||
|
||||
public IValue get(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
return this.heap.get(address);
|
||||
}
|
||||
|
||||
public void remove(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.remove(address);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : this.heap.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(this.heap.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Hashtable<Integer, IValue> getContent() {
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public void setContent(Hashtable<Integer, IValue> content) {
|
||||
this.heap = content;
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public interface IDictionary<K, V> {
|
||||
public void add(K key, V value) throws BaseException;
|
||||
public void update(K key, V value) throws BaseException;
|
||||
public void remove(K key) throws BaseException;
|
||||
public V get(K key) throws BaseException;
|
||||
public boolean contains(K key);
|
||||
public Collection<V> getContent();
|
||||
public IDictionary<K, V> copy();
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IHeap {
|
||||
public Integer getFreeAddress();
|
||||
public Integer add(IValue value);
|
||||
public void update(Integer address, IValue value) throws BaseException;
|
||||
public IValue get(Integer address) throws BaseException;
|
||||
public void remove(Integer address) throws BaseException;
|
||||
public Boolean contains(Integer address);
|
||||
public Hashtable<Integer, IValue> getContent();
|
||||
public void setContent(Hashtable<Integer, IValue> content);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package Models.Program;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public interface IQueue<T> {
|
||||
public T dequeue() throws BaseException;
|
||||
public void enqueue(T value);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package Models.Program;
|
||||
|
||||
public interface IStack<T> {
|
||||
public T pop();
|
||||
public void push(T value);
|
||||
public boolean isEmpty();
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.Set;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Statements.IStatement;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.StringValue;;
|
||||
|
||||
public class ProgramState{
|
||||
//region Fields
|
||||
private IStack<IStatement> stack;
|
||||
private IDictionary<String, IValue> symbolTable;
|
||||
private IQueue<IValue> output;
|
||||
private IDictionary<StringValue, BufferedReader> fileTable;
|
||||
private IStatement originalProgram;
|
||||
private IHeap heap;
|
||||
private Integer id;
|
||||
private static Set<Integer> ids = new java.util.HashSet<>();
|
||||
//endregion
|
||||
|
||||
//region Exposed Methods
|
||||
public ProgramState(IStack<IStatement> stack, IDictionary<String, IValue> symbolTable, IQueue<IValue> output, IDictionary<StringValue, BufferedReader> fileTable, IHeap heap,IStatement program) throws BaseException{
|
||||
this.stack = stack;
|
||||
this.symbolTable = symbolTable;
|
||||
this.output = output;
|
||||
this.fileTable = fileTable;
|
||||
this.originalProgram = program.copy();
|
||||
this.stack.push(program);
|
||||
this.heap = heap;
|
||||
this.id = getNewId();
|
||||
}
|
||||
|
||||
private static Integer getNewId(){
|
||||
Integer newId = 1;
|
||||
synchronized (ids){
|
||||
while(ids.contains(newId)){
|
||||
newId++;
|
||||
}
|
||||
ids.add(newId);
|
||||
}
|
||||
return newId;
|
||||
}
|
||||
|
||||
public IStack<IStatement> getStack(){
|
||||
return this.stack;
|
||||
}
|
||||
|
||||
public IDictionary<String, IValue> getSymbolTable(){
|
||||
return this.symbolTable;
|
||||
}
|
||||
|
||||
public IQueue<IValue> getOutput(){
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public IDictionary<StringValue, BufferedReader> getFileTable(){
|
||||
return this.fileTable;
|
||||
}
|
||||
|
||||
public IStatement getOriginalProgram(){
|
||||
return this.originalProgram;
|
||||
}
|
||||
|
||||
public IHeap getHeap(){
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public boolean isNotCompleted(){
|
||||
return !this.stack.isEmpty();
|
||||
}
|
||||
|
||||
public ProgramState oneStep() throws BaseException{
|
||||
IStack<IStatement> stack = this.getStack();
|
||||
if (stack.isEmpty()) {
|
||||
throw new RuntimeException("Execution stack is empty!");
|
||||
}
|
||||
IStatement currentStatement = stack.pop();
|
||||
return currentStatement.execute(this);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "Id: " + id + "\n" + "Stack:\n" + this.stack.toString() + "\nSymbol Table:\n" + this.symbolTable.toString() + "\nOutput:\n" + this.output.toString() + "\nFile Table:\n" + this.fileTable.toString() + "\n" + "Heap:" + "\n" + this.heap.toString() + "\n";
|
||||
}
|
||||
|
||||
public void typeCheck() throws BaseException{
|
||||
this.originalProgram.typeCheck(new GenericDictionary<String, IType>());
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
+54
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -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;
|
||||
}
|
||||
}
|
||||
+40
@@ -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
|
||||
}
|
||||
+33
@@ -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;
|
||||
}
|
||||
}
|
||||
+12
@@ -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;
|
||||
}
|
||||
+60
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -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;
|
||||
}
|
||||
}
|
||||
+23
@@ -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;
|
||||
}
|
||||
}
|
||||
+57
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -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
|
||||
}
|
||||
+74
@@ -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;
|
||||
}
|
||||
}
|
||||
+41
@@ -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;
|
||||
}
|
||||
}
|
||||
+58
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
@@ -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;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class BooleanType implements IType {
|
||||
//#region Exposed Methods
|
||||
public boolean equals(Object other){
|
||||
return other instanceof BooleanType;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "boolean";
|
||||
}
|
||||
|
||||
public IValue defaultValue(){
|
||||
return new BooleanValue(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IType {
|
||||
public IValue defaultValue();
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.IntegerValue;
|
||||
|
||||
public class IntegerType implements IType {
|
||||
//#region Exposed Methods
|
||||
public boolean equals(Object other){
|
||||
return other instanceof IntegerType;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "int";
|
||||
}
|
||||
|
||||
public IValue defaultValue(){
|
||||
return new IntegerValue(0);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class ReferenceType implements IType {
|
||||
private IType innerType;
|
||||
|
||||
public ReferenceType(IType innerType) {
|
||||
this.innerType = innerType;
|
||||
}
|
||||
|
||||
public IType getInnerType() {
|
||||
return this.innerType;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof ReferenceType) {
|
||||
return this.innerType.equals(((ReferenceType)other).getInnerType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Ref(" + this.innerType.toString() + ")";
|
||||
}
|
||||
|
||||
public IValue defaultValue() {
|
||||
return new ReferenceValue(0, this.innerType);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.StringValue;
|
||||
|
||||
public class StringType implements IType {
|
||||
public boolean equals(Object another) {
|
||||
return another instanceof StringType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "string";
|
||||
}
|
||||
|
||||
public IValue defaultValue() {
|
||||
return new StringValue("");
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.BooleanType;
|
||||
|
||||
public class BooleanValue implements IValue {
|
||||
//#region Fields
|
||||
private boolean value;
|
||||
//#endregion
|
||||
|
||||
//#region Exposed Methods
|
||||
public BooleanValue(boolean value){
|
||||
this.value = value;
|
||||
}
|
||||
public boolean getValue(){
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return Boolean.toString(this.value);
|
||||
}
|
||||
|
||||
public IType getType(){
|
||||
return new BooleanType();
|
||||
}
|
||||
|
||||
public boolean equals(Object other){
|
||||
if(other instanceof BooleanValue){
|
||||
var otherValue = (BooleanValue)other;
|
||||
return otherValue.getValue() == this.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
|
||||
public interface IValue {
|
||||
public IType getType();
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
|
||||
public class IntegerValue implements IValue {
|
||||
//#region Fields
|
||||
private int value;
|
||||
//#endregion
|
||||
|
||||
//#region Exposed Methods
|
||||
public IntegerValue(int value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue(){
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return Integer.toString(this.value);
|
||||
}
|
||||
|
||||
public IType getType(){
|
||||
return new IntegerType();
|
||||
}
|
||||
|
||||
public boolean equals(Object other){
|
||||
if(other instanceof IntegerValue){
|
||||
var otherValue = (IntegerValue)other;
|
||||
return otherValue.getValue() == this.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
|
||||
public class ReferenceValue implements IValue {
|
||||
private Integer address;
|
||||
private IType locationType;
|
||||
|
||||
public ReferenceValue(Integer address, IType locationType) {
|
||||
this.address = address;
|
||||
this.locationType = locationType;
|
||||
}
|
||||
|
||||
public Integer getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public IType getType() {
|
||||
return new ReferenceType(this.locationType);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.StringType;
|
||||
|
||||
public class StringValue implements IValue {
|
||||
private String value;
|
||||
|
||||
public StringValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof StringValue) {
|
||||
var otherValue = (StringValue) other;
|
||||
return otherValue.getValue().equals(this.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public IValue copy() {
|
||||
return new StringValue(this.value);
|
||||
}
|
||||
|
||||
public IType getType() {
|
||||
return new StringType();
|
||||
}
|
||||
|
||||
public boolean equals(IValue other) {
|
||||
if (other instanceof StringValue) {
|
||||
var otherValue = (StringValue) other;
|
||||
return otherValue.getValue().equals(this.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package Repositories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.ProgramState;
|
||||
|
||||
public interface IRepository {
|
||||
public void addProgramState(ProgramState programState) throws BaseException;
|
||||
public void logProgramStateExecution(ProgramState state) throws BaseException;
|
||||
public List<ProgramState> getProgramStates();
|
||||
public void setProgramStates(List<ProgramState> programStates);
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package Repositories;
|
||||
|
||||
import Models.Program.ProgramState;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public class Repository implements IRepository {
|
||||
private List<ProgramState> programStates;
|
||||
private String logFilePath;
|
||||
|
||||
public Repository() {
|
||||
this.programStates = new ArrayList<ProgramState>();
|
||||
this.logFilePath = "log.txt";
|
||||
}
|
||||
|
||||
public Repository(String logFilePath) {
|
||||
this.programStates = new ArrayList<ProgramState>();
|
||||
this.logFilePath = logFilePath;
|
||||
}
|
||||
|
||||
public void addProgramState(ProgramState programState) throws BaseException {
|
||||
programState.typeCheck();
|
||||
programStates.clear();
|
||||
programStates.add(programState);
|
||||
}
|
||||
|
||||
public List<ProgramState> getProgramStates() {
|
||||
return programStates;
|
||||
}
|
||||
|
||||
public void setProgramStates(List<ProgramState> programStates) {
|
||||
this.programStates = programStates;
|
||||
}
|
||||
|
||||
public void logProgramStateExecution(ProgramState state) throws BaseException{
|
||||
try{
|
||||
var logFile = new PrintWriter(new BufferedWriter(new FileWriter(this.logFilePath, true)));
|
||||
logFile.println(state.toString());
|
||||
logFile.close();
|
||||
}
|
||||
catch(Exception exception){
|
||||
throw new BaseException(exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package Views.Commands;
|
||||
|
||||
public abstract class Command {
|
||||
private String key;
|
||||
private String description;
|
||||
public Command (String key, String description) {
|
||||
this.key = key;
|
||||
this.description = description;
|
||||
}
|
||||
public abstract void execute();
|
||||
public String getKey() {
|
||||
return this.key;
|
||||
}
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package Views.Commands;
|
||||
|
||||
public class ExitCommand extends Command {
|
||||
public ExitCommand(String key, String description) {
|
||||
super(key, description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package Views.Commands;
|
||||
|
||||
import Controllers.Controller;
|
||||
|
||||
public class RunExampleCommand extends Command {
|
||||
private Controller controller;
|
||||
public RunExampleCommand(String key, String description, Controller controller) {
|
||||
super(key, description);
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
this.controller.allSteps();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package Views;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
import Views.Commands.Command;
|
||||
|
||||
public class TextMenu {
|
||||
private Map<String, Command> commands;
|
||||
public TextMenu() {
|
||||
this.commands = new HashMap<String, Command>();
|
||||
}
|
||||
public void addCommand(Command command) {
|
||||
this.commands.put(command.getKey(), command);
|
||||
}
|
||||
private void printMenu() {
|
||||
System.out.println("Menu:");
|
||||
for (Command command : this.commands.values()) {
|
||||
String line = String.format("%4s: %s", command.getKey(), command.getDescription());
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
public void show() {
|
||||
var scanner = new Scanner(System.in);
|
||||
while (true) {
|
||||
this.printMenu();
|
||||
System.out.println("Input the option: ");
|
||||
String key = scanner.nextLine();
|
||||
Command command = this.commands.get(key);
|
||||
if (command == null) {
|
||||
System.out.println("Invalid option");
|
||||
continue;
|
||||
}
|
||||
command.execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
15
|
||||
50
|
||||
@@ -0,0 +1,41 @@
|
||||
package Controller;
|
||||
|
||||
import Model.IVehicle;
|
||||
import Repository.IRepository;
|
||||
|
||||
public class Controller {
|
||||
private IRepository _repository;
|
||||
|
||||
public Controller(IRepository repository) {
|
||||
this._repository = repository;
|
||||
}
|
||||
|
||||
public void addVehicle(IVehicle vehicle) throws IllegalArgumentException {
|
||||
_repository.add(vehicle);
|
||||
}
|
||||
|
||||
public void removeVehicle(int index) throws IllegalArgumentException {
|
||||
_repository.remove(index);
|
||||
}
|
||||
|
||||
public IVehicle[] getAllVehicles() {
|
||||
return _repository.getAll();
|
||||
}
|
||||
|
||||
public IVehicle[] filterVehicles(String color){
|
||||
IVehicle[] vehicles = _repository.getAll();
|
||||
IVehicle[] filteredVehicles = new IVehicle[_repository.getSize()];
|
||||
int index = 0;
|
||||
for(IVehicle vehicle : vehicles) {
|
||||
if(vehicle.getColor().equals(color)) {
|
||||
filteredVehicles[index++] = vehicle;
|
||||
}
|
||||
}
|
||||
IVehicle[] copy = new IVehicle[index];
|
||||
for(int i = 0; i < index; i++) {
|
||||
copy[i] = filteredVehicles[i];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package Model;
|
||||
|
||||
public class Bicycle implements IVehicle {
|
||||
|
||||
private String _brand;
|
||||
private String _color;
|
||||
|
||||
public Bicycle(String brand, String color) {
|
||||
this._brand = brand;
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
public String getBrand() {
|
||||
return this._brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) throws IllegalArgumentException {
|
||||
if (brand == null || brand.length() < 3) {
|
||||
throw new IllegalArgumentException("Brand must be at least 3 characters long");
|
||||
}
|
||||
this._brand = brand;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public void setColor(String color) throws IllegalArgumentException {
|
||||
if (color == null || color.length() < 3) {
|
||||
throw new IllegalArgumentException("Color must be at least 3 characters long");
|
||||
}
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Bicycle{" +
|
||||
"brand='" + _brand + '\'' +
|
||||
", color='" + _color + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package Model;
|
||||
|
||||
public class Car implements IVehicle {
|
||||
|
||||
private String _brand;
|
||||
private String _color;
|
||||
|
||||
public Car(String brand, String color) {
|
||||
this._brand = brand;
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
public String getBrand() {
|
||||
return this._brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) throws IllegalArgumentException {
|
||||
if (brand == null || brand.length() < 3) {
|
||||
throw new IllegalArgumentException("Brand must be at least 3 characters long");
|
||||
}
|
||||
this._brand = brand;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public void setColor(String color) throws IllegalArgumentException {
|
||||
if (color == null || color.length() < 3) {
|
||||
throw new IllegalArgumentException("Color must be at least 3 characters long");
|
||||
}
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Car{" +
|
||||
"brand='" + _brand + '\'' +
|
||||
", color='" + _color + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package Model;
|
||||
|
||||
public interface IVehicle {
|
||||
String getBrand();
|
||||
void setBrand(String brand) throws IllegalArgumentException;
|
||||
String getColor();
|
||||
void setColor(String color) throws IllegalArgumentException;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package Model;
|
||||
|
||||
public class Motorcycle implements IVehicle{
|
||||
|
||||
private String _brand;
|
||||
private String _color;
|
||||
|
||||
public Motorcycle(String brand, String color) {
|
||||
this._brand = brand;
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
public String getBrand() {
|
||||
return this._brand;
|
||||
}
|
||||
|
||||
public void setBrand(String brand) throws IllegalArgumentException {
|
||||
if (brand == null || brand.length() < 3) {
|
||||
throw new IllegalArgumentException("Brand must be at least 3 characters long");
|
||||
}
|
||||
this._brand = brand;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public void setColor(String color) throws IllegalArgumentException {
|
||||
if (color == null || color.length() < 3) {
|
||||
throw new IllegalArgumentException("Color must be at least 3 characters long");
|
||||
}
|
||||
this._color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Motorcycle{" +
|
||||
"brand='" + _brand + '\'' +
|
||||
", color='" + _color + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package Repository;
|
||||
|
||||
import Model.IVehicle;
|
||||
|
||||
public interface IRepository {
|
||||
public void add(IVehicle vehicle) throws IllegalArgumentException;
|
||||
public void remove(int index) throws IllegalArgumentException;
|
||||
public IVehicle[] getAll();
|
||||
public int getSize();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package Repository;
|
||||
|
||||
import Model.IVehicle;
|
||||
|
||||
public class VehicleRepo implements IRepository {
|
||||
|
||||
private IVehicle[] _vehicles;
|
||||
private Integer _capacity;
|
||||
private Integer _size;
|
||||
|
||||
public VehicleRepo(Integer capacity) throws IllegalArgumentException {
|
||||
if(capacity < 0) {
|
||||
throw new IllegalArgumentException("Capacity must be a positive number");
|
||||
}
|
||||
this._capacity = capacity;
|
||||
this._vehicles = new IVehicle[capacity];
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(IVehicle vehicle) throws IllegalArgumentException {
|
||||
if(_size == _capacity) {
|
||||
throw new IllegalArgumentException("Repository is full");
|
||||
}
|
||||
_vehicles[_size] = vehicle;
|
||||
_size++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(int index) throws IllegalArgumentException {
|
||||
if(_size == 0) {
|
||||
throw new IllegalArgumentException("Repository is empty");
|
||||
}
|
||||
if(index < 0 || index > _size) {
|
||||
throw new IllegalArgumentException("Index out of bounds");
|
||||
}
|
||||
for(int i = index; i < _size - 1; i++) {
|
||||
_vehicles[i] = _vehicles[i + 1];
|
||||
}
|
||||
_size--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IVehicle[] getAll() {
|
||||
IVehicle[] copy = new IVehicle[_size];
|
||||
for(int i = 0; i < _size; i++) {
|
||||
copy[i] = _vehicles[i];
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package View;
|
||||
|
||||
import Controller.Controller;
|
||||
import Model.Car;
|
||||
import Model.IVehicle;
|
||||
import Model.Motorcycle;
|
||||
import Model.Bicycle;
|
||||
import Repository.IRepository;
|
||||
import Repository.VehicleRepo;
|
||||
|
||||
public class View {
|
||||
public static void main(String[] args) {
|
||||
IRepository repo;
|
||||
try{
|
||||
repo = new VehicleRepo(-5);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
Controller controller = new Controller(repo);
|
||||
Car car = new Car("BMW", "Red");
|
||||
Motorcycle motorcycle = new Motorcycle("Honda", "Black");
|
||||
Bicycle bicycle = new Bicycle("Trek", "Blue");
|
||||
Bicycle bicycle2 = new Bicycle("Trek", "Red");
|
||||
try{
|
||||
controller.addVehicle(car);
|
||||
controller.addVehicle(motorcycle);
|
||||
controller.addVehicle(bicycle);
|
||||
controller.addVehicle(bicycle2);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
System.out.println(e.getMessage());
|
||||
return;
|
||||
}
|
||||
IVehicle[] filteredVehicles = controller.filterVehicles("Red");
|
||||
for(IVehicle vehicle : filteredVehicles) {
|
||||
System.out.println(vehicle.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
/target
|
||||
*.in
|
||||
*.txt
|
||||
@@ -0,0 +1,51 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>gui_interpretor</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>13</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<release>11</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<!-- Default configuration for running -->
|
||||
<!-- Usage: mvn clean javafx:run -->
|
||||
<id>default-cli</id>
|
||||
<configuration>
|
||||
<mainClass>com.example.App</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.example;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
FXMLLoader listLoader = new FXMLLoader();
|
||||
listLoader.setLocation(getClass().getResource("listView.fxml"));
|
||||
Parent root = listLoader.load();
|
||||
ListController listController = listLoader.getController();
|
||||
primaryStage.setTitle("Select");
|
||||
primaryStage.setScene(new Scene(root, 500, 550));
|
||||
primaryStage.show();
|
||||
|
||||
FXMLLoader programLoader = new FXMLLoader();
|
||||
programLoader.setLocation(getClass().getResource("programView.fxml"));
|
||||
Parent programRoot = programLoader.load();
|
||||
ProgramController programController = programLoader.getController();
|
||||
listController.setProgramController(programController);
|
||||
Stage secondaryStage = new Stage();
|
||||
secondaryStage.setTitle("Interpreter");
|
||||
secondaryStage.setScene(new Scene(programRoot, 1920, 1000));
|
||||
secondaryStage.show();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
launch(args);
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
package com.example.Controllers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Models.Values.ReferenceValue;
|
||||
import com.example.Repositories.IRepository;
|
||||
|
||||
public class Controller {
|
||||
private IRepository repository;
|
||||
private boolean displayFlag;
|
||||
private ExecutorService executor;
|
||||
|
||||
public Controller(IRepository repository, boolean displayFlag) {
|
||||
this.repository = repository;
|
||||
this.displayFlag = displayFlag;
|
||||
}
|
||||
public List<ProgramState> getProgramStates(){
|
||||
return repository.getProgramStates();
|
||||
}
|
||||
public List<ProgramState> removeCompletedPrograms(List<ProgramState> programStates) {
|
||||
return programStates.stream().filter(p -> p.isNotCompleted()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void oneStepForAllProgramStates(List<ProgramState> programStates) {
|
||||
programStates = programStates.stream().filter(p -> p != null).collect(Collectors.toList());
|
||||
programStates.forEach(programState -> {
|
||||
try{
|
||||
repository.logProgramStateExecution(programState);
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
List<Callable<ProgramState>> callList = programStates.stream().map((ProgramState p) -> (Callable<ProgramState>)(() -> {
|
||||
try{
|
||||
return p.oneStep();
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
})).filter(c -> c != null).collect(Collectors.toList());
|
||||
List<ProgramState> newProgramStates = new ArrayList<ProgramState>();
|
||||
try{
|
||||
newProgramStates = executor.invokeAll(callList).stream().map(future -> {
|
||||
try {
|
||||
return future.get();
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}).filter(p -> p != null).collect(Collectors.toList());
|
||||
}
|
||||
catch(InterruptedException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
programStates.addAll(newProgramStates);
|
||||
programStates.forEach(programState -> {
|
||||
try{
|
||||
repository.logProgramStateExecution(programState);
|
||||
}
|
||||
catch(BaseException e){
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
});
|
||||
repository.setProgramStates(programStates);
|
||||
}
|
||||
|
||||
public void oneStepAll(){
|
||||
executor = Executors.newFixedThreadPool(2);
|
||||
List<ProgramState> programStates = removeCompletedPrograms(repository.getProgramStates());
|
||||
programStates.get(0).getHeap().setContent(this.garbageCollector(this.getAddressesFromSymbolTable(programStates.stream().map(programState -> programState.getSymbolTable().getContent()).collect(Collectors.toList()), programStates.get(0).getHeap().getContent()), programStates.get(0).getHeap().getContent()));
|
||||
oneStepForAllProgramStates(programStates);
|
||||
executor.shutdownNow();
|
||||
//repository.setProgramStates(programStates);
|
||||
}
|
||||
|
||||
public void allSteps() {
|
||||
executor = Executors.newFixedThreadPool(2);
|
||||
List<ProgramState> programStates = removeCompletedPrograms(repository.getProgramStates());
|
||||
while(programStates.size() > 0){
|
||||
programStates.get(0).getHeap().setContent(this.garbageCollector(this.getAddressesFromSymbolTable(programStates.stream().map(programState -> programState.getSymbolTable().getContent()).collect(Collectors.toList()), programStates.get(0).getHeap().getContent()), programStates.get(0).getHeap().getContent()));
|
||||
oneStepForAllProgramStates(programStates);
|
||||
programStates = removeCompletedPrograms(repository.getProgramStates());
|
||||
}
|
||||
executor.shutdownNow();
|
||||
repository.setProgramStates(programStates);
|
||||
}
|
||||
|
||||
public Hashtable<Integer, IValue> garbageCollector(Set<Integer> symbolTable, Hashtable<Integer, IValue> heap) {
|
||||
return heap.entrySet().stream().filter(e -> symbolTable.contains(e.getKey()))
|
||||
.collect(Hashtable::new, (m, e) -> m.put(e.getKey(), e.getValue()), Hashtable::putAll);
|
||||
}
|
||||
|
||||
public Set<Integer> getAddressesFromSymbolTable(List<Collection<IValue>> symbolTablesValues, Hashtable<Integer, IValue> heap) {
|
||||
return symbolTablesValues.stream().flatMap(Collection::stream).filter(v -> v instanceof ReferenceValue)
|
||||
.flatMap(v -> Stream.iterate(((ReferenceValue) v).getAddress(), Objects::nonNull, addr -> {
|
||||
var value = heap.get(addr);
|
||||
return value instanceof ReferenceValue ? ((ReferenceValue) value).getAddress() : null;
|
||||
})).distinct().collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.example;
|
||||
|
||||
import com.example.Models.Expressions.ArithmeticExpression;
|
||||
import com.example.Models.Expressions.ReadHeap;
|
||||
import com.example.Models.Expressions.RelationalExpression;
|
||||
import com.example.Models.Expressions.ValueExpression;
|
||||
import com.example.Models.Expressions.VariableExpression;
|
||||
import com.example.Models.Statements.AquireStatement;
|
||||
import com.example.Models.Statements.AssignmentStatement;
|
||||
import com.example.Models.Statements.CloseReadFileStatement;
|
||||
import com.example.Models.Statements.CompoundStatement;
|
||||
import com.example.Models.Statements.CreateSemaphore;
|
||||
import com.example.Models.Statements.ForkStatement;
|
||||
import com.example.Models.Statements.IStatement;
|
||||
import com.example.Models.Statements.IfStatement;
|
||||
import com.example.Models.Statements.NewStatement;
|
||||
import com.example.Models.Statements.OpenReadFileStatement;
|
||||
import com.example.Models.Statements.PrintStatement;
|
||||
import com.example.Models.Statements.ReadFileStatement;
|
||||
import com.example.Models.Statements.ReleaseStatement;
|
||||
import com.example.Models.Statements.SwitchStatement;
|
||||
import com.example.Models.Statements.VariableDeclarationStatement;
|
||||
import com.example.Models.Statements.WhileStatement;
|
||||
import com.example.Models.Statements.WriteHeap;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Types.ReferenceType;
|
||||
import com.example.Models.Types.StringType;
|
||||
import com.example.Models.Values.BooleanValue;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
import com.example.Models.Values.StringValue;
|
||||
|
||||
public class Examples{
|
||||
public static IStatement[] exampleList() {
|
||||
IStatement ex1= new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue((2)))), new PrintStatement(new VariableExpression(("v")))));
|
||||
|
||||
IStatement ex2 = new CompoundStatement( new VariableDeclarationStatement("a",new IntegerType()),
|
||||
new CompoundStatement(new VariableDeclarationStatement("b",new IntegerType()),
|
||||
new CompoundStatement(new AssignmentStatement("a", new ArithmeticExpression('+',new ValueExpression(new IntegerValue(2)),new
|
||||
ArithmeticExpression('*',new ValueExpression(new IntegerValue(3)), new ValueExpression(new IntegerValue(5))))),
|
||||
new CompoundStatement(new AssignmentStatement("b",new ArithmeticExpression('+',new VariableExpression("a"), new ValueExpression(new
|
||||
IntegerValue(1)))), new PrintStatement(new VariableExpression("b"))))));
|
||||
|
||||
IStatement ex3 = new CompoundStatement(new VariableDeclarationStatement("a",new BooleanType()),
|
||||
new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()),
|
||||
new CompoundStatement(new AssignmentStatement("a", new ValueExpression(new BooleanValue(true))),
|
||||
new CompoundStatement(new IfStatement(new VariableExpression("a"),new AssignmentStatement("v",new ValueExpression(new
|
||||
IntegerValue(2))), new AssignmentStatement("v", new ValueExpression(new IntegerValue(3)))), new PrintStatement(new
|
||||
VariableExpression("v"))))));
|
||||
|
||||
IStatement ex4 = new CompoundStatement(new VariableDeclarationStatement("varf", new StringType()), new CompoundStatement(new AssignmentStatement("varf", new ValueExpression(new StringValue("test.in"))), new CompoundStatement(new OpenReadFileStatement(new VariableExpression("varf")), new CompoundStatement(new VariableDeclarationStatement("varc", new IntegerType()), new CompoundStatement(new ReadFileStatement(new VariableExpression("varf"), "varc"), new CompoundStatement(new PrintStatement(new VariableExpression("varc")), new CompoundStatement(new ReadFileStatement(new VariableExpression("varf"), "varc"), new CompoundStatement(new PrintStatement(new VariableExpression("varc")), new CloseReadFileStatement(new VariableExpression("varf"))))))))));
|
||||
|
||||
IStatement ex5 = new CompoundStatement(new IfStatement(new RelationalExpression(new ValueExpression(new IntegerValue(1)), new ValueExpression(new IntegerValue(2)), "<"), new PrintStatement(new ValueExpression(new IntegerValue(1))),new PrintStatement(new ValueExpression(new IntegerValue(2)))), new PrintStatement(new ValueExpression(new IntegerValue(3))));
|
||||
|
||||
IStatement ex6 = new CompoundStatement(new VariableDeclarationStatement("v", new ReferenceType(new IntegerType())), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(20))), new CompoundStatement(new VariableDeclarationStatement("a", new ReferenceType(new ReferenceType(new IntegerType()))), new CompoundStatement(new NewStatement("a", new VariableExpression("v")), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(30))), new PrintStatement(new ReadHeap(new ReadHeap(new VariableExpression("a")))))))));
|
||||
|
||||
IStatement ex7 = new CompoundStatement(new VariableDeclarationStatement("v", new ReferenceType(new IntegerType())), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(10))), new CompoundStatement(new NewStatement("v", new ValueExpression(new IntegerValue(20))), new PrintStatement(new VariableExpression("v")))));
|
||||
|
||||
IStatement ex8 = new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(4))), new CompoundStatement(new WhileStatement(new CompoundStatement(new PrintStatement(new VariableExpression("v")), new AssignmentStatement("v", new ArithmeticExpression('-', new VariableExpression("v"), new ValueExpression(new IntegerValue(1))))), new RelationalExpression(new VariableExpression("v"), new ValueExpression(new IntegerValue(0)), ">")), new PrintStatement(new VariableExpression("v")))));
|
||||
|
||||
IStatement ex9 = new CompoundStatement(new VariableDeclarationStatement("v", new IntegerType()), new CompoundStatement(new VariableDeclarationStatement("a", new ReferenceType(new IntegerType())), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(10))), new CompoundStatement(new NewStatement("a", new ValueExpression(new IntegerValue(22))), new CompoundStatement(new ForkStatement(new CompoundStatement(new WriteHeap("a", new ValueExpression(new IntegerValue(30))), new CompoundStatement(new AssignmentStatement("v", new ValueExpression(new IntegerValue(32))), new CompoundStatement(new PrintStatement(new VariableExpression("v")), new PrintStatement(new ReadHeap(new VariableExpression("a"))))))), new CompoundStatement(new PrintStatement(new VariableExpression("v")), new PrintStatement(new ReadHeap(new VariableExpression("a")))))))));
|
||||
|
||||
IStatement ex10 = new CompoundStatement(new VariableDeclarationStatement("v1", new ReferenceType(new IntegerType())), new CompoundStatement(new VariableDeclarationStatement("cnt", new IntegerType()), new CompoundStatement(new NewStatement("v1", new ValueExpression(new IntegerValue(1))), new CompoundStatement(new CreateSemaphore("cnt", new ReadHeap(new VariableExpression("v1"))), new CompoundStatement(new ForkStatement(new CompoundStatement(new AquireStatement("cnt"), new CompoundStatement(new WriteHeap("v1", new ArithmeticExpression('*', new ReadHeap(new VariableExpression("v1")), new ValueExpression(new IntegerValue(10)))), new CompoundStatement(new PrintStatement(new ReadHeap(new VariableExpression("v1"))), new ReleaseStatement("cnt"))))), new CompoundStatement(new ForkStatement(new CompoundStatement(new AquireStatement("cnt"), new CompoundStatement(new WriteHeap("v1",new ArithmeticExpression('*', new ReadHeap(new VariableExpression("v1")), new ValueExpression(new IntegerValue(10)))), new CompoundStatement(new WriteHeap("v1", new ArithmeticExpression('*', new ReadHeap(new VariableExpression("v1")), new ValueExpression(new IntegerValue(2)))), new CompoundStatement(new PrintStatement(new ReadHeap(new VariableExpression("v1"))), new ReleaseStatement("cnt")))))), new CompoundStatement(new AquireStatement("cnt"), new CompoundStatement(new PrintStatement(new ArithmeticExpression('-', new ReadHeap(new VariableExpression("v1")), new ValueExpression(new IntegerValue(1)))), new ReleaseStatement("cnt")))))))));
|
||||
|
||||
IStatement ex11 = new CompoundStatement(new VariableDeclarationStatement("a", new IntegerType()), new CompoundStatement(new VariableDeclarationStatement("b", new IntegerType()), new CompoundStatement(new VariableDeclarationStatement("c", new IntegerType()), new CompoundStatement(new AssignmentStatement("a", new ValueExpression(new IntegerValue(1))), new CompoundStatement(new AssignmentStatement("b", new ValueExpression(new IntegerValue(2))), new CompoundStatement(new AssignmentStatement("c", new ValueExpression(new IntegerValue(5))), new CompoundStatement(new SwitchStatement(new ArithmeticExpression('*', new VariableExpression("a"), new ValueExpression(new IntegerValue(10))), new ArithmeticExpression('*', new VariableExpression("b"), new VariableExpression("c")), new ValueExpression(new IntegerValue(10)), new CompoundStatement(new PrintStatement(new VariableExpression("a")), new PrintStatement(new VariableExpression("b"))), new CompoundStatement(new PrintStatement(new ValueExpression(new IntegerValue(100))), new PrintStatement(new ValueExpression(new IntegerValue(200)))), new PrintStatement(new ValueExpression(new IntegerValue(300)))), new PrintStatement(new ValueExpression(new IntegerValue(300))))))))));
|
||||
|
||||
return new IStatement[]{ex1, ex2, ex3, ex4, ex5, ex6, ex7, ex8, ex9, ex10, ex11};
|
||||
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.example.Exceptions;
|
||||
|
||||
public class BaseException extends Throwable {
|
||||
public BaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.example;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.example.Controllers.Controller;
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.GenericDictionary;
|
||||
import com.example.Models.Program.GenericQueue;
|
||||
import com.example.Models.Program.GenericStack;
|
||||
import com.example.Models.Program.Heap;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Program.SemaphoreTable;
|
||||
import com.example.Models.Statements.IStatement;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Models.Values.StringValue;
|
||||
import com.example.Repositories.IRepository;
|
||||
import com.example.Repositories.Repository;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
public class ListController {
|
||||
|
||||
private ProgramController programController;
|
||||
|
||||
public void setProgramController(ProgramController programController) {
|
||||
this.programController = programController;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private ListView<IStatement> statements;
|
||||
|
||||
@FXML
|
||||
private Button displayButton;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
statements.setItems(FXCollections.observableArrayList(Examples.exampleList()));
|
||||
displayButton.setOnAction(actionEvent -> {
|
||||
int index = statements.getSelectionModel().getSelectedIndex();
|
||||
if (index < 0)
|
||||
return;
|
||||
try{
|
||||
ProgramState state = new ProgramState(new GenericStack<IStatement>(), new GenericDictionary<String, IValue>(), new GenericQueue<IValue>(), new GenericDictionary<StringValue, BufferedReader>(), new Heap(), new SemaphoreTable(), Examples.exampleList()[index]);
|
||||
IRepository repository = new Repository("log.txt");
|
||||
repository.addProgramState(state);
|
||||
Controller controller = new Controller(repository, true);
|
||||
programController.setController(controller);
|
||||
} catch (BaseException interpreterError) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, interpreterError.getMessage(), ButtonType.OK);
|
||||
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||
alert.showAndWait();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public class ArithmeticExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private char operator;
|
||||
|
||||
public ArithmeticExpression(char operator,IExpression left, IExpression right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new IntegerType())) {
|
||||
int leftInt = ((IntegerValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new IntegerType())) {
|
||||
int rightInt = ((IntegerValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case '+':
|
||||
return new IntegerValue(leftInt + rightInt);
|
||||
case '-':
|
||||
return new IntegerValue(leftInt - rightInt);
|
||||
case '*':
|
||||
return new IntegerValue(leftInt * rightInt);
|
||||
case '/':
|
||||
if (rightInt == 0) {
|
||||
throw new BaseException("Division by zero!");
|
||||
}
|
||||
return new IntegerValue(leftInt / rightInt);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ArithmeticExpression(operator, left.copy(), right.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type1, type2;
|
||||
type1 = left.typeCheck(typeTable);
|
||||
type2 = right.typeCheck(typeTable);
|
||||
if (type1.equals(new IntegerType())) {
|
||||
if (type2.equals(new IntegerType())) {
|
||||
return new IntegerType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public interface IExpression {
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException;
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException;
|
||||
public IExpression copy();
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.BooleanValue;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public class LogicExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private String operator;
|
||||
|
||||
public LogicExpression(IExpression left, IExpression right, String operator) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new BooleanType())) {
|
||||
boolean leftBool = ((BooleanValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new BooleanType())) {
|
||||
boolean rightBool = ((BooleanValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case "&&":
|
||||
return new BooleanValue(leftBool && rightBool);
|
||||
case "||":
|
||||
return new BooleanValue(leftBool || rightBool);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new LogicExpression(left.copy(), right.copy(), operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType leftType, rightType;
|
||||
leftType = left.typeCheck(typeTable);
|
||||
rightType = right.typeCheck(typeTable);
|
||||
if (leftType.equals(new BooleanType())) {
|
||||
if (rightType.equals(new BooleanType())) {
|
||||
return new BooleanType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.ReferenceType;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Models.Values.ReferenceValue;
|
||||
|
||||
public class ReadHeap implements IExpression {
|
||||
private IExpression expression;
|
||||
|
||||
public ReadHeap(IExpression expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "rH(" + expression + ")";
|
||||
}
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue value = this.expression.evaluate(table, heap);
|
||||
if(!(value instanceof ReferenceValue)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
int address = ((ReferenceValue)value).getAddress();
|
||||
if(!heap.contains(address)) {
|
||||
throw new BaseException("Address " + address + " is not in the heap");
|
||||
}
|
||||
return heap.get(address);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ReadHeap(this.expression.copy());
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type = this.expression.typeCheck(typeTable);
|
||||
if(!(type instanceof ReferenceType)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
return ((ReferenceType)type).getInnerType();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Values.BooleanValue;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
|
||||
public class RelationalExpression implements IExpression {
|
||||
private IExpression leftExpression;
|
||||
private IExpression rightExpression;
|
||||
private String operator;
|
||||
|
||||
public RelationalExpression(IExpression leftExpression, IExpression rightExpression, String operator) {
|
||||
this.leftExpression = leftExpression;
|
||||
this.rightExpression = rightExpression;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new RelationalExpression(this.leftExpression.copy(), this.rightExpression.copy(), this.operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.leftExpression.toString() + " " + this.operator + " " + this.rightExpression.toString();
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> symbolTable, IHeap heap) throws BaseException {
|
||||
var leftValue = this.leftExpression.evaluate(symbolTable, heap);
|
||||
var rightValue = this.rightExpression.evaluate(symbolTable, heap);
|
||||
if (leftValue.getType().equals(new IntegerType()) && rightValue.getType().equals(new IntegerType())) {
|
||||
var leftIntegerValue = (IntegerValue) leftValue;
|
||||
var rightIntegerValue = (IntegerValue) rightValue;
|
||||
var leftInteger = leftIntegerValue.getValue();
|
||||
var rightInteger = rightIntegerValue.getValue();
|
||||
switch (this.operator) {
|
||||
case "<":
|
||||
return new BooleanValue(leftInteger < rightInteger);
|
||||
case "<=":
|
||||
return new BooleanValue(leftInteger <= rightInteger);
|
||||
case "==":
|
||||
return new BooleanValue(leftInteger == rightInteger);
|
||||
case "!=":
|
||||
return new BooleanValue(leftInteger != rightInteger);
|
||||
case ">":
|
||||
return new BooleanValue(leftInteger > rightInteger);
|
||||
case ">=":
|
||||
return new BooleanValue(leftInteger >= rightInteger);
|
||||
default:
|
||||
throw new BaseException("RelationalExpression: Invalid operator");
|
||||
}
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Operands are not of type IntegerType");
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
var leftType = this.leftExpression.typeCheck(typeTable);
|
||||
var rightType = this.rightExpression.typeCheck(typeTable);
|
||||
if (leftType.equals(new IntegerType())) {
|
||||
if (rightType.equals(new IntegerType())) {
|
||||
return new BooleanType();
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Right operand is not of type IntegerType");
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Left operand is not of type IntegerType");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.IType;
|
||||
|
||||
public class ValueExpression implements IExpression {
|
||||
private IValue value;
|
||||
|
||||
public ValueExpression(IValue value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ValueExpression(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return value.getType();
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.example.Models.Expressions;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public class VariableExpression implements IExpression {
|
||||
private String name;
|
||||
|
||||
public VariableExpression(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return table.get(name);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new VariableExpression(name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return typeTable.get(name);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class GenericDictionary<K, V> implements IDictionary<K, V> {
|
||||
private Hashtable<K, V> dictionary;
|
||||
|
||||
public GenericDictionary() {
|
||||
dictionary = new Hashtable<K, V>();
|
||||
}
|
||||
|
||||
public void add(K key, V value) throws BaseException {
|
||||
if (dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key already exists in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void update(K key, V value) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void remove(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
dictionary.remove(key);
|
||||
}
|
||||
|
||||
public V get(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
return dictionary.get(key);
|
||||
}
|
||||
|
||||
public boolean contains(K key) {
|
||||
return dictionary.containsKey(key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : dictionary.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(dictionary.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Collection<V> getContent() {
|
||||
return dictionary.values();
|
||||
}
|
||||
|
||||
public IDictionary<K, V> copy() {
|
||||
var newDictionary = new GenericDictionary<K, V>();
|
||||
for (var key : dictionary.keySet()) {
|
||||
newDictionary.dictionary.put(key, dictionary.get(key));
|
||||
}
|
||||
return newDictionary;
|
||||
}
|
||||
|
||||
public Hashtable<K, V> getDictionary() {
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class GenericQueue<T> implements IQueue<T> {
|
||||
private Queue<T> queue;
|
||||
|
||||
public GenericQueue() {
|
||||
this.queue = new LinkedList<T>();
|
||||
}
|
||||
|
||||
public T dequeue() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public void enqueue(T value) {
|
||||
queue.add(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : queue) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public List<T> getContent(){
|
||||
return new ArrayList<>(queue);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class GenericStack<T> implements IStack<T> {
|
||||
private Deque<T> stack;
|
||||
|
||||
public GenericStack() {
|
||||
stack = new ArrayDeque<T>();
|
||||
}
|
||||
|
||||
public Deque<T> getStack(){
|
||||
return stack;
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
stack.push(value);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : stack) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public class Heap implements IHeap{
|
||||
private Integer freeAddress;
|
||||
private Hashtable<Integer, IValue> heap;
|
||||
|
||||
public Heap() {
|
||||
this.freeAddress = 1;
|
||||
this.heap = new Hashtable<Integer, IValue>();
|
||||
}
|
||||
|
||||
public Integer getFreeAddress() {
|
||||
return this.freeAddress;
|
||||
}
|
||||
|
||||
public Boolean contains(Integer address) {
|
||||
return this.heap.containsKey(address);
|
||||
}
|
||||
|
||||
public Integer add(IValue value) {
|
||||
this.heap.put(this.freeAddress, value);
|
||||
this.freeAddress += 1;
|
||||
return this.freeAddress - 1;
|
||||
}
|
||||
|
||||
public void update(Integer address, IValue value) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.put(address, value);
|
||||
}
|
||||
|
||||
public IValue get(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
return this.heap.get(address);
|
||||
}
|
||||
|
||||
public void remove(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.remove(address);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : this.heap.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(this.heap.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Hashtable<Integer, IValue> getContent() {
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public void setContent(Hashtable<Integer, IValue> content) {
|
||||
this.heap = content;
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
|
||||
public interface IDictionary<K, V> {
|
||||
public void add(K key, V value) throws BaseException;
|
||||
public void update(K key, V value) throws BaseException;
|
||||
public void remove(K key) throws BaseException;
|
||||
public V get(K key) throws BaseException;
|
||||
public boolean contains(K key);
|
||||
public Collection<V> getContent();
|
||||
public IDictionary<K, V> copy();
|
||||
public Hashtable<K, V> getDictionary();
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public interface IHeap {
|
||||
public Integer getFreeAddress();
|
||||
public Integer add(IValue value);
|
||||
public void update(Integer address, IValue value) throws BaseException;
|
||||
public IValue get(Integer address) throws BaseException;
|
||||
public void remove(Integer address) throws BaseException;
|
||||
public Boolean contains(Integer address);
|
||||
public Hashtable<Integer, IValue> getContent();
|
||||
public void setContent(Hashtable<Integer, IValue> content);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
|
||||
public interface IQueue<T> {
|
||||
public T dequeue() throws BaseException;
|
||||
public void enqueue(T value);
|
||||
public List<T> getContent();
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
|
||||
import javafx.util.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public interface ISemaphoreTable {
|
||||
public Integer add(Pair<Integer,ArrayList<Integer>> value);
|
||||
public void update(Integer key, Pair<Integer,ArrayList<Integer>> value) throws BaseException;
|
||||
public Pair<Integer,ArrayList<Integer>> get(Integer key) throws BaseException;
|
||||
public boolean contains (Integer key);
|
||||
public Collection<Pair<Integer,ArrayList<Integer>>> values();
|
||||
public Hashtable<Integer, Pair<Integer,ArrayList<Integer>>> getDictionary();
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.Deque;
|
||||
|
||||
public interface IStack<T> {
|
||||
public T pop();
|
||||
public void push(T value);
|
||||
public boolean isEmpty();
|
||||
public Deque<T> getStack();
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.Set;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Statements.IStatement;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.Models.Values.StringValue;;
|
||||
|
||||
public class ProgramState{
|
||||
//region Fields
|
||||
private IStack<IStatement> stack;
|
||||
private IDictionary<String, IValue> symbolTable;
|
||||
private IQueue<IValue> output;
|
||||
private IDictionary<StringValue, BufferedReader> fileTable;
|
||||
private IStatement originalProgram;
|
||||
private IHeap heap;
|
||||
private ISemaphoreTable semaphoreTable;
|
||||
public Integer id;
|
||||
private static Set<Integer> ids = new java.util.HashSet<>();
|
||||
//endregion
|
||||
|
||||
//region Exposed Methods
|
||||
public ProgramState(IStack<IStatement> stack, IDictionary<String, IValue> symbolTable, IQueue<IValue> output, IDictionary<StringValue, BufferedReader> fileTable, IHeap heap, ISemaphoreTable semaphoreTable, IStatement program) throws BaseException{
|
||||
this.stack = stack;
|
||||
this.symbolTable = symbolTable;
|
||||
this.output = output;
|
||||
this.fileTable = fileTable;
|
||||
this.originalProgram = program.copy();
|
||||
this.stack.push(program);
|
||||
this.heap = heap;
|
||||
this.semaphoreTable = semaphoreTable;
|
||||
this.id = getNewId();
|
||||
}
|
||||
|
||||
private static Integer getNewId(){
|
||||
Integer newId = 1;
|
||||
synchronized (ids){
|
||||
while(ids.contains(newId)){
|
||||
newId++;
|
||||
}
|
||||
ids.add(newId);
|
||||
}
|
||||
return newId;
|
||||
}
|
||||
|
||||
public IStack<IStatement> getStack(){
|
||||
return this.stack;
|
||||
}
|
||||
|
||||
public IDictionary<String, IValue> getSymbolTable(){
|
||||
return this.symbolTable;
|
||||
}
|
||||
|
||||
public IQueue<IValue> getOutput(){
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public IDictionary<StringValue, BufferedReader> getFileTable(){
|
||||
return this.fileTable;
|
||||
}
|
||||
|
||||
public IStatement getOriginalProgram(){
|
||||
return this.originalProgram;
|
||||
}
|
||||
|
||||
public IHeap getHeap(){
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public ISemaphoreTable getSemaphoreTable(){
|
||||
return this.semaphoreTable;
|
||||
}
|
||||
|
||||
public boolean isNotCompleted(){
|
||||
return !this.stack.isEmpty();
|
||||
}
|
||||
|
||||
public ProgramState oneStep() throws BaseException{
|
||||
IStack<IStatement> stack = this.getStack();
|
||||
if (stack.isEmpty()) {
|
||||
throw new RuntimeException("Execution stack is empty!");
|
||||
}
|
||||
IStatement currentStatement = stack.pop();
|
||||
return currentStatement.execute(this);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "Id: " + id + "\n" + "Stack:\n" + this.stack.toString() + "\nSymbol Table:\n" + this.symbolTable.toString() + "\nOutput:\n" + this.output.toString() + "\nFile Table:\n" + this.fileTable.toString() + "\n" + "Heap:" + "\n" + this.heap.toString() + "\n" + "Semaphore Table:" + "\n" + this.semaphoreTable.toString() + "\n";
|
||||
}
|
||||
|
||||
public void typeCheck() throws BaseException{
|
||||
this.originalProgram.typeCheck(new GenericDictionary<String, IType>());
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.example.Models.Program;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
|
||||
import javafx.util.Pair;
|
||||
|
||||
public class SemaphoreTable implements ISemaphoreTable{
|
||||
private Hashtable<Integer, Pair<Integer,ArrayList<Integer>>> dictionary;
|
||||
private static Integer freeLocation = 0;
|
||||
|
||||
public SemaphoreTable(){
|
||||
this.dictionary = new Hashtable<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer add(Pair<Integer,ArrayList<Integer>> value) {
|
||||
synchronized (this.dictionary){
|
||||
this.dictionary.put(freeLocation, value);
|
||||
freeLocation++;
|
||||
return freeLocation - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Integer key, Pair<Integer,ArrayList<Integer>> value) throws BaseException {
|
||||
synchronized (this.dictionary){
|
||||
if(!this.dictionary.containsKey(key)){
|
||||
throw new BaseException("Key not found in semaphore table.");
|
||||
}
|
||||
this.dictionary.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Integer,ArrayList<Integer>> get(Integer key) throws BaseException {
|
||||
synchronized (this.dictionary){
|
||||
if(!this.dictionary.containsKey(key)){
|
||||
throw new BaseException("Key not found in semaphore table.");
|
||||
}
|
||||
return this.dictionary.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Integer key){
|
||||
return this.dictionary.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Pair<Integer,ArrayList<Integer>>> values() {
|
||||
return this.dictionary.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hashtable<Integer, Pair<Integer,ArrayList<Integer>>> getDictionary() {
|
||||
return this.dictionary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : dictionary.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(dictionary.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
|
||||
public class AquireStatement implements IStatement{
|
||||
private String var;
|
||||
|
||||
public AquireStatement(String var) {
|
||||
this.var = var;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "aquire(" + this.var + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
var symbolTable = state.getSymbolTable();
|
||||
var semaphoreTable = state.getSemaphoreTable();
|
||||
synchronized(semaphoreTable){
|
||||
var stack = state.getStack();
|
||||
|
||||
if(!symbolTable.contains(this.var)){
|
||||
throw new BaseException("Variable not found in symbol table.");
|
||||
}
|
||||
|
||||
var index = symbolTable.get(this.var);
|
||||
if(!index.getType().equals(new IntegerType())){
|
||||
throw new BaseException("Variable not of the type Integer");
|
||||
}
|
||||
var indexValue = ((IntegerValue)index).getValue();
|
||||
if(!semaphoreTable.contains(indexValue)){
|
||||
throw new BaseException("Index not found in semaphore table.");
|
||||
}
|
||||
|
||||
var value = semaphoreTable.get(indexValue);
|
||||
if(value.getKey() > value.getValue().size()){
|
||||
if(!value.getValue().contains(state.id)){
|
||||
value.getValue().add(state.id);
|
||||
}
|
||||
}
|
||||
else{
|
||||
stack.push(this);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatement copy() {
|
||||
return new AquireStatement(this.var);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var type = typeTable.get(this.var);
|
||||
if(!type.equals(new IntegerType())){
|
||||
throw new BaseException("Variable not of the type Integer");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.StringType;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IStack;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.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
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
|
||||
import javafx.util.Pair;
|
||||
|
||||
public class CreateSemaphore implements IStatement{
|
||||
private String variable;
|
||||
private IExpression expressionValue;
|
||||
|
||||
public CreateSemaphore(String variable, IExpression expressionValue) {
|
||||
this.variable = variable;
|
||||
this.expressionValue = expressionValue;
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new CreateSemaphore(variable, expressionValue);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "CreateSemaphore(" + variable + ", " + expressionValue + ")";
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException{
|
||||
var symbolTable = state.getSymbolTable();
|
||||
var semaphoreTable = state.getSemaphoreTable();
|
||||
synchronized(semaphoreTable){
|
||||
var expressionValue = this.expressionValue.evaluate(symbolTable, state.getHeap());
|
||||
if(!expressionValue.getType().equals(new IntegerType())){
|
||||
throw new BaseException("Expression is not of type IntegerValue.");
|
||||
}
|
||||
var expressionInt = ((IntegerValue)expressionValue).getValue();
|
||||
if(!symbolTable.contains(variable)){
|
||||
throw new BaseException("Variable not found in symbol table.");
|
||||
}
|
||||
var index = semaphoreTable.add(new Pair<Integer,ArrayList<Integer>>(expressionInt, new ArrayList<Integer>()));
|
||||
symbolTable.update(variable, new IntegerValue(index));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var typeExpression = expressionValue.typeCheck(typeTable);
|
||||
if(!typeExpression.equals(new IntegerType())){
|
||||
throw new BaseException("Expression is not of type IntegerValue.");
|
||||
}
|
||||
var typeVariable = typeTable.get(variable);
|
||||
if(!typeVariable.equals(new IntegerType())){
|
||||
throw new BaseException("Variable is not of type IntegerValue.");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.GenericStack;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.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(), state.getSemaphoreTable(), 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;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.BooleanValue;
|
||||
import com.example.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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.ReferenceType;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.StringType;
|
||||
import com.example.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;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IQueue;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Types.StringType;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.IntegerType;
|
||||
import com.example.Models.Values.IntegerValue;
|
||||
|
||||
public class ReleaseStatement implements IStatement {
|
||||
private String var;
|
||||
|
||||
public ReleaseStatement(String var) {
|
||||
this.var = var;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "release(" + this.var + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
var symbolTable = state.getSymbolTable();
|
||||
var semaphoreTable = state.getSemaphoreTable();
|
||||
synchronized(semaphoreTable){
|
||||
var stack = state.getStack();
|
||||
|
||||
if(!symbolTable.contains(this.var)){
|
||||
throw new BaseException("Variable not found in symbol table.");
|
||||
}
|
||||
|
||||
var index = symbolTable.get(this.var);
|
||||
if(!index.getType().equals(new IntegerType())){
|
||||
throw new BaseException("Variable not of the type Integer");
|
||||
}
|
||||
var indexValue = ((IntegerValue)index).getValue();
|
||||
if(!semaphoreTable.contains(indexValue)){
|
||||
throw new BaseException("Index not found in semaphore table.");
|
||||
}
|
||||
|
||||
var value = semaphoreTable.get(indexValue);
|
||||
if(value.getValue().contains(state.id)){
|
||||
value.getValue().remove(state.id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var type = typeTable.get(this.var);
|
||||
if(!type.equals(new IntegerType())){
|
||||
throw new BaseException("Variable not of the type Integer");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IStatement copy() {
|
||||
return new ReleaseStatement(this.var);
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Expressions.RelationalExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IType;
|
||||
|
||||
public class SwitchStatement implements IStatement{
|
||||
private IExpression exp;
|
||||
private IExpression exp1;
|
||||
private IExpression exp2;
|
||||
private IStatement stmt1;
|
||||
private IStatement stmt2;
|
||||
private IStatement stmt3;
|
||||
|
||||
public SwitchStatement(IExpression exp,IExpression exp1, IExpression exp2, IStatement stmt1, IStatement stmt2, IStatement stmt3){
|
||||
this.exp = exp;
|
||||
this.exp1 = exp1;
|
||||
this.exp2 = exp2;
|
||||
this.stmt1 = stmt1;
|
||||
this.stmt2 = stmt2;
|
||||
this.stmt3 = stmt3;
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException{
|
||||
var stack = state.getStack();
|
||||
var ifstmt = new IfStatement(new RelationalExpression(exp, exp1, "=="), stmt1 , new IfStatement(new RelationalExpression(exp, exp2, "=="), stmt2, stmt3));
|
||||
stack.push(ifstmt);
|
||||
return null;
|
||||
}
|
||||
public IStatement copy(){
|
||||
return new SwitchStatement(exp, exp1, exp2, stmt1, stmt2, stmt3);
|
||||
}
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
IType expType = exp.typeCheck(typeTable);
|
||||
IType exp1Type = exp1.typeCheck(typeTable);
|
||||
IType exp2Type = exp2.typeCheck(typeTable);
|
||||
if (expType.equals(exp1Type) && expType.equals(exp2Type)) {
|
||||
stmt1.typeCheck(typeTable.copy());
|
||||
stmt2.typeCheck(typeTable.copy());
|
||||
stmt3.typeCheck(typeTable.copy());
|
||||
return typeTable;
|
||||
} else {
|
||||
throw new BaseException("Condition is not a boolean!");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "(switch(" + exp +") (case(" + exp1 + ") : " + stmt1 + ") (case (" + exp2 + ") : " + stmt2 + ") (default : " + stmt3 + "))";
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.example.Models.Statements;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Expressions.IExpression;
|
||||
import com.example.Models.Program.IDictionary;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Program.IStack;
|
||||
import com.example.Models.Program.ProgramState;
|
||||
import com.example.Models.Types.BooleanType;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user