School Commit Init
This commit is contained in:
+77
@@ -0,0 +1,77 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Values.IntegerValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class ArithmeticExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private char operator;
|
||||
|
||||
public ArithmeticExpression(char operator,IExpression left, IExpression right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new IntegerType())) {
|
||||
int leftInt = ((IntegerValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new IntegerType())) {
|
||||
int rightInt = ((IntegerValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case '+':
|
||||
return new IntegerValue(leftInt + rightInt);
|
||||
case '-':
|
||||
return new IntegerValue(leftInt - rightInt);
|
||||
case '*':
|
||||
return new IntegerValue(leftInt * rightInt);
|
||||
case '/':
|
||||
if (rightInt == 0) {
|
||||
throw new BaseException("Division by zero!");
|
||||
}
|
||||
return new IntegerValue(leftInt / rightInt);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ArithmeticExpression(operator, left.copy(), right.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type1, type2;
|
||||
type1 = left.typeCheck(typeTable);
|
||||
type2 = right.typeCheck(typeTable);
|
||||
if (type1.equals(new IntegerType())) {
|
||||
if (type2.equals(new IntegerType())) {
|
||||
return new IntegerType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not an integer!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not an integer!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IExpression {
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException;
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException;
|
||||
public IExpression copy();
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class LogicExpression implements IExpression {
|
||||
private IExpression left;
|
||||
private IExpression right;
|
||||
private String operator;
|
||||
|
||||
public LogicExpression(IExpression left, IExpression right, String operator) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue leftValue = left.evaluate(table, heap);
|
||||
IValue rightValue = right.evaluate(table, heap);
|
||||
|
||||
if (leftValue.getType().equals(new BooleanType())) {
|
||||
boolean leftBool = ((BooleanValue)leftValue).getValue();
|
||||
|
||||
if (rightValue.getType().equals(new BooleanType())) {
|
||||
boolean rightBool = ((BooleanValue)rightValue).getValue();
|
||||
|
||||
switch (operator) {
|
||||
case "&&":
|
||||
return new BooleanValue(leftBool && rightBool);
|
||||
case "||":
|
||||
return new BooleanValue(leftBool || rightBool);
|
||||
default:
|
||||
throw new BaseException("Invalid operator!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new LogicExpression(left.copy(), right.copy(), operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return left.toString() + " " + operator + " " + right.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType leftType, rightType;
|
||||
leftType = left.typeCheck(typeTable);
|
||||
rightType = right.typeCheck(typeTable);
|
||||
if (leftType.equals(new BooleanType())) {
|
||||
if (rightType.equals(new BooleanType())) {
|
||||
return new BooleanType();
|
||||
} else {
|
||||
throw new BaseException("Second operand is not a boolean!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("First operand is not a boolean!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class ReadHeap implements IExpression {
|
||||
private IExpression expression;
|
||||
|
||||
public ReadHeap(IExpression expression) {
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
IValue value = this.expression.evaluate(table, heap);
|
||||
if(!(value instanceof ReferenceValue)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
int address = ((ReferenceValue)value).getAddress();
|
||||
if(!heap.contains(address)) {
|
||||
throw new BaseException("Address " + address + " is not in the heap");
|
||||
}
|
||||
return heap.get(address);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ReadHeap(this.expression.copy());
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType type = this.expression.typeCheck(typeTable);
|
||||
if(!(type instanceof ReferenceType)) {
|
||||
throw new BaseException("Expression is not a reference value");
|
||||
}
|
||||
return ((ReferenceType)type).getInnerType();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.IntegerValue;
|
||||
|
||||
public class RelationalExpression implements IExpression {
|
||||
private IExpression leftExpression;
|
||||
private IExpression rightExpression;
|
||||
private String operator;
|
||||
|
||||
public RelationalExpression(IExpression leftExpression, IExpression rightExpression, String operator) {
|
||||
this.leftExpression = leftExpression;
|
||||
this.rightExpression = rightExpression;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new RelationalExpression(this.leftExpression.copy(), this.rightExpression.copy(), this.operator);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.leftExpression.toString() + " " + this.operator + " " + this.rightExpression.toString();
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> symbolTable, IHeap heap) throws BaseException {
|
||||
var leftValue = this.leftExpression.evaluate(symbolTable, heap);
|
||||
var rightValue = this.rightExpression.evaluate(symbolTable, heap);
|
||||
if (leftValue.getType().equals(new IntegerType()) && rightValue.getType().equals(new IntegerType())) {
|
||||
var leftIntegerValue = (IntegerValue) leftValue;
|
||||
var rightIntegerValue = (IntegerValue) rightValue;
|
||||
var leftInteger = leftIntegerValue.getValue();
|
||||
var rightInteger = rightIntegerValue.getValue();
|
||||
switch (this.operator) {
|
||||
case "<":
|
||||
return new BooleanValue(leftInteger < rightInteger);
|
||||
case "<=":
|
||||
return new BooleanValue(leftInteger <= rightInteger);
|
||||
case "==":
|
||||
return new BooleanValue(leftInteger == rightInteger);
|
||||
case "!=":
|
||||
return new BooleanValue(leftInteger != rightInteger);
|
||||
case ">":
|
||||
return new BooleanValue(leftInteger > rightInteger);
|
||||
case ">=":
|
||||
return new BooleanValue(leftInteger >= rightInteger);
|
||||
default:
|
||||
throw new BaseException("RelationalExpression: Invalid operator");
|
||||
}
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Operands are not of type IntegerType");
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
var leftType = this.leftExpression.typeCheck(typeTable);
|
||||
var rightType = this.rightExpression.typeCheck(typeTable);
|
||||
if (leftType.equals(new IntegerType())) {
|
||||
if (rightType.equals(new IntegerType())) {
|
||||
return new BooleanType();
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Right operand is not of type IntegerType");
|
||||
}
|
||||
throw new BaseException("RelationalExpression: Left operand is not of type IntegerType");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
|
||||
public class ValueExpression implements IExpression {
|
||||
private IValue value;
|
||||
|
||||
public ValueExpression(IValue value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new ValueExpression(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return value.getType();
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package Models.Expressions;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class VariableExpression implements IExpression {
|
||||
private String name;
|
||||
|
||||
public VariableExpression(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public IValue evaluate(IDictionary<String, IValue> table, IHeap heap) throws BaseException {
|
||||
return table.get(name);
|
||||
}
|
||||
|
||||
public IExpression copy() {
|
||||
return new VariableExpression(name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public IType typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
return typeTable.get(name);
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package Models.Program;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Hashtable;
|
||||
|
||||
public class GenericDictionary<K, V> implements IDictionary<K, V> {
|
||||
private Hashtable<K, V> dictionary;
|
||||
|
||||
public GenericDictionary() {
|
||||
dictionary = new Hashtable<K, V>();
|
||||
}
|
||||
|
||||
public void add(K key, V value) throws BaseException {
|
||||
if (dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key already exists in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void update(K key, V value) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
dictionary.put(key, value);
|
||||
}
|
||||
|
||||
public void remove(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
dictionary.remove(key);
|
||||
}
|
||||
|
||||
public V get(K key) throws BaseException {
|
||||
if (!dictionary.containsKey(key)) {
|
||||
throw new BaseException("Key does not exist in dictionary.");
|
||||
}
|
||||
|
||||
return dictionary.get(key);
|
||||
}
|
||||
|
||||
public boolean contains(K key) {
|
||||
return dictionary.containsKey(key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : dictionary.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(dictionary.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Collection<V> getContent() {
|
||||
return dictionary.values();
|
||||
}
|
||||
|
||||
public IDictionary<K, V> copy() {
|
||||
var newDictionary = new GenericDictionary<K, V>();
|
||||
for (var key : dictionary.keySet()) {
|
||||
newDictionary.dictionary.put(key, dictionary.get(key));
|
||||
}
|
||||
return newDictionary;
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class GenericQueue<T> implements IQueue<T> {
|
||||
private Queue<T> queue;
|
||||
|
||||
public GenericQueue() {
|
||||
this.queue = new LinkedList<T>();
|
||||
}
|
||||
|
||||
public T dequeue() {
|
||||
return queue.poll();
|
||||
}
|
||||
|
||||
public void enqueue(T value) {
|
||||
queue.add(value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : queue) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class GenericStack<T> implements IStack<T> {
|
||||
private Deque<T> stack;
|
||||
|
||||
public GenericStack() {
|
||||
stack = new ArrayDeque<T>();
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
public void push(T value) {
|
||||
stack.push(value);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return stack.isEmpty();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var item : stack) {
|
||||
sb.append(item);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class Heap implements IHeap{
|
||||
private Integer freeAddress;
|
||||
private Hashtable<Integer, IValue> heap;
|
||||
|
||||
public Heap() {
|
||||
this.freeAddress = 1;
|
||||
this.heap = new Hashtable<Integer, IValue>();
|
||||
}
|
||||
|
||||
public Integer getFreeAddress() {
|
||||
return this.freeAddress;
|
||||
}
|
||||
|
||||
public Boolean contains(Integer address) {
|
||||
return this.heap.containsKey(address);
|
||||
}
|
||||
|
||||
public Integer add(IValue value) {
|
||||
this.heap.put(this.freeAddress, value);
|
||||
this.freeAddress += 1;
|
||||
return this.freeAddress - 1;
|
||||
}
|
||||
|
||||
public void update(Integer address, IValue value) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.put(address, value);
|
||||
}
|
||||
|
||||
public IValue get(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
return this.heap.get(address);
|
||||
}
|
||||
|
||||
public void remove(Integer address) throws BaseException {
|
||||
if (!this.heap.containsKey(address)) {
|
||||
throw new BaseException("Address does not exist in heap.");
|
||||
}
|
||||
|
||||
this.heap.remove(address);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var sb = new StringBuilder();
|
||||
for (var key : this.heap.keySet()) {
|
||||
sb.append(key);
|
||||
sb.append(" --> ");
|
||||
sb.append(this.heap.get(key));
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public Hashtable<Integer, IValue> getContent() {
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public void setContent(Hashtable<Integer, IValue> content) {
|
||||
this.heap = content;
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public interface IDictionary<K, V> {
|
||||
public void add(K key, V value) throws BaseException;
|
||||
public void update(K key, V value) throws BaseException;
|
||||
public void remove(K key) throws BaseException;
|
||||
public V get(K key) throws BaseException;
|
||||
public boolean contains(K key);
|
||||
public Collection<V> getContent();
|
||||
public IDictionary<K, V> copy();
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IHeap {
|
||||
public Integer getFreeAddress();
|
||||
public Integer add(IValue value);
|
||||
public void update(Integer address, IValue value) throws BaseException;
|
||||
public IValue get(Integer address) throws BaseException;
|
||||
public void remove(Integer address) throws BaseException;
|
||||
public Boolean contains(Integer address);
|
||||
public Hashtable<Integer, IValue> getContent();
|
||||
public void setContent(Hashtable<Integer, IValue> content);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package Models.Program;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public interface IQueue<T> {
|
||||
public T dequeue() throws BaseException;
|
||||
public void enqueue(T value);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package Models.Program;
|
||||
|
||||
public interface IStack<T> {
|
||||
public T pop();
|
||||
public void push(T value);
|
||||
public boolean isEmpty();
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package Models.Program;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.util.Set;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Statements.IStatement;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.StringValue;;
|
||||
|
||||
public class ProgramState{
|
||||
//region Fields
|
||||
private IStack<IStatement> stack;
|
||||
private IDictionary<String, IValue> symbolTable;
|
||||
private IQueue<IValue> output;
|
||||
private IDictionary<StringValue, BufferedReader> fileTable;
|
||||
private IStatement originalProgram;
|
||||
private IHeap heap;
|
||||
private Integer id;
|
||||
private static Set<Integer> ids = new java.util.HashSet<>();
|
||||
//endregion
|
||||
|
||||
//region Exposed Methods
|
||||
public ProgramState(IStack<IStatement> stack, IDictionary<String, IValue> symbolTable, IQueue<IValue> output, IDictionary<StringValue, BufferedReader> fileTable, IHeap heap,IStatement program) throws BaseException{
|
||||
this.stack = stack;
|
||||
this.symbolTable = symbolTable;
|
||||
this.output = output;
|
||||
this.fileTable = fileTable;
|
||||
this.originalProgram = program.copy();
|
||||
this.stack.push(program);
|
||||
this.heap = heap;
|
||||
this.id = getNewId();
|
||||
}
|
||||
|
||||
private static Integer getNewId(){
|
||||
Integer newId = 1;
|
||||
synchronized (ids){
|
||||
while(ids.contains(newId)){
|
||||
newId++;
|
||||
}
|
||||
ids.add(newId);
|
||||
}
|
||||
return newId;
|
||||
}
|
||||
|
||||
public IStack<IStatement> getStack(){
|
||||
return this.stack;
|
||||
}
|
||||
|
||||
public IDictionary<String, IValue> getSymbolTable(){
|
||||
return this.symbolTable;
|
||||
}
|
||||
|
||||
public IQueue<IValue> getOutput(){
|
||||
return this.output;
|
||||
}
|
||||
|
||||
public IDictionary<StringValue, BufferedReader> getFileTable(){
|
||||
return this.fileTable;
|
||||
}
|
||||
|
||||
public IStatement getOriginalProgram(){
|
||||
return this.originalProgram;
|
||||
}
|
||||
|
||||
public IHeap getHeap(){
|
||||
return this.heap;
|
||||
}
|
||||
|
||||
public boolean isNotCompleted(){
|
||||
return !this.stack.isEmpty();
|
||||
}
|
||||
|
||||
public ProgramState oneStep() throws BaseException{
|
||||
IStack<IStatement> stack = this.getStack();
|
||||
if (stack.isEmpty()) {
|
||||
throw new RuntimeException("Execution stack is empty!");
|
||||
}
|
||||
IStatement currentStatement = stack.pop();
|
||||
return currentStatement.execute(this);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "Id: " + id + "\n" + "Stack:\n" + this.stack.toString() + "\nSymbol Table:\n" + this.symbolTable.toString() + "\nOutput:\n" + this.output.toString() + "\nFile Table:\n" + this.fileTable.toString() + "\n" + "Heap:" + "\n" + this.heap.toString() + "\n";
|
||||
}
|
||||
|
||||
public void typeCheck() throws BaseException{
|
||||
this.originalProgram.typeCheck(new GenericDictionary<String, IType>());
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class AssignmentStatement implements IStatement {
|
||||
private String variableName;
|
||||
private IExpression expression;
|
||||
|
||||
public AssignmentStatement(String variableName, IExpression expression) {
|
||||
this.variableName = variableName;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return variableName + " = " + expression.toString();
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new AssignmentStatement(variableName, expression.copy());
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
|
||||
IHeap heap = state.getHeap();
|
||||
if(symbolTable.contains(variableName)) {
|
||||
IValue value = expression.evaluate(symbolTable, heap);
|
||||
IType variableType = (symbolTable.get(variableName)).getType();
|
||||
if(value.getType().equals(variableType)) {
|
||||
symbolTable.update(variableName, value);
|
||||
} else {
|
||||
throw new BaseException("Declared type of variable " + variableName + " and type of the assigned expression do not match!");
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Variable " + variableName + " is not defined!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType variableType = typeTable.get(variableName);
|
||||
IType expressionType = expression.typeCheck(typeTable);
|
||||
if(variableType.equals(expressionType)) {
|
||||
return typeTable;
|
||||
} else {
|
||||
throw new BaseException("Declared type of variable " + variableName + " and type of the assigned expression do not match!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.StringType;
|
||||
import Models.Values.StringValue;
|
||||
|
||||
public class CloseReadFileStatement implements IStatement{
|
||||
private IExpression expression;
|
||||
|
||||
public CloseReadFileStatement(IExpression expression){
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public IStatement copy(){
|
||||
return new CloseReadFileStatement(this.expression.copy());
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "closeRFile(" + this.expression.toString() + ")";
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState programState) throws BaseException{
|
||||
var value = this.expression.evaluate(programState.getSymbolTable(), programState.getHeap());
|
||||
if(!value.getType().equals(new StringType())){
|
||||
throw new BaseException("CloseReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
if(!programState.getFileTable().contains((StringValue)value)){
|
||||
throw new BaseException("CloseReadFileStatement: File is not open");
|
||||
}
|
||||
var bufferedReader = programState.getFileTable().get((StringValue)value);
|
||||
try{
|
||||
bufferedReader.close();
|
||||
}
|
||||
catch(Exception exception){
|
||||
throw new BaseException("CloseReadFileStatement: File could not be closed");
|
||||
}
|
||||
programState.getFileTable().remove((StringValue)value);
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var expressionType = this.expression.typeCheck(typeTable);
|
||||
if(!expressionType.equals(new StringType())){
|
||||
throw new BaseException("CloseReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IStack;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
|
||||
public class CompoundStatement implements IStatement {
|
||||
//region Fields
|
||||
private IStatement first;
|
||||
private IStatement second;
|
||||
//endregion
|
||||
|
||||
//region Exposed Methods
|
||||
public CompoundStatement(IStatement first, IStatement second){
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "(" + first.toString() + ";" + second.toString() + ")";
|
||||
}
|
||||
|
||||
public IStatement copy(){
|
||||
return new CompoundStatement(first.copy(), second.copy());
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state){
|
||||
IStack<IStatement> stack = state.getStack();
|
||||
stack.push(second);
|
||||
stack.push(first);
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
return second.typeCheck(first.typeCheck(typeTable));
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.GenericStack;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
|
||||
public class ForkStatement implements IStatement {
|
||||
private IStatement statement;
|
||||
|
||||
public ForkStatement(IStatement statement) {
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
ProgramState forkedProgramState = new ProgramState(new GenericStack<IStatement>(), state.getSymbolTable().copy(), state.getOutput(), state.getFileTable(), state.getHeap(), this.statement);
|
||||
return forkedProgramState;
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new ForkStatement(this.statement.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "fork(" + this.statement.toString() + ")";
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
this.statement.typeCheck(typeTable.copy());
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Exceptions.BaseException;
|
||||
|
||||
public interface IStatement{
|
||||
public ProgramState execute(ProgramState state) throws BaseException;
|
||||
public IStatement copy();
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException;
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
|
||||
public class IfStatement implements IStatement {
|
||||
private IStatement thenStatement;
|
||||
private IStatement elseStatement;
|
||||
private IExpression condition;
|
||||
|
||||
public IfStatement(IExpression condition, IStatement thenStatement, IStatement elseStatement) {
|
||||
this.condition = condition;
|
||||
this.thenStatement = thenStatement;
|
||||
this.elseStatement = elseStatement;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(if(" + condition.toString() + ") then(" + thenStatement.toString() + ") else(" + elseStatement.toString() + "))";
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new IfStatement(condition.copy(), thenStatement.copy(), elseStatement.copy());
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
|
||||
IHeap heap = state.getHeap();
|
||||
IValue conditionValue = condition.evaluate(symbolTable, heap);
|
||||
if (conditionValue.getType().equals(new BooleanType())) {
|
||||
boolean conditionBool = ((BooleanValue)conditionValue).getValue();
|
||||
if (conditionBool) {
|
||||
thenStatement.execute(state);
|
||||
} else {
|
||||
elseStatement.execute(state);
|
||||
}
|
||||
} else {
|
||||
throw new BaseException("Condition is not a boolean!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType conditionType = condition.typeCheck(typeTable);
|
||||
if (conditionType.equals(new BooleanType())) {
|
||||
thenStatement.typeCheck(typeTable.copy());
|
||||
elseStatement.typeCheck(typeTable.copy());
|
||||
return typeTable;
|
||||
} else {
|
||||
throw new BaseException("Condition is not a boolean!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class NewStatement implements IStatement {
|
||||
private String variableName;
|
||||
private IExpression expression;
|
||||
|
||||
public NewStatement(String variableName, IExpression expression) {
|
||||
this.variableName = variableName;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new NewStatement(this.variableName, this.expression.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "new(" + this.variableName + ", " + this.expression.toString() + ")";
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState programState) throws BaseException {
|
||||
var symbolTable = programState.getSymbolTable();
|
||||
var heap = programState.getHeap();
|
||||
if (!symbolTable.contains(this.variableName)) {
|
||||
throw new BaseException("NewStatement: Variable is not defined");
|
||||
}
|
||||
var value = symbolTable.get(this.variableName);
|
||||
var expressionValue = this.expression.evaluate(symbolTable, heap);
|
||||
if (!value.getType().equals(new ReferenceType(expressionValue.getType()))) {
|
||||
throw new BaseException("NewStatement: Variable is not of type ReferenceType");
|
||||
}
|
||||
var address = heap.add(expressionValue);
|
||||
symbolTable.update(this.variableName, new ReferenceValue(address, expressionValue.getType()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
var variableType = typeTable.get(this.variableName);
|
||||
var expressionType = this.expression.typeCheck(typeTable);
|
||||
if (!variableType.equals(new ReferenceType(expressionType))) {
|
||||
throw new BaseException("NewStatement: Right hand side and Left hand side have different types");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
|
||||
public class NopStatement implements IStatement {
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new NopStatement();
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) {
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package Models.Statements;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.StringType;
|
||||
import Models.Values.StringValue;
|
||||
|
||||
public class OpenReadFileStatement implements IStatement {
|
||||
private IExpression expression;
|
||||
|
||||
public OpenReadFileStatement(IExpression expression){
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState programState) throws BaseException{
|
||||
var value = this.expression.evaluate(programState.getSymbolTable(), programState.getHeap());
|
||||
if(!value.getType().equals(new StringType())){
|
||||
throw new BaseException("OpenReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
var stringValue = (StringValue)value;
|
||||
if(programState.getFileTable().contains(stringValue)){
|
||||
throw new BaseException("OpenReadFileStatement: File is already open");
|
||||
}
|
||||
BufferedReader bufferedReader;
|
||||
try{
|
||||
bufferedReader = new BufferedReader(new FileReader(stringValue.getValue()));
|
||||
}
|
||||
catch(Exception exception){
|
||||
throw new BaseException("OpenReadFileStatement: File does not exist");
|
||||
}
|
||||
programState.getFileTable().add(stringValue, bufferedReader);
|
||||
return null;
|
||||
}
|
||||
|
||||
public IStatement copy(){
|
||||
return new OpenReadFileStatement(this.expression.copy());
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "openRFile(" + this.expression.toString() + ")";
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var expressionType = this.expression.typeCheck(typeTable);
|
||||
if(!expressionType.equals(new StringType())){
|
||||
throw new BaseException("OpenReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IQueue;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class PrintStatement implements IStatement {
|
||||
//region Fields
|
||||
private IExpression expression;
|
||||
//endregion
|
||||
|
||||
//region Exposed Methods
|
||||
public PrintStatement(IExpression expression){
|
||||
this.expression = expression;
|
||||
}
|
||||
public String toString(){
|
||||
return "print(" + expression.toString() + ")";
|
||||
}
|
||||
|
||||
public IStatement copy(){
|
||||
return new PrintStatement(expression.copy());
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException{
|
||||
IQueue<IValue> output = state.getOutput();
|
||||
output.enqueue(expression.evaluate(state.getSymbolTable(), state.getHeap() ));
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
expression.typeCheck(typeTable);
|
||||
return typeTable;
|
||||
}
|
||||
//endregion
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package Models.Statements;
|
||||
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
import Models.Types.StringType;
|
||||
import Models.Values.IntegerValue;
|
||||
import Models.Values.StringValue;
|
||||
|
||||
public class ReadFileStatement implements IStatement{
|
||||
private IExpression expression;
|
||||
private String variableName;
|
||||
|
||||
public ReadFileStatement(IExpression expression, String variableName){
|
||||
this.expression = expression;
|
||||
this.variableName = variableName;
|
||||
}
|
||||
|
||||
public IStatement copy(){
|
||||
return new ReadFileStatement(this.expression.copy(), this.variableName);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "readFile(" + this.expression.toString() + ", " + this.variableName + ")";
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState programState) throws BaseException{
|
||||
var symbolTable = programState.getSymbolTable();
|
||||
var fileTable = programState.getFileTable();
|
||||
var heap = programState.getHeap();
|
||||
if(!symbolTable.contains(this.variableName)){
|
||||
throw new BaseException("ReadFileStatement: Variable is not defined");
|
||||
}
|
||||
var value = symbolTable.get(this.variableName);
|
||||
if(!value.getType().equals(new IntegerType())){
|
||||
throw new BaseException("ReadFileStatement: Variable is not of type IntegerType");
|
||||
}
|
||||
var expressionValue = this.expression.evaluate(symbolTable, heap);
|
||||
if(!expressionValue.getType().equals(new StringType())){
|
||||
throw new BaseException("ReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
if(!fileTable.contains((StringValue)expressionValue)){
|
||||
throw new BaseException("ReadFileStatement: File is not open");
|
||||
}
|
||||
var bufferedReader = fileTable.get((StringValue)expressionValue);
|
||||
try{
|
||||
var line = bufferedReader.readLine();
|
||||
if(line == null){
|
||||
line = "0";
|
||||
}
|
||||
symbolTable.update(this.variableName, new IntegerValue(Integer.parseInt(line)));
|
||||
}
|
||||
catch(Exception exception){
|
||||
throw new BaseException("ReadFileStatement: File is empty");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException{
|
||||
var expressionType = this.expression.typeCheck(typeTable);
|
||||
if(!expressionType.equals(new StringType())){
|
||||
throw new BaseException("ReadFileStatement: Expression is not of type StringType");
|
||||
}
|
||||
var variableType = typeTable.get(this.variableName);
|
||||
if(!variableType.equals(new IntegerType())){
|
||||
throw new BaseException("ReadFileStatement: Variable is not of type IntegerType");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
|
||||
|
||||
public class VariableDeclarationStatement implements IStatement {
|
||||
private String variableName;
|
||||
private IType variableType;
|
||||
|
||||
public VariableDeclarationStatement(String variableName, IType variableType) {
|
||||
this.variableName = variableName;
|
||||
this.variableType = variableType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return variableType.toString() + " " + variableName;
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new VariableDeclarationStatement(variableName, variableType);
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
|
||||
if(!symbolTable.contains(variableName)) {
|
||||
symbolTable.add(variableName, variableType.defaultValue());
|
||||
} else {
|
||||
throw new BaseException("Variable " + variableName + " is already defined!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
typeTable.add(variableName, variableType);
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.IHeap;
|
||||
import Models.Program.IStack;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.BooleanType;
|
||||
import Models.Types.IType;
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.BooleanValue;
|
||||
|
||||
public class WhileStatement implements IStatement {
|
||||
private IStatement statement;
|
||||
private IExpression expression;
|
||||
|
||||
public WhileStatement(IStatement statement, IExpression expression) {
|
||||
this.statement = statement;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
IStack<IStatement> stack = state.getStack();
|
||||
IHeap heap = state.getHeap();
|
||||
IDictionary<String, IValue> symbolTable = state.getSymbolTable();
|
||||
|
||||
IValue condition = expression.evaluate(symbolTable, heap);
|
||||
if (!condition.getType().equals(new BooleanType())) {
|
||||
throw new BaseException("Condition is not a boolean.");
|
||||
}
|
||||
|
||||
if (((BooleanValue) condition).getValue()) {
|
||||
stack.push(this);
|
||||
stack.push(statement);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "while(" + expression.toString() + ") {" + statement.toString() + "}";
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new WhileStatement(statement.copy(), expression.copy());
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
IType expressionType = expression.typeCheck(typeTable);
|
||||
if (expressionType.equals(new BooleanType())) {
|
||||
statement.typeCheck(typeTable.copy());
|
||||
return typeTable;
|
||||
} else {
|
||||
throw new BaseException("Condition is not a boolean!");
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package Models.Statements;
|
||||
|
||||
import Exceptions.BaseException;
|
||||
import Models.Expressions.IExpression;
|
||||
import Models.Program.IDictionary;
|
||||
import Models.Program.ProgramState;
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class WriteHeap implements IStatement {
|
||||
private String variableName;
|
||||
private IExpression expression;
|
||||
|
||||
public WriteHeap(String variableName, IExpression expression) {
|
||||
this.variableName = variableName;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public ProgramState execute(ProgramState state) throws BaseException {
|
||||
var symbolTable = state.getSymbolTable();
|
||||
var heap = state.getHeap();
|
||||
if(!symbolTable.contains(this.variableName)) {
|
||||
throw new BaseException("Variable " + this.variableName + " is not defined");
|
||||
}
|
||||
if(!(symbolTable.get(this.variableName) instanceof ReferenceValue)) {
|
||||
throw new BaseException("Variable " + this.variableName + " is not a reference value");
|
||||
}
|
||||
int address = ((ReferenceValue)symbolTable.get(this.variableName)).getAddress();
|
||||
if(!heap.contains(address)) {
|
||||
throw new BaseException("Address " + address + " is not in the heap");
|
||||
}
|
||||
var heapValue = heap.get(address);
|
||||
var expressionValue = this.expression.evaluate(symbolTable, heap);
|
||||
if(!heapValue.getType().equals(expressionValue.getType())) {
|
||||
throw new BaseException("Types do not match");
|
||||
}
|
||||
heap.update(address, expressionValue);
|
||||
return null;
|
||||
}
|
||||
|
||||
public IStatement copy() {
|
||||
return new WriteHeap(this.variableName, this.expression.copy());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "writeHeap(" + this.variableName + ", " + this.expression.toString() + ")";
|
||||
}
|
||||
|
||||
public IDictionary<String, IType> typeCheck(IDictionary<String, IType> typeTable) throws BaseException {
|
||||
var variableType = typeTable.get(this.variableName);
|
||||
var expressionType = this.expression.typeCheck(typeTable);
|
||||
if(!variableType.equals(new ReferenceType(expressionType))) {
|
||||
throw new BaseException("Types do not match");
|
||||
}
|
||||
return typeTable;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.BooleanValue;
|
||||
import Models.Values.IValue;
|
||||
|
||||
public class BooleanType implements IType {
|
||||
//#region Exposed Methods
|
||||
public boolean equals(Object other){
|
||||
return other instanceof BooleanType;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "boolean";
|
||||
}
|
||||
|
||||
public IValue defaultValue(){
|
||||
return new BooleanValue(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
|
||||
public interface IType {
|
||||
public IValue defaultValue();
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.IntegerValue;
|
||||
|
||||
public class IntegerType implements IType {
|
||||
//#region Exposed Methods
|
||||
public boolean equals(Object other){
|
||||
return other instanceof IntegerType;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "int";
|
||||
}
|
||||
|
||||
public IValue defaultValue(){
|
||||
return new IntegerValue(0);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.ReferenceValue;
|
||||
|
||||
public class ReferenceType implements IType {
|
||||
private IType innerType;
|
||||
|
||||
public ReferenceType(IType innerType) {
|
||||
this.innerType = innerType;
|
||||
}
|
||||
|
||||
public IType getInnerType() {
|
||||
return this.innerType;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof ReferenceType) {
|
||||
return this.innerType.equals(((ReferenceType)other).getInnerType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Ref(" + this.innerType.toString() + ")";
|
||||
}
|
||||
|
||||
public IValue defaultValue() {
|
||||
return new ReferenceValue(0, this.innerType);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package Models.Types;
|
||||
|
||||
import Models.Values.IValue;
|
||||
import Models.Values.StringValue;
|
||||
|
||||
public class StringType implements IType {
|
||||
public boolean equals(Object another) {
|
||||
return another instanceof StringType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "string";
|
||||
}
|
||||
|
||||
public IValue defaultValue() {
|
||||
return new StringValue("");
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.BooleanType;
|
||||
|
||||
public class BooleanValue implements IValue {
|
||||
//#region Fields
|
||||
private boolean value;
|
||||
//#endregion
|
||||
|
||||
//#region Exposed Methods
|
||||
public BooleanValue(boolean value){
|
||||
this.value = value;
|
||||
}
|
||||
public boolean getValue(){
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return Boolean.toString(this.value);
|
||||
}
|
||||
|
||||
public IType getType(){
|
||||
return new BooleanType();
|
||||
}
|
||||
|
||||
public boolean equals(Object other){
|
||||
if(other instanceof BooleanValue){
|
||||
var otherValue = (BooleanValue)other;
|
||||
return otherValue.getValue() == this.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
|
||||
public interface IValue {
|
||||
public IType getType();
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.IntegerType;
|
||||
|
||||
public class IntegerValue implements IValue {
|
||||
//#region Fields
|
||||
private int value;
|
||||
//#endregion
|
||||
|
||||
//#region Exposed Methods
|
||||
public IntegerValue(int value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue(){
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return Integer.toString(this.value);
|
||||
}
|
||||
|
||||
public IType getType(){
|
||||
return new IntegerType();
|
||||
}
|
||||
|
||||
public boolean equals(Object other){
|
||||
if(other instanceof IntegerValue){
|
||||
var otherValue = (IntegerValue)other;
|
||||
return otherValue.getValue() == this.value;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//#endregion
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.ReferenceType;
|
||||
|
||||
public class ReferenceValue implements IValue {
|
||||
private Integer address;
|
||||
private IType locationType;
|
||||
|
||||
public ReferenceValue(Integer address, IType locationType) {
|
||||
this.address = address;
|
||||
this.locationType = locationType;
|
||||
}
|
||||
|
||||
public Integer getAddress() {
|
||||
return this.address;
|
||||
}
|
||||
|
||||
public IType getType() {
|
||||
return new ReferenceType(this.locationType);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package Models.Values;
|
||||
|
||||
import Models.Types.IType;
|
||||
import Models.Types.StringType;
|
||||
|
||||
public class StringValue implements IValue {
|
||||
private String value;
|
||||
|
||||
public StringValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof StringValue) {
|
||||
var otherValue = (StringValue) other;
|
||||
return otherValue.getValue().equals(this.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public IValue copy() {
|
||||
return new StringValue(this.value);
|
||||
}
|
||||
|
||||
public IType getType() {
|
||||
return new StringType();
|
||||
}
|
||||
|
||||
public boolean equals(IValue other) {
|
||||
if (other instanceof StringValue) {
|
||||
var otherValue = (StringValue) other;
|
||||
return otherValue.getValue().equals(this.value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user