diff --git a/java/counting.bb b/java/counting.bb
new file mode 100644
index 0000000000000000000000000000000000000000..7c0ee2323b5ab0fcae6e378a910eef855a214961
--- /dev/null
+++ b/java/counting.bb
@@ -0,0 +1,7 @@
+clear X;
+incr X;
+incr X;
+incr X;
+while X not 0 do;
+   decr X;
+end;
diff --git a/java/multiply.bb b/java/multiply.bb
new file mode 100644
index 0000000000000000000000000000000000000000..2ab092c4c8491b6a9a22fcf059414a047b650c43
--- /dev/null
+++ b/java/multiply.bb
@@ -0,0 +1,21 @@
+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;
diff --git a/java/negative.bb b/java/negative.bb
new file mode 100644
index 0000000000000000000000000000000000000000..1522cde1839f15fa58410cccdbc477a11936ac42
--- /dev/null
+++ b/java/negative.bb
@@ -0,0 +1,2 @@
+clear x;
+decr x;
\ No newline at end of file
diff --git a/java/src/jrr1g18/bb/Interpreter.java b/java/src/jrr1g18/bb/Interpreter.java
new file mode 100644
index 0000000000000000000000000000000000000000..871072be8c9d091bc5fd48539055593218c6f55d
--- /dev/null
+++ b/java/src/jrr1g18/bb/Interpreter.java
@@ -0,0 +1,262 @@
+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;
+    }
+
+}
diff --git a/java/src/jrr1g18/bb/Main.java b/java/src/jrr1g18/bb/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d3d9c8af199892ea9b02e2a466d670cc9405644
--- /dev/null
+++ b/java/src/jrr1g18/bb/Main.java
@@ -0,0 +1,11 @@
+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());
+    }
+
+}