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());
}
}
Supports Markdown
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