School Commit Init
This commit is contained in:
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+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.ProgramState;
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.Models.Types.ReferenceType;
|
||||
import com.example.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 com.example.Models.Types;
|
||||
|
||||
import com.example.Models.Values.BooleanValue;
|
||||
import com.example.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);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.example.Models.Types;
|
||||
|
||||
import com.example.Models.Values.IValue;
|
||||
|
||||
public interface IType {
|
||||
public IValue defaultValue();
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.example.Models.Types;
|
||||
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.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 com.example.Models.Types;
|
||||
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.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 com.example.Models.Types;
|
||||
|
||||
import com.example.Models.Values.IValue;
|
||||
import com.example.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 com.example.Models.Values;
|
||||
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.example.Models.Values;
|
||||
|
||||
import com.example.Models.Types.IType;
|
||||
|
||||
public interface IValue {
|
||||
public IType getType();
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.example.Models.Values;
|
||||
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.example.Models.Values;
|
||||
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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 String toString(){
|
||||
return Integer.toString(this.address);
|
||||
}
|
||||
public Integer getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public IType getType() {
|
||||
return new ReferenceType(this.locationType);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.example.Models.Values;
|
||||
|
||||
import com.example.Models.Types.IType;
|
||||
import com.example.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;
|
||||
}
|
||||
}
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
package com.example;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.example.Controllers.Controller;
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.Models.Program.GenericQueue;
|
||||
import com.example.Models.Program.Heap;
|
||||
import com.example.Models.Program.IHeap;
|
||||
import com.example.Models.Program.IQueue;
|
||||
import com.example.Models.Program.ISemaphoreTable;
|
||||
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 javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
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.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.util.Pair;
|
||||
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.util.Pair;
|
||||
|
||||
public class ProgramController {
|
||||
|
||||
private Controller controller;
|
||||
|
||||
@FXML
|
||||
private TableView<Pair<Integer, IValue>> heapTable;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<Integer, IValue>, Integer> addressColumn;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<Integer, IValue>, String> valueColumn;
|
||||
|
||||
@FXML
|
||||
private ListView<String> outputList;
|
||||
|
||||
@FXML
|
||||
private ListView<String> fileList;
|
||||
|
||||
@FXML
|
||||
private ListView<Integer> programStateList;
|
||||
|
||||
@FXML
|
||||
private ListView<String> executionStackList;
|
||||
|
||||
@FXML
|
||||
private TableView<Pair<String, IValue>> symbolTable;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<String, IValue>, String> symVariableColumn;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<String, IValue>, String> symValueColumn;
|
||||
|
||||
@FXML
|
||||
private TableView<Pair<Integer,Pair<Integer, ArrayList<Integer>>>> semaphoresTable;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<Integer,Pair<Integer, ArrayList<Integer>>>, Integer> semaphoresVariableColumn;
|
||||
|
||||
@FXML
|
||||
private TableColumn<Pair<Integer,Pair<Integer, ArrayList<Integer>>>, String> semaphoresValueColumn;
|
||||
|
||||
@FXML
|
||||
private TextField numberOfProgramStates;
|
||||
|
||||
@FXML
|
||||
private Button oneStep;
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
addressColumn.setCellValueFactory(p -> new SimpleIntegerProperty(p.getValue().getKey()).asObject());
|
||||
valueColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getValue().toString()));
|
||||
symVariableColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getKey()));
|
||||
symValueColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getValue().toString()));
|
||||
semaphoresVariableColumn.setCellValueFactory(p -> new SimpleIntegerProperty(p.getValue().getKey()).asObject());
|
||||
semaphoresValueColumn.setCellValueFactory(p -> new SimpleStringProperty(p.getValue().getValue().toString()));
|
||||
oneStep.setOnAction(actionEvent -> {
|
||||
if(controller == null){
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, "The program was not selected", ButtonType.OK);
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
|
||||
boolean programStateLeft = !controller.getProgramStates().stream().anyMatch(p -> (p != null && p.isNotCompleted()));
|
||||
if(programStateLeft){
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, "Nothing left to execute", ButtonType.OK);
|
||||
alert.showAndWait();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
controller.oneStepAll();
|
||||
populate();
|
||||
} catch (Exception interpreterError) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, interpreterError.getMessage(), ButtonType.OK);
|
||||
alert.showAndWait();
|
||||
}
|
||||
});
|
||||
programStateList.setOnMouseClicked(mouseEvent -> populate());
|
||||
}
|
||||
|
||||
private ProgramState getCurrentProgramState(){
|
||||
if (controller.getProgramStates().size() == 0)
|
||||
return null;
|
||||
int currentId = programStateList.getSelectionModel().getSelectedIndex();
|
||||
if (currentId == -1)
|
||||
return controller.getProgramStates().get(0);
|
||||
return controller.getProgramStates().get(currentId);
|
||||
}
|
||||
|
||||
public void setController(Controller controller) {
|
||||
this.controller = controller;
|
||||
populate();
|
||||
}
|
||||
|
||||
private void populate() {
|
||||
populateHeap();
|
||||
populateProgramStateIdentifiers();
|
||||
populateFileTable();
|
||||
populateOutput();
|
||||
populateSymbolTable();
|
||||
populateExecutionStack();
|
||||
populateSemaphoreTable();
|
||||
}
|
||||
|
||||
private void populateHeap() {
|
||||
IHeap heap;
|
||||
if (controller.getProgramStates().size() > 0)
|
||||
heap = controller.getProgramStates().get(0).getHeap();
|
||||
else heap = new Heap();
|
||||
List<Pair<Integer, IValue>> heapTableList = new ArrayList<>();
|
||||
for (Map.Entry<Integer, IValue> entry : heap.getContent().entrySet())
|
||||
heapTableList.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
heapTable.setItems(FXCollections.observableList(heapTableList));
|
||||
heapTable.refresh();
|
||||
}
|
||||
|
||||
private void populateProgramStateIdentifiers() {
|
||||
List<ProgramState> programStates = controller.getProgramStates();
|
||||
var idList = programStates.stream().map(ps -> ps.id).collect(Collectors.toList());
|
||||
programStateList.setItems(FXCollections.observableList(idList));
|
||||
numberOfProgramStates.setText("" + programStates.size());
|
||||
}
|
||||
|
||||
private void populateFileTable() {
|
||||
ArrayList<String> files;
|
||||
if (controller.getProgramStates().size() > 0)
|
||||
files = new ArrayList<String>(controller.getProgramStates().get(0).getFileTable().getDictionary().keySet().stream().map(Object::toString).collect(Collectors.toList()));
|
||||
else files = new ArrayList<String>();
|
||||
fileList.setItems(FXCollections.observableArrayList(files));
|
||||
}
|
||||
|
||||
private void populateOutput() {
|
||||
IQueue<IValue> output;
|
||||
if (controller.getProgramStates().size() > 0)
|
||||
output = controller.getProgramStates().get(0).getOutput();
|
||||
else output = new GenericQueue<>();
|
||||
outputList.setItems(FXCollections.observableList(output.getContent().stream().map(Object::toString).collect(Collectors.toList())));
|
||||
outputList.refresh();
|
||||
}
|
||||
|
||||
private void populateSymbolTable() {
|
||||
ProgramState state = getCurrentProgramState();
|
||||
List<Pair<String, IValue>> symbolTableList = new ArrayList<>();
|
||||
if (state != null)
|
||||
for (Map.Entry<String, IValue> entry : state.getSymbolTable().getDictionary().entrySet())
|
||||
symbolTableList.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
symbolTable.setItems(FXCollections.observableList(symbolTableList));
|
||||
symbolTable.refresh();
|
||||
}
|
||||
|
||||
private void populateExecutionStack() {
|
||||
ProgramState state = getCurrentProgramState();
|
||||
List<String> executionStackListAsString = new ArrayList<>();
|
||||
if (state != null)
|
||||
for(IStatement s : state.getStack().getStack()){
|
||||
executionStackListAsString.add(s.toString());
|
||||
}
|
||||
executionStackList.setItems(FXCollections.observableList(executionStackListAsString));
|
||||
executionStackList.refresh();
|
||||
}
|
||||
|
||||
private void populateSemaphoreTable(){
|
||||
ISemaphoreTable semaphoreTableInternal;
|
||||
if (controller.getProgramStates().size() > 0)
|
||||
semaphoreTableInternal = controller.getProgramStates().get(0).getSemaphoreTable();
|
||||
else semaphoreTableInternal = new SemaphoreTable();
|
||||
List<Pair<Integer,Pair<Integer, ArrayList<Integer>>>> semaphoreTableList = new ArrayList<>();
|
||||
for (var entry : semaphoreTableInternal.getDictionary().entrySet())
|
||||
semaphoreTableList.add(new Pair<>(entry.getKey(), entry.getValue()));
|
||||
semaphoresTable.setItems(FXCollections.observableList(semaphoreTableList));
|
||||
semaphoresTable.refresh();
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.example.Repositories;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.example.Exceptions.BaseException;
|
||||
import com.example.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 com.example.Repositories;
|
||||
|
||||
import com.example.Models.Program.ProgramState;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.example.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());
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
module com.example {
|
||||
requires javafx.controls;
|
||||
requires javafx.fxml;
|
||||
|
||||
opens com.example to javafx.fxml;
|
||||
exports com.example;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="504.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.ListController">
|
||||
<ListView fx:id="statements" layoutX="26.0" layoutY="63.0" prefHeight="412.0" prefWidth="435.0" />
|
||||
<Button fx:id="displayButton" alignment="CENTER" layoutX="208.0" layoutY="500.0" mnemonicParsing="false" text="Execute" />
|
||||
</AnchorPane>
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1920.0" prefWidth="1400.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.ProgramController">
|
||||
<TableView fx:id="heapTable" layoutX="50.0" layoutY="50.0" prefHeight="400.0" prefWidth="400.0">
|
||||
<columns>
|
||||
<TableColumn fx:id="addressColumn" prefWidth="200.0" text="Address" />
|
||||
<TableColumn fx:id="valueColumn" prefWidth="200.0" text="Value" />
|
||||
</columns>
|
||||
</TableView>
|
||||
<Label layoutX="50.0" layoutY="25.0" text="Heap" />
|
||||
<ListView fx:id="outputList" layoutX="500.0" layoutY="50.0" prefHeight="400.0" prefWidth="400.0" />
|
||||
<Label layoutX="500.0" layoutY="25.0" text="Output" />
|
||||
<ListView fx:id="fileList" layoutX="950.0" layoutY="50.0" prefHeight="400.0" prefWidth="400.0" />
|
||||
<Label layoutX="950.0" layoutY="25.0" text="Files" />
|
||||
<Label layoutX="50.0" layoutY="475.0" text="Program states" />
|
||||
<ListView fx:id="programStateList" layoutX="50.0" layoutY="500.0" prefHeight="400.0" prefWidth="400.0" />
|
||||
<ListView fx:id="executionStackList" layoutX="500.0" layoutY="500.0" prefHeight="400.0" prefWidth="400.0" />
|
||||
<Label layoutX="500.0" layoutY="475.0" text="Execution Stack" />
|
||||
<TableView fx:id="symbolTable" layoutX="950.0" layoutY="500.0" prefHeight="400.0" prefWidth="400.0">
|
||||
<columns>
|
||||
<TableColumn fx:id="symVariableColumn" prefWidth="200.0" text="Variable" />
|
||||
<TableColumn fx:id="symValueColumn" prefWidth="200.0" text="Value" />
|
||||
</columns>
|
||||
</TableView>
|
||||
<Label layoutX="950.0" layoutY="475.0" text="Symbols table" />
|
||||
<TableView fx:id="semaphoresTable" layoutX="1400.0" layoutY="50.0" prefHeight="400.0" prefWidth="400.0">
|
||||
<columns>
|
||||
<TableColumn fx:id="semaphoresVariableColumn" prefWidth="200.0" text="Address" />
|
||||
<TableColumn fx:id="semaphoresValueColumn" prefWidth="200.0" text="Value" />
|
||||
</columns>
|
||||
</TableView>
|
||||
<Label layoutX="1400.0" layoutY="25.0" text="Semaphore Table" />
|
||||
<TextField fx:id="numberOfProgramStates" layoutX="345.0" layoutY="950.0" editable="false" />
|
||||
<Label layoutX="342.0" layoutY="922.0" text="# of program states" />
|
||||
<Button fx:id="oneStep" layoutX="828.0" layoutY="932.0" mnemonicParsing="false" prefHeight="36.0" prefWidth="144.0" text="One Step" />
|
||||
</AnchorPane>
|
||||
Reference in New Issue
Block a user