Administrator approval is now required for registering new accounts. If you are registering a new account, and are external to the University, please ask the repository owner to contact ServiceLine to request your account be approved. Repository owners must include the newly registered email address, and specific repository in the request for approval.

Verified Commit ba7e0717 authored by Emily Rowlands's avatar Emily Rowlands
Browse files

Further migration

parent 4eb14a04
clear X;
incr X;
incr X;
incr X;
while X not 0 do;
decr X;
end;
clear X;
incr X;
incr X;
clear Y;
incr Y;
incr Y;
incr Y;
clear Z;
while X not 0 do;
clear W;
while Y not 0 do;
incr Z;
incr W;
decr Y;
end;
while W not 0 do;
incr Y;
decr W;
end;
decr X;
end;
clear x;
decr x;
\ No newline at end of file
package jrr1g18.bb;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Interpreter {
private Map<String, Integer> m_vars = new HashMap<>();
private List<String> m_code = new ArrayList<>();
private Map<Integer, Integer> m_whiles = new HashMap<>();
private int m_lineCount = 0;
private int m_whileDepth = 0;
private final String m_filename;
private static final Map<InstructionType, String> INSTRUCTION_NAMES;
static {
Map<InstructionType, String> tempMap = new HashMap<>();
tempMap.put(InstructionType.CLEAR, "clear");
tempMap.put(InstructionType.DECR, "decr");
tempMap.put(InstructionType.INCR, "incr");
tempMap.put(InstructionType.WHILE, "while");
tempMap.put(InstructionType.END, "end;");
INSTRUCTION_NAMES = Collections.unmodifiableMap(tempMap);
}
private enum InstructionType {
INCR, DECR, CLEAR, WHILE, END,
}
private static InstructionType stringToInstructionType(String instruction) {
for(Entry<InstructionType, String> entry : INSTRUCTION_NAMES
.entrySet()) {
if(Objects.equals(instruction, entry.getValue())) {
return entry.getKey();
}
}
return null;
}
private static String getVarFromLine(String line) {
Matcher m =
Pattern.compile("(?<=incr|clear|decr)(.+)(?=;)").matcher(line);
if(!m.find()) {
System.err.println(line);
System.exit(1);
}
return stripWhitespace(m.group(1));
}
public Interpreter(String fileName) {
m_filename = fileName;
}
public void run() {
readCode();
validateCode();
exec();
}
public String variablesToString() {
return m_vars.toString();
}
private String getLine(int line) {
return m_code.get(line);
}
private static String[] splitLine(String line) {
return stripWhitespace(line).split("\\s+");
}
public static String stripWhitespace(String str) {
return str.replaceAll("(^\\s+|\\s+$)", "");
}
private String[] getSplitLine(int line) {
return splitLine(getLine(line));
}
private boolean isVariableNull(String name) {
return m_vars.get(name) == null;
}
private void validateCode() {
String line;
String[] splitLine;
int whileDepth = 0;
for(int idx = 0; idx < m_lineCount; ++idx) {
line = stripWhitespace(getLine(idx));
splitLine = splitLine(line);
if(line.equals("")) {
continue;
}
if(!line.matches(".*;$")) {
System.err.println("missing ; on line " + (idx + 1));
System.exit(1);
}
if(!splitLine[0].equals("incr") && !splitLine[0].equals("decr")
&& !splitLine[0].equals("end;")
&& !splitLine[0].equals("clear")
&& !splitLine[0].equals("while")) {
System.err.println("Syntax error on line " + (idx + 1));
System.exit(1);
}
InstructionType instruction = stringToInstructionType(splitLine[0]);
if((instruction == InstructionType.CLEAR
|| instruction == InstructionType.DECR
|| instruction == InstructionType.INCR)
&& splitLine.length > 2) {
System.err.println("Too many arguments on line " + (idx + 1));
System.exit(1);
}
switch (instruction) {
case WHILE:
whileDepth++;
if(!splitLine[2].equals("not") || splitLine.length > 5) {
System.err.println("Syntax error on line " + (idx + 1));
System.exit(1);
}
break;
case END:
whileDepth--;
if(splitLine.length > 1) {
System.err.println("Syntax error on line " + (idx + 1));
System.exit(1);
}
break;
default:
break;
}
}
if(whileDepth > 0) {
System.err.println("Syntax error: unclosed while");
} else if(whileDepth < 0) {
System.err.println("Syntax error: overclosed while");
}
}
private void readCode() {
try(BufferedReader reader =
new BufferedReader(new FileReader(m_filename))) {
String line;
while((line = reader.readLine()) != null) {
m_code.add(line);
m_lineCount++;
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
}
}
private void exec() {
String[] splitLine;
for(int idx = 0; idx < m_lineCount; ++idx) {
splitLine = getSplitLine(idx);
InstructionType instruction = stringToInstructionType(splitLine[0]);
switch (instruction) {
case WHILE:
case END:
idx = loop(idx, splitLine);
continue;
default:
break;
}
String var = getVarFromLine(getLine(idx));
switch (instruction) {
case CLEAR:
clear(var);
break;
case INCR:
incr(var);
break;
case DECR:
decr(var);
break;
default:
break;
}
}
}
private void incr(String name) {
if(isVariableNull(name)) {
System.err.println("Error: Variable " + name + " doesn't exist");
System.exit(1);
} else {
m_vars.put(name, m_vars.get(name) + 1);
}
}
private void decr(String name) {
if(isVariableNull(name)) {
System.err.println("Error: Variable " + name + " doesn't exist");
System.exit(1);
} else if(m_vars.get(name) == 0) {
// System.err
// .println("Error: Variable " + name + " cannot be negative");
// System.exit(1);
m_vars.put(name, Integer.MAX_VALUE);
} else {
m_vars.put(name, m_vars.get(name) - 1);
}
}
private void clear(String name) {
m_vars.put(name, 0);
}
private int loop(int idx, String[] splitLine) {
String line;
if(splitLine[0].equals("while")) {
m_whileDepth++;
m_whiles.put(m_whileDepth, idx);
int condition = Integer.parseInt(splitLine[3]);
if(isVariableNull(splitLine[1])
&& m_vars.get(splitLine[1]) == condition) {
while(!splitLine[0].equals("end;")) {
idx++;
line = getLine(idx);
splitLine = splitLine(line);
}
}
} else {
line = m_code.get(m_whiles.get(m_whileDepth));
splitLine = splitLine(line);
int condition = Integer.parseInt(splitLine[3]);
if(m_vars.get(splitLine[1]) != condition)
idx = m_whiles.get(m_whileDepth);
else {
m_whileDepth--;
}
}
return idx;
}
}
package jrr1g18.bb;
public class Main {
public static void main(String[] args) {
Interpreter interpreter = new Interpreter("negative.bb");
interpreter.run();
System.out.println(interpreter.variablesToString());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment